ci: add the CI passed aggregate the org rule can require - #30
Conversation
A required status check is matched by literal name, and no two repos here name their jobs alike — from one job in bymax-bio-web to sixteen in rust-auth. There is no list of contexts that works org-wide, which is why required checks never moved above the repository level: only 12 of 38 repos require CI at all, each with its own vocabulary. One aggregate per repo, always spelled `CI passed`, is what a single organisation ruleset can require. It also means a repository created from now on inherits the gate without anyone configuring it. always() is what makes it a gate: without it the job is skipped as soon as a dependency fails, and a skipped check reports neutral — the pull request would look unblocked exactly when it is broken. cancelled is named for the same reason, and is not hypothetical: the Actions incident of 2026-08-06 produced nothing but cancelled jobs for hours.
There was a problem hiding this comment.
Pull request overview
Adds an aggregate GitHub Actions job that reports a single required-check-friendly status (CI passed) summarizing the outcomes of the existing CI jobs, enabling an org ruleset to require one consistent check name across repositories without changing the underlying pipeline behavior.
Changes:
- Adds a new terminal job (
ci-pass) namedCI passedthat always runs and depends oninstall, lint, typecheck, build, unit, e2e. - Fails the aggregate job if any dependency concluded with
failureorcancelled(while allowingskippeddependencies).
Suppressed comments (1)
.github/workflows/ci.yml:129
- This line uses a Unicode em dash (—). Consider replacing it with ASCII punctuation (e.g., a semicolon) to keep workflow comments plain-ASCII.
# neutral — the pull request would look unblocked precisely when it is broken.
| # Single check the org ruleset can require, in every repo, under one name. | ||
| # | ||
| # A required status check is matched by literal name, and this repo's jobs are | ||
| # named nothing like the next repo's — so there is no list of contexts that |
- timeout-minutes: once this is the required check, a hung runner holds every merge behind it for GitHub's default of six hours. - Report every dependency's result, on success as well as failure. The gate reported a bare red X and left the reader opening each job to find which one broke. - Rename the step to what the condition does. skipped is deliberately not a failure here, so "did not succeed" described a stricter gate.
|
On the em dash: I checked before changing it, and the convention here goes the other way — Applying it would create a single repo whose workflow comments are punctuated differently from every other, which is worse for searching than the character itself. Left as is. The other three findings from this review round were real and are applied across all 25 pull requests in this rollout: |
Adds one job that reports a single check named
CI passed, summarising the jobs this repository already runs. Nothing about the pipeline itself changes.Gates on:
install,lint,typecheck,build,unit,e2e— read from this repo's ownci.yml, not templated.Why
A required status check is matched by literal name, and the repos in this org name their jobs nothing alike —
verifyhere,quality/container/e2ethere, sixteen separate jobs inrust-auth. There is no list of contexts that can be written once at the organisation level, and that is why required checks were never centralised: today only 12 of 38 repos require CI at all.With every repo exposing
CI passed, one organisation ruleset requires one context — and every repository created from now on inherits the gate with no configuration.The two guards in the condition
always()— without it the job is skipped the instant a dependency fails, and a skipped check reports neutral. The pull request would read as unblocked exactly when it is broken.cancelled— a cancelled job is not a passing one. Not hypothetical: the Actions incident of 2026-08-06 produced hours of cancelled jobs, and a gate ignoring them would have waved the whole day through.A skipped dependency is accepted on purpose, since jobs here are conditional on the event.
Validated first
Piloted in
nest-cache-example#24: the check appears at top level as exactlyCI passed(notci / CI passed), and a skippedMutation testingdid not fail it.