ci: gate main on one aggregate check instead of eleven job names - #391
Merged
Conversation
Branch protection named eleven ci.yml jobs as required status checks — a contract living in GitHub settings, outside git, that no diff shows and every rename breaks. Extracting the test steps into a reusable workflow (#336) renamed the four matrix legs to "Test (Python X.Y) / Test (Python X.Y)", because a job delegating via `uses:` always reports as "<caller> / <callee>". The four bare contexts main required were never reported again and PR #387 sat BLOCKED with every check green (run 31250898534). Renaming the contexts fixes that PR and leaves the next rename to rediscover the same thing. So protection names one ci.yml context, `CI Green`, and the covered list lives in the `ci-green` job's `needs:` — in git, visible in review. `if: always()` is load-bearing: without it the job is itself skipped when a need fails, the context is never reported, and the PR blocks with no explanation instead of a red X naming the culprit. That moves the failure mode rather than removing it, so both escape hatches are closed by scripts/check_ci_gate_complete.py, run by `lint`: - a job added to ci.yml but not to `needs` would run outside the gate and could fail without blocking a merge -> refused; - a job carrying a job-level `if:` legitimately reports `skipped`, so the gate accepts a skip only for jobs declared in ALLOWED_SKIPS (today: mcp-host-config, which cannot run on fork PRs) -> an undeclared conditional, or a stale exemption naming a job with no `if:`, refused. Side effect worth stating: `mcp-host-config` and the two Docker Build jobs were required by nothing before this commit. They are gated now. Not covered, deliberately: fuzz.yml and upstream-identity.yml are separate workflows, out of reach of a ci.yml aggregate; they are not required checks today and this does not make them so. 8 tests, ruff clean, actionlint 0 finding, check_doc_claims 0 finding. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01263uv1QqR8TVzw2jXYUrXn
This was referenced Aug 8, 2026
cdeust
added a commit
that referenced
this pull request
Aug 8, 2026
Re-applies the exact tree validated at 8b97994, which passed 22 checks on the head of #394. Verified byte-identical: `git diff 8b97994` is empty. What this contains, per reverted PR: - #391 scripts/check_ci_gate_complete.py — the `CI Green` aggregate. - #387 .github/actions/test-suite/action.yml — one test suite shared by ci.yml and release.yml instead of two drifting copies. - #393 scripts/check_version_surfaces.py — one gate over all 14 version sites, pyproject.toml as the single canonical source. - #394 the tag becomes an output of a green tree rather than a hand-pushed input. No branch-protection change is required or requested. All eleven required contexts keep their exact names — Lint, Type Check, Build Package, Docker Smoke, Test (Python 3.10/3.11/3.12/3.13), Test (SQLite backend), Test (Windows, SQLite backend) — this only adds jobs alongside them. `CI Green` is not proposed as a required context; it gates the tag, which needs no protection change to be enforced.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Branch protection on
mainnames elevenci.ymljobs as required status checks. That contract lives in GitHub settings — outside git, invisible in review, unversioned — and breaks on every rename.It broke: #336 extracts the test steps into a reusable workflow, and a job delegating via
uses:always reports as"<caller> / <callee>". The four matrix legs becameTest (Python X.Y) / Test (Python X.Y), the four bare contextsmainrequires were never reported again, and #387 sits BLOCKED with every check green (run 31250898534). Renaming the four contexts unblocks that one PR and leaves the next rename to rediscover the same defect.What
One required
ci.ymlcontext,CI Green(theci-greenjob), needing every other job in the workflow. The covered list is in the file, in git, visible in a diff.if: always()is load-bearing — without it the job is itself skipped when a need fails, the context is never reported, and the PR blocks with no explanation instead of a red X naming the culprit.The two escape hatches, closed
An aggregate gate moves the failure mode rather than removing it, so
scripts/check_ci_gate_complete.py(run bylint) refuses:ci.ymlthat is not inci-green.needs— it would run outside the gate and could fail without blocking a merge;if:that is not inALLOWED_SKIPS— it can reportskippedand slip past;ALLOWED_SKIPSentry naming a job with noif:— an exemption guarding nothing hides a real skip.Today
ALLOWED_SKIPSholds exactlymcp-host-config(cannot run on fork PRs), with the reason inline.Side effect worth stating
mcp-host-configand the twoDocker Buildjobs were required by nothing before this PR. They are gated now.Not covered, deliberately
fuzz.ymlandupstream-identity.ymlare separate workflows, out of reach of aci.ymlaggregate. They are not required checks today and this PR does not make them so.Merge order
CI Green+CodeQL.Verification
scripts/check_ci_gate_complete.pyfails onmainas it stands today (noci-greenjob), passes here.ci.yml.ruff format --check+ruff checkclean;actionlint0 finding;check_doc_claims.py0 finding.