Repository navigation
Conversation
…check matches a real check run (#9318) Branch protection matches a required check by CHECK-RUN name, and a job's check-run name is its `name:` value. Registering `CI` — ci.yml's WORKFLOW name — matched no check run at all: the context sat permanently "Expected", green merge groups timed out and nothing merged for ~1h45m on 2026-08-17. This job makes the name real, implementing #9283's Option A ruling in the durable form: one stable required context that rolls up every gate job, so adding a gate extends the queue's protection with no settings change. - `ci-rollup` / `name: CI`, `if: always()`, `needs:` filter + the six gate jobs (test-gate, dogfood-gate, temporal-conformance, build-core, build-docs, console-pin). The sharded matrices are deliberately absent: their verdicts arrive through the aggregates, which count per-shard attestations instead of reading the one aggregate word #6082 measured going wrong both ways. - The verdict is computed from `needs.*.result` explicitly, because default propagation would SKIP this job on an upstream failure and a skipped required context is the #3622 deadlock. success/skipped pass; failure/cancelled fail; an unrecognised runner lifecycle value (`abandoned`, #6082) fails closed; an empty `needs` context fails rather than ticking (#4690). - Pins the literal in `check-required-contexts.mjs` (#6865), so a rename of the roll-up fails in the ESLint job instead of silently detaching the gate — the one name in the repo where that protection matters most. Fixes #9318 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NYgmGheCzM6NrHZN436Cxf
|
ACCEPT — PM review at Verified against the diff, not the report: one appended job ( The PR run itself supplied a live acceptance test beyond the card's three criteria: on attempt 1, Flipped ready and armed merge-when-ready. After merge, the maintainer step follows: re-add Generated by Claude Code |
|
应该不需要,已经改过设置了 |
Fixes #9318
Implements #9283's maintainer ruling (Option A — the full suite blocks the merge queue) in its durable form: one always-run roll-up job whose check-run name is exactly
CI, so the queue's required context finally matches a real check run.Why
Branch protection matches a required check by check-run name, and a job's check-run name is its
name:value. The first attempt registeredCI— which is this workflow's workflow name (line 1 ofci.yml), not any job's name. Nothing ever published that context, so it sat permanently "Expected": green merge groups timed out and nothing merged from 11:29Z until the maintainer removed the entry (~13:15Z) on 2026-08-17, ~1h45m. The failure mode had flipped from #9283's "red merges anyway" to "green cannot merge".With this job, the required set stops being a hand-maintained roster of gate job names: adding a gate to
needs:here extends the queue's protection with no settings change.What changed
.github/workflows/ci.yml— one appended job, plus the comment block the file's conventions call for (the name-is-the-contract note, the #9283/#9318 lineage, and why the results are read explicitly):The
needs:list was re-derived from the file, not taken from the card. It matches the card's six gate jobs plusfilter, and three jobs are deliberately excluded:needs:?test-gate,dogfood-gate,temporal-conformance,build-core,build-docs,console-pinfilterfilterfails, every downstreamif:evaluates against empty outputs (THE FILTER CONTRACT, #4928), so no scheduling decision in the run was actually made — a green roll-up would certify a run whose shape nobody chose.test-gate/dogfood-gatealready readneeds.filter.resultfor that reason; this makes it true for the run as a whole.test,dogfood,dogfood-verifyabandoned; run 31114735713: that same value swallowing a shard's realfailure). Listing the matrices here would reintroduce exactly that read, one level up.Verdict logic — computed from
needs.*.resultin a small bash step overtoJSON(needs). Defaultneeds:propagation is not usable: an upstream failure would make this job skip, and a skipped required context is the #3622 deadlock; meanwhile a docs-only PR legitimately skips every core gate and must still publish a greenCI.needs.*.resultsuccess,skippedfailure,cancelledneedscontextTwo of those are judgment calls, stated rather than buried:
cancelledfails, diverging on purpose from the shard gates, which pass it for CI: Dogfood Regression Gate 把 cancelled 当失败 —— 每次连续推送都产生一条假红 #3668's reason (a superseded push cancels the in-flight matrix, and failing there reds a SHA nobody is merging). At whole-gate level the word means the gate never reached a verdict, and on amerge_groupbuild it means the queue build was dropped — neither is something a greenCImay certify. The superseded-SHA cost is unchanged: a newer run publishes newer contexts on the newer SHA.abandoned, CI 聚合门禁把合并队列重建的aggregate result: abandoned判成红 —— 在队 PR 零测试失败被踢出(ci.yml 两处白名单缺abandoned) #6082), and the maintainer rejected whitelisting one as a pass on 2026-08-07: a discarded job is not moot while the queue is still consuming the run's verdicts. A false red costs a re-run; a false green merges unverified code.scripts/check-required-contexts.mjs— one registry row pinningci.yml:ci-rollup → 'CI'. This is the one file outside the card's declared surface, so the reasoning is here rather than implied: the pin (#6865) exists precisely so a rename cannot silently detach branch protection, andCIis about to be the single most load-bearing check name in the repo. Without the row it would be the only required context with no repo-side protection. The row is enrolled ahead of the settings change deliberately — the registry's own header licenses that ("adding a row here does NOT make a context required … a pin that is merely inert, never wrong"), and theauthorizedfield says so in full. Reviewer's call: dropping this hunk leaves the workflow change fully functional and costs only the rename protection.Not touched: triggers (
pull_request+merge_groupwere already there), thefilterjob and what it skips, any other workflow, any repository setting.Sequencing — the maintainer step that follows
⛔ This PR must merge through the queue before the settings change. After it lands, the maintainer re-adds
CIto the required checks (no agent seat can read or write Settings → Rulesets; the API answers 403). At that point the interim per-job entries — and evenTest Core/Dogfood Regression Gate— can be pruned to the singleCIentry.Verification
Union re-run after the final commit, at
9b207e0(=git rev-parse --short HEADat that run):Gate families derived, not recalled —
node scripts/pm/dispatch-gates.mjs .github/workflows/ci.yml scripts/check-required-contexts.mjsnames exactly those five, and re-deriving against the actual changed paths (both files) added nothing beyond the single-path derivation.Reverse verification of the pin (run from the committed state, then restored and confirmed byte-identical to HEAD). Predicted direction: red, naming the job and the context. Observed:
The verdict logic was executed, not eyeballed: the step's real
run:text was lifted out of the parsedci.yml(never retyped) and driven against syntheticneedscontexts. All eight scenarios behaved as designed — including the card's three acceptance criteria:skippedbyfilter)temporal-conformance=failure(the #9283 job)cancelledfilteritself failedabandoned(#6082's undocumented value)needscontext (#4690)Acceptance 3 (the name is exactly
CIin the check-run list) is whatcheck:required-contextsnow pins, and what the parsed YAML reports:ci-rollup => "CI".Tier derivation
Verbatim from
node scripts/pm/dispatch-gates.mjs --tier .github/workflows/ci.yml:Changeset
None — workflow + gate-script only, nothing user-facing is published. Declared the way this repo actually declares it, the
skip-changesetlabel (pr-automation.yml'schangeset-checkexemption), applied at PR-creation time and read back after the labeler settled.Generated by Claude Code