Skip to content

ci: add the CI passed aggregate the org rule can require - #132

Merged
msalvatti merged 2 commits into
mainfrom
chore/ci-passed-aggregate-gate
Aug 7, 2026
Merged

ci: add the CI passed aggregate the org rule can require#132
msalvatti merged 2 commits into
mainfrom
chore/ci-passed-aggregate-gate

Conversation

@msalvatti

Copy link
Copy Markdown
Member

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: core,feature-matrix,doc,ts-rs-drift,wasm-purity,wasm-binding,wasm-pack,supply-chain,invariants,versions,public-api,fuzz-smoke,npm,examples,dogfood,e2e-browser — read from this repo's own ci.yml, not templated.

Why

A required status check is matched by literal name, and the repos in this org name their jobs nothing alike — verify here, quality/container/e2e there, sixteen separate jobs in rust-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 exactly CI passed (not ci / CI passed), and a skipped Mutation testing did not fail it.

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.
Copilot AI lite review requested due to automatic review settings August 7, 2026 17:04

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an aggregate GitHub Actions job that produces a single, stable check name (CI passed) so an organization-level ruleset can require one literal status check across repositories with differing CI job names.

Changes:

  • Adds a ci-pass job named CI passed that depends on the existing CI jobs and runs under if: always().
  • Fails the aggregate check when any dependency job is failure or cancelled (while permitting skipped).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/ci.yml Outdated
Comment on lines +620 to +622
- name: Fail when any dependency did not succeed
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
run: exit 1
- 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.
Copilot AI review requested due to automatic review settings August 7, 2026 17:22

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (1)

.github/workflows/ci.yml:634

  • This step relies on jq being present on the runner image, but the workflow doesn’t install it anywhere else. If the ubuntu-latest image changes (or the job is moved to a different runner), the aggregate check can fail for infrastructure reasons, blocking merges even when all dependencies passed. Consider avoiding jq and rendering the table via python3 (already available on GitHub-hosted runners) so the gate stays self-contained.
        run: |
          {
            echo "| Job | Result |"
            echo "| --- | --- |"
            echo "$NEEDS" | jq -r 'to_entries[] | "| \(.key) | \(.value.result) |"' | sort
          } | tee -a "$GITHUB_STEP_SUMMARY"

@msalvatti
msalvatti merged commit 82d631d into main Aug 7, 2026
28 checks passed
@msalvatti
msalvatti deleted the chore/ci-passed-aggregate-gate branch August 7, 2026 17:28
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.

2 participants