Skip to content

ci: report gate skips as SKIP, and a deleted baseline as a failure - #1306

Merged
justinjoy merged 3 commits into
mainfrom
fix/1301-gate-skip-exit-codes
Sep 3, 2026
Merged

ci: report gate skips as SKIP, and a deleted baseline as a failure#1306
justinjoy merged 3 commits into
mainfrom
fix/1301-gate-skip-exit-codes

Conversation

@justinjoy

Copy link
Copy Markdown
Collaborator

Refs #1301. Third instance of this defect class (#1288 fixed check-release-template.sh, #1302 the wl_log_emit provenance check), so the guard here is shared rather than per-gate.

The defect

Five meson-registered gates printed SKIP: … and exited 0. Meson reads exit 0 as a pass, so each was recorded as having asserted something it never looked at.

check-abi-manifest.sh · check-abi-symbols.sh · check-abi-symbols-locale.sh · check-abi-symbols-macos.sh · check-sbom-snapshot.sh

All five are reached only through tests/meson.build. 77 is safe under meson and not under a bare workflow run: step, where GitHub's bash -e fails the job — each header now says so.

Two branches go the other way, to exit 1

abi/libwirelog-1.0.abi.json and sbom/snapshot.txt are committed, so absence means a baseline was deleted, not that the build can't answer. check-abi-symbols.sh has always treated a missing allowlist as a hard failure — three gates were giving three verdicts for one condition.

Both sit behind their tool probes, so exit 1 is only reachable on a host that could otherwise have checked; the release tarball ships both files; and every downstream/upgrade consumer builds -Dtests=false, so these gates aren't even registered there.

In check-abi-manifest.sh the baseline check deliberately precedes the arm64 arch skip: a deleted baseline is true on every architecture at once, so severity outranks environment, and the order makes the arm64 leg a second detector rather than a blind spot.

One deliberate inconsistency

check-abi-symbols-macos.sh keeps exit 0 for a missing allowlist. That gate reports real symbol drift as a warning, so a missing allowlist — strictly less informative than drift — cannot carry a harsher status than the drift itself; and 77 would show SKIP for "no allowlist" beside OK for "the symbols diverged."

The rule the file now states: 77 means the environment cannot supply the input; once it can, the gate's own severity applies.

#1301 contradicts itself here: its out-of-scope section names :46 and :70 as advisory by design, its exit-1 section names :48 — the same branch's exit. The out-of-scope reading is coherent, and that adjudication is recorded next to the branch.

The shared guard

Partitions every meson-registered check script into COVERED (16) or EXEMPT (3, each with a reason) and fails when one is neither. Listing the ten already-clean gates is the point — a list of only the broken ones couldn't guard them.

One exemption is honest rather than principled: check-release-template.sh has the defect and is exempted only because #1288 fixes it on another branch. It's labelled as the one entry failing the file's own rule, with a TODO to promote it.

Four defects found in the guard itself

Three are the same class this PR exists to fix:

defect consequence
git fixture used cd, but GIT_DIR overrides it committed the caller's uncommitted work while printing "all cases passed"; with GIT_DIR alone, deletes the tracked tree. It fired against this worktree during review. Also unnecessary — the gate invokes git zero times
grep -A | grep -q under pipefail grep -q kills its producer; reported "no defect" on a large file
the obvious repair, printf | grep -c failed identically — grep -c returns 1 on a zero count, and || true can't distinguish that from a producer dying at 141. Removing the pipeline, not hardening it, was the fix
the coverage guard was fail-open a scan matching nothing reported success — this PR's own defect one level up

Each now has a mutation that kills it.

Validation

  • abi suite 42 Ok / 0 Fail / 0 Skipped on Linux x86_64 with abidiff and syft present — nothing that could enforce was downgraded; a patch turning everything into 77 would show up here
  • full suite 305 Ok / 0 Fail / 12 Skipped (all skips pre-existing)
  • 30 assertions; mutation-tested including both exit-1 conversions, the arm64 arch-skip, three quote/printf evasion shapes, uppercase and underscore gate names, and an empty scan
  • the backstop's window has 18 lines of false-positive slack but only one line against false negatives; the comment states the one-line figure, verified empirically (gap=6 caught, gap=7 evades)

Three review rounds; final verdicts Reviewer, Architect and Critic all approving.

Five meson-registered gates printed "SKIP: ..." and then exited 0.  Meson
reads exit 0 as a pass, so each was recorded as having asserted something
it never looked at: check-abi-manifest.sh, check-abi-symbols.sh,
check-abi-symbols-locale.sh, check-abi-symbols-macos.sh and
check-sbom-snapshot.sh.  This is the third instance of the defect in this
repository -- #1288 fixed check-release-template.sh and #1302 the
wl_log_emit provenance check -- so the guard here is shared rather than
per-gate.

