First real run of nigig-map.yml reported failure at 530 passed /
9 failed -- exactly the baseline it was supposed to allow.
The step ran `out="$(cargo test ...)"` under the runner's `-e` shell.
cargo test exits 101 while any test fails, and a failing command
substitution in a plain assignment aborts the step immediately, so
neither the parse nor the comparison ever executed. The `set -o
pipefail` I had added made it worse, not better.
`|| status=$?` puts the assignment inside a tested compound command,
which -e exempts, so the script keeps control and decides for itself.
Verified against the same `bash -e` the runner uses:
at baseline 530 passed / 9 failed -> exit 0, "OK"
regressed 527 passed / 12 failed -> exit 1, "12 failing ...
baseline is 9"
restored 530 passed / 9 failed -> exit 0
My bug, introduced in de698b1. The rest of that workflow was sound:
the same run proved checkout, native deps, the pinned-toolchain
install and the build gate all pass, which is the first time this
crate has ever built in CI.
148 lines
6.3 KiB
YAML
148 lines
6.3 KiB
YAML
name: nigig-map
|
|
|
|
# CI workflow for the map rendering crate.
|
|
#
|
|
# Enforces:
|
|
# 1. The map crate compiles (lib + tests).
|
|
# 2. The test suite is green.
|
|
# 3. No regressions in tile parsing, style compilation, or tessellation.
|
|
#
|
|
# This workflow was added to catch runtime errors like:
|
|
# - 'too many elements (N > 100000)' from overpass_parser
|
|
# - 'type mismatch for property style_light: expected MapThemeStyle'
|
|
# - triangulation failures in tile_disk
|
|
|
|
on:
|
|
push:
|
|
paths:
|
|
- 'crates/apps/map/**'
|
|
- 'Cargo.lock'
|
|
- 'Cargo.toml'
|
|
- 'rust-toolchain.toml'
|
|
- '.forgejo/workflows/nigig-map.yml'
|
|
pull_request:
|
|
paths:
|
|
- 'crates/apps/map/**'
|
|
- 'Cargo.lock'
|
|
- 'Cargo.toml'
|
|
- 'rust-toolchain.toml'
|
|
- '.forgejo/workflows/nigig-map.yml'
|
|
|
|
jobs:
|
|
test:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
# Makepad needs a desktop/GL stack even for a check build.
|
|
- name: Install native dependencies
|
|
run: |
|
|
sudo apt-get update -qq
|
|
sudo apt-get install -y -qq \
|
|
pkg-config libwayland-dev libxcursor-dev libxrandr-dev \
|
|
libxi-dev libx11-dev libgl1-mesa-dev libasound2-dev \
|
|
libglib2.0-dev libssl-dev libsqlite3-dev libudev-dev \
|
|
libpulse-dev libxkbcommon-dev
|
|
|
|
# NOT `actions/setup-rust@v1`. That action does not exist on this
|
|
# instance's action registry (data.forgejo.org) and Forgejo does
|
|
# not fall back to github.com, so the job died in "Set up job"
|
|
# with "repository not found" and cancelled all seven steps. It
|
|
# had therefore never built anything. See .forgejo/RUNNER.md.
|
|
#
|
|
# It also asked for `toolchain: stable`, which contradicts the
|
|
# 1.97.1 pin in rust-toolchain.toml. This installs the declared
|
|
# version, matching pay-domain.yml.
|
|
- name: Install the declared toolchain
|
|
run: |
|
|
set -e
|
|
version="$(sed -n 's/^[[:space:]]*channel[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/p' \
|
|
rust-toolchain.toml | head -n 1)"
|
|
curl --fail --location --proto '=https' --tlsv1.2 https://sh.rustup.rs -o /tmp/rustup-init
|
|
chmod 700 /tmp/rustup-init
|
|
/tmp/rustup-init -y --profile minimal --default-toolchain "$version" \
|
|
--component rustfmt --component clippy --no-modify-path
|
|
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
|
|
|
- name: Cache cargo registry
|
|
uses: actions/cache@v3
|
|
with:
|
|
path: |
|
|
~/.cargo/registry
|
|
~/.cargo/git
|
|
target
|
|
key: ${{ runner.os }}-cargo-map-${{ hashFiles('**/Cargo.lock') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-cargo-map-
|
|
|
|
# The gate that matters: until now this crate did not compile at
|
|
# all. Keep it first so a regression is unambiguous.
|
|
- name: Build map crate
|
|
run: cargo build --manifest-path crates/apps/map/Cargo.toml
|
|
|
|
# `cargo test` (no filter) still fails to COMPILE two of the four
|
|
# test targets -- tests/ui.rs imports makepad_widgets::makepad_test,
|
|
# and tests/makepad_visual_tests.rs plus the criterion bench import
|
|
# private modules and a dev-dependency that is not declared. Those
|
|
# are separate pre-existing defects, not map logic.
|
|
#
|
|
# The 535 unit tests in src/ are real and were never executed
|
|
# before the crate compiled. Nine of them fail on genuine logic
|
|
# (4 mvt_parser, 1 overpass_parser, 4 sprite classification), so
|
|
# this is a ratchet rather than a hard gate: it holds the line at
|
|
# the current count and fails if it gets worse.
|
|
- name: Unit tests (ratchet)
|
|
run: |
|
|
# No `set -e` / `set -o pipefail` here, deliberately. The runner
|
|
# already runs steps under `-e`, and `cargo test` exits non-zero
|
|
# while the baseline is above 0, so the command substitution
|
|
# below would abort the step before any ratchet logic ran. That
|
|
# is exactly what happened on the first run of this workflow:
|
|
# 530 passed / 9 failed -- precisely the baseline -- reported as
|
|
# a failure. Capture the status, then decide.
|
|
BASELINE=9
|
|
# `out=$(cmd)` under -e aborts on a non-zero cmd before the next
|
|
# line runs, so `status=$?` never executes. `|| status=$?` keeps
|
|
# the assignment inside a tested compound command, which -e
|
|
# exempts.
|
|
status=0
|
|
out="$(cargo test --manifest-path crates/apps/map/Cargo.toml --lib 2>&1)" \
|
|
|| status=$?
|
|
echo "$out"
|
|
echo "cargo test exit status: $status"
|
|
line="$(echo "$out" | grep -E '^test result:' | tail -n 1)"
|
|
failed="$(echo "$line" | sed -n 's/.* \([0-9]\+\) failed.*/\1/p')"
|
|
passed="$(echo "$line" | sed -n 's/.* \([0-9]\+\) passed.*/\1/p')"
|
|
echo "passed=$passed failed=$failed baseline=$BASELINE"
|
|
if [ -z "$failed" ]; then
|
|
echo "ERROR: could not parse a test result line."
|
|
exit 1
|
|
fi
|
|
if [ "$failed" -gt "$BASELINE" ]; then
|
|
echo "ERROR: $failed failing unit tests, baseline is $BASELINE."
|
|
echo "A new unit test regression was introduced."
|
|
exit 1
|
|
fi
|
|
if [ "$failed" -lt "$BASELINE" ]; then
|
|
echo "$failed < $BASELINE: lower BASELINE in this workflow."
|
|
fi
|
|
echo "OK"
|
|
|
|
# rustfmt could not parse view.rs while the crate was broken, so it
|
|
# silently skipped all of src/ and only ever checked tests/. With
|
|
# the parse error fixed it reports 392 pre-existing diffs in src/.
|
|
# Reformatting them wholesale would bury the next real diff, so
|
|
# this reports and does not gate -- the same reasoning already
|
|
# recorded in doc-engine.yml and sms.yml.
|
|
- name: Formatting (report only)
|
|
run: |
|
|
cargo fmt --manifest-path crates/apps/map/Cargo.toml -- --check \
|
|
|| echo "NOTE: pre-existing formatting drift, not gated yet."
|
|
|
|
# Likewise clippy: -D warnings against a crate with 132 existing
|
|
# warnings is a step that always fails, which gets ignored.
|
|
- name: Clippy (report only)
|
|
run: |
|
|
cargo clippy --manifest-path crates/apps/map/Cargo.toml \
|
|
|| echo "NOTE: pre-existing clippy findings, not gated yet."
|