Those branches now exit 77 through a named SKIP_EXIT.  All five are
reached only through tests/meson.build; 77 is safe under meson and not
under a bare workflow `run:` step, where GitHub's `bash -e` would fail
the job, and each header now says so.

Two branches move the other way, to exit 1.  abi/libwirelog-1.0.abi.json
and sbom/snapshot.txt are committed, so their absence means someone
deleted a baseline rather than that this build cannot answer -- and
check-abi-symbols.sh has always treated a missing allowlist as a hard
failure, so three gates were giving three verdicts for one condition.
Both sit behind their tool probes, so exit 1 is only reachable on a host
that could otherwise have checked, and the release tarball ships both
files.  In check-abi-manifest.sh the baseline check deliberately precedes
the arm64 arch skip: a deleted baseline is true on every architecture at
once, so severity outranks environment here, and keeping the order makes
the arm64 leg a second detector rather than a blind spot.

check-abi-symbols-macos.sh keeps exit 0 for its missing allowlist.  That
gate reports real symbol drift as a warning, so a missing allowlist --
strictly less informative than drift -- cannot correctly carry a harsher
status than the drift itself, and 77 would show SKIP for "no allowlist"
beside OK for "the symbols diverged".  The rule the file follows, now
written down: 77 means the environment cannot supply the input; once it
can, the gate's own severity applies.

Note that #1301 contradicts itself on this point.  Its out-of-scope
section names :46 and :70 as advisory by design; its exit-1 section names
:48, which is the same branch's exit.  The out-of-scope reading is the
coherent one and is recorded next to the branch so the next reader finds
it adjudicated rather than open.

The shared self-test partitions every meson-registered check script into
covered or exempt and fails when one is neither, so a gate added later
cannot quietly reintroduce this.  Listing the ten already-clean gates is
the point: a list of only the broken ones could not guard them.  One
exemption is honest rather than principled -- check-release-template.sh
has the defect and is exempted only because #1288 fixes it on another
branch; it is labelled as the one entry that fails the file's own rule,
and should move once that lands.

Four defects in the guard itself were found by review and are worth
recording, because three are the same class this commit exists to fix.
Its fixture built a throwaway git repository, and GIT_DIR overrides `cd`
rather than supplementing it -- so under a hook, `git bisect run` or
`git rebase --exec` it committed the caller's uncommitted work while
printing "all cases passed".  With GIT_DIR alone it deletes the tracked
tree entirely.  It fired against this worktree during review.  The
fixture was also unnecessary: check-abi-manifest.sh invokes git zero
times.  Separately, `grep -A | grep -q` under pipefail reported "no
defect" on a large file because grep -q killed its producer, and the
obvious repair -- capturing, then `printf | grep -c` -- failed the same
way, since grep -c returns 1 on a zero count and `|| true` cannot tell
that from a producer dying at 141.  Removing the pipeline, not hardening
it, was the fix.  And the coverage guard was fail-open: with a scan that
matched nothing it reported success, which is this commit's own defect
one level up.  Each now has a mutation that kills it.

Verified: abi suite 42 Ok / 0 Fail / 0 Skipped on Linux x86_64 with
abidiff and syft present, so nothing that could enforce was downgraded --
a patch turning everything into 77 would show up there.  Full suite 305
Ok / 0 Fail / 12 Skipped, all skips pre-existing.

Refs #1301.
This test and PR #1304's log_abi_testhook_provenance were both inserted
immediately before log_abi_no_testhook_in_libwirelog, so the two conflict
on merge even though each is a pure addition.

Moved above log_abi_header_not_public.  Verified the full stack now
merges bottom-up without conflict.
check-manifest-collation.sh (#1294) and check-sbom-snapshot-locale.sh
(#1291) are meson-registered on their own branches and were in neither
list here, so merging those branches with this one failed the coverage
guard.  That is the guard working -- both gates had SKIP branches exiting
0, the defect this issue exists to remove, introduced in gates written to
fix other issues.  They are fixed on their own branches and listed here.

A listed gate may legitimately be absent while these land separately, so
absent-and-unregistered is now a note rather than a failure.  Absent but
still registered in meson remains a failure: that is a moved or deleted
gate, which is the case the check is for.
@justinjoy
justinjoy force-pushed the fix/1301-gate-skip-exit-codes branch from cefa4e3 to 1509692 Compare September 3, 2026 01:00
@justinjoy
justinjoy enabled auto-merge (rebase) September 3, 2026 01:02
@justinjoy
justinjoy merged commit 921a25d into main Sep 3, 2026
26 checks passed
@justinjoy
justinjoy deleted the fix/1301-gate-skip-exit-codes branch September 3, 2026 02:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant