Repository navigation
Commit e253f3a
ci: fail fast on the test, test-ui and dogfood matrices in the merge queue only (#31753)
<!-- claude-projects-attribution: {"github_login":"zhuangjianguo"} -->
_Requested by **Steedos** · [project
thread](https://claude.ai/code/project/chan_018ETKaNwMZCNRYD7D8Q9Ubb?thread=cmsg_018ETKaNwMZCNRYD7D8Q9UbbSRBDKqdoCoEAF1SZ4CCZZs)_
Fixes #31517
Clause-②: no
Metadata-protocol: none
## 维护者速读
- **改了什么**:合并队列(`merge_group`)里,Test Core、Test UI、Dogfood
三个测试矩阵改成「一个分片红了,其余分片立即停止」。PR、push、定时运行不变,仍然每个分片都跑完。
- **为什么改**:以前队列里一个分片已经红了,还要等最慢的分片(Test Core 最慢片中位约 19
分钟)跑完聚合检查才报红,排在后面的条目也跟着干等。按裁决 6730013883(A)执行。
- **风险与回滚**:只用矩阵自带的 fail-fast,没有取消整次运行,真红仍然是红(聚合检查读到
`failure`)。代价是队列运行只显示第一个红分片,完整红单仍在作者的 PR 运行里。回滚:把三处表达式改回 `false`。
- **先看**:`.github/workflows/ci.yml` 里 `test` 任务的 `strategy`
段(表达式和说明);`scripts/check-shard-attestation.mjs` 新增的 #31517 自测电池;`ci.yml`
里 `dogfood` 与 `test-ui` 的 `strategy` 段。
- **两分钟验证**:`node scripts/check-shard-attestation.mjs
--self-test`,预期最后一行是 `✓ check-shard-attestation --self-test: 350
assertions …`,并且 `grep -n 'fail-fast:' .github/workflows/ci.yml` 恰好三行,都是
`${{ github.event_name == 'merge_group' }}`。
- **需要你做的**:审阅并亲手合并(`.github/workflows/**` 属 Tier H)。
## What changes
- **`.github/workflows/ci.yml`**: `strategy.fail-fast: ${{
github.event_name == 'merge_group' }}` on `test` (Test Core), `test-ui`
(Test UI) and `dogfood` (Dogfood Regression Gate), as ruled (ruling
record 6730013883, letter A). The expression is false on `pull_request`,
`push`, `schedule` and `workflow_dispatch`, so those runs keep every
shard running to its end. It is the matrix's own fail-fast; there is no
run-level cancel and no `concurrency` change.
- **The A1 wording** (#23177 ruling B, item A1, comment 6139629628): the
`test` strategy comment says why the queue is the exception (its job is
a fast mergeable-or-not answer, and the PR run of the same diff already
showed every red); the Test Core step's A1 note now says A1 holds inside
a shard on every event and the queue is the exception across shards; the
`dogfood`, `test-ui`, Dogfood Regression Gate and Test UI aggregate
comments say how each reads the fail-fast shape.
- **`scripts/check-shard-attestation.mjs`**: a new self-test battery,
`#31517 merge-queue fail-fast: one shard red, the rest cancelled by the
strategy` (8 cases, roster floor 25 → 26), and a header paragraph. No
verdict logic changes. The cases: a red shard beside attested and
fail-fast-cancelled siblings is red by the declared negative and by the
count; a red shard with zero attestations is red (`failure` is never the
zero-attestation #3668 pass); a `failure` matrix asks no cancel cause;
the measured fail-fast cancel annotation classifies as `other`, never a
supersession; if a matrix ever read `cancelled` after a sibling
attested, that cause still reds it; a planned (#26084) roster cut short
is red; the Dogfood Regression Gate reads a red dogfood shard with a
cancelled sibling as red.
- **`scripts/ci-shard-matrix.mjs`**: its self-test fixture job spelled
`fail-fast: false`; it now spells the new expression, so the reader is
exercised over the line ci.yml carries. The other three scripts the card
named (`check-shard-attestation.mjs`, `check-aggregator-roster.mjs`,
`partition-test-shards.mjs`) pin no `fail-fast` anchor: `git grep -n
fail-fast -- scripts` at f2abd47 hits `ci-shard-matrix.mjs:220` only,
plus unrelated step-level fail-fast prose in
`scripts/ci/lane-verdict.mjs` and `scripts/pm/ci-failure.mjs`.
## Tests
<details><summary>Self-tests and live checks of the touched and
card-named scripts (6903a73, and again at the final head 0a383d6, all
exit 0)</summary>
- `node scripts/check-shard-attestation.mjs --self-test`: exit 0, `✓
check-shard-attestation --self-test: 350 assertions …`
- `node scripts/check-shard-attestation.mjs` (static guard over ci.yml):
exit 0, `✓ check-shard-attestation: 2 aggregate gate(s) count 3 declared
leg(s) across 3 attesting job(s).`
- `node scripts/ci-shard-matrix.mjs --self-test`: exit 0, `27 cases pass
across 5 batteries (live: test=8, dogfood=3, test-ui=16)`
- `node scripts/check-aggregator-roster.mjs --self-test`: exit 0 (63
assertions); live: exit 0
- `node scripts/partition-test-shards.mjs --self-test`: exit 0
- `node scripts/ci/scheduled-full-run.mjs --self-test`: exit 0
</details>
<details><summary>The new cases can fail: two mutations, red, then
restored (committed head, in-place edit, `git checkout HEAD --` restore,
blob hash checked)</summary>
- `classifyCancelAnnotations` also reading `The strategy configuration
was canceled` as a supersession: self-test exit 1, failing exactly
`#31517: a shard cancelled by its matrix's fail-fast is never read as a
supersession` and `#31517: were the matrix ever to read cancelled after
a sibling attested, the fail-fast cause still reds it…`.
- `judge()` routing a `failure` leg into the `cancelled` branch:
self-test exit 1, failing exactly `#31517: the first shard red before
any sibling attested, all cancelled ⇒ red…`.
- Both restores: `git hash-object` equal to the HEAD blob and `git diff
HEAD` empty.
</details>
## Acceptance notes
- **The aggregates read the fail-fast shape correctly.** Measured on run
30271824408 (the #3668 experiment, a fail-fast matrix): shard 1
concluded `failure`, shard 2 concluded `cancelled`, and the observer
read the matrix result as `failure`. The cancelled shard's check run
89995981782 carries the annotation `The strategy configuration was
canceled because "matrix._1" failed` (read from the check-run
annotations endpoint). So `Test Core` and the Dogfood Regression Gate
read `failure` (a declared negative, plus the missing credentials), and
`Test UI` reads anything but `success` (or a filter-explained skip) as
red.
- **A fail-fast queue run is never borrowed by a push (#31611,
df91a35).** `queueRunVerdict` in `scripts/ci/scheduled-full-run.mjs`
covers a commit only when its queue run concluded `success`; a run whose
aggregate is red concludes `failure`. `testUiFullGreen` counts only
`Test UI (k/16)` jobs that concluded `success`, so a cancelled shard
makes `ui_full_green` false and the push runs Test UI. Both are pinned
by that script's existing self-test (a `failure` queue run, and 15 of 16
green shards). Nothing in that file changes.
- **What a red queue run shows now.** Only the shards that finished
before the first red one, plus that one. The author's pull_request run
of the same diff still shows every red shard (ruling 6139629628 A1,
unchanged there).
- **Reading after landing (owed by the devx seat, on #31517):** for 7
days of `merge_group` runs of ci.yml, the queue time from the first red
`Test Core (k/8)`, `Test UI (k/16)` or `Dogfood Regression Gate (k/3)`
shard to the matching aggregate concluding red, compared with the same
reading over the 7 days before landing.
- **Noted, not filed (pre-existing, unchanged here):** a matrix where
every shard is killed by its own timeout before any shard attests reads
`cancelled` with zero attestations, and that is #3668's pass with no
cause read (ruled not extended on #22653). Fail-fast does not widen it:
a timeout fires at 60 or 30 minutes, long after the fast shards attest,
and a shard that goes red first makes the matrix read `failure`.
## Verification
<details><summary>Derived gates: node scripts/pm/dispatch-gates.mjs
--commands --repo objectstack-ai/objectstack (63 commands)</summary>
Run at the final head 0a383d6 (origin/main 90cea47 merged): 63
derived, 63 run, every one exit 0. `--ran` verdict: `✓ dispatch-gates
--ran: 63 derived famil(ies) accounted for — 63 run, 0 NOT-MEASURED`.
The first run, at 6903a73 before the merge, read the same 63-command
list; there `check:dts-closure`, `check:dual-build-cjs-loads`,
`check:lean-entry-closure` and `check:sourcemap-no-sources-content`
exited 3 (no built dist yet). `check:type-check-debt` built the
workspace in that run, so on the final head they read a dist built at
6903a73; `packages/objectql` is the only package whose source the merge
moved, and this diff touches no package.
```text
node scripts/check-closing-keyword-parity.mjs :: exit 0
node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0
node scripts/check-comment-mask-corpus.mjs :: exit 0
node scripts/check-declaration-mirrors.mjs :: exit 0
node scripts/check-declaration-mirrors.mjs --self-test :: exit 0
node scripts/check-dts-emitted.mjs --self-test :: exit 0
node scripts/check-self-test-wired.mjs :: exit 0
node scripts/check-self-test-wired.mjs --self-test :: exit 0
node scripts/check-self-test-workflow-commands.mjs :: exit 0
node scripts/check-self-test-workflow-commands.mjs --self-test :: exit 0
node scripts/check-step-collectors.mjs :: exit 0
node scripts/check-step-collectors.mjs --self-test :: exit 0
node scripts/check-whole-set-label-write.mjs :: exit 0
node scripts/check-whole-set-label-write.mjs --self-test :: exit 0
node scripts/ci/assert-turbo-remote-cache.mjs --self-test :: exit 0
node scripts/ci/plan-test-core-shards.mjs --self-test :: exit 0
node scripts/ci/prune-turbo-cache.mjs --self-test :: exit 0
node scripts/ci/scheduled-full-run.mjs --self-test :: exit 0
node scripts/docs-audit/check-drift-comment.mjs :: exit 0
node scripts/pm/bare-root-worklist.mjs --self-test :: exit 0
node scripts/pm/ci-failure.mjs --self-test :: exit 0
pnpm check:agent-test-spelling :: exit 0
pnpm check:aggregator-roster :: exit 0
pnpm check:bash32-floor :: exit 0
pnpm check:ci-filter-parity :: exit 0
pnpm check:cli-command-ids :: exit 0
pnpm check:cross-package-test-inputs :: exit 0
pnpm check:declared-population-live :: exit 0
pnpm check:driver-memory-census :: exit 0
pnpm check:dts-closure :: exit 0
pnpm check:dual-build-cjs-loads :: exit 0
pnpm check:entry-guard :: exit 0
pnpm check:gitlink-declared :: exit 0
pnpm check:lean-entry-closure :: exit 0
pnpm check:node-version :: exit 0
pnpm check:nul-bytes :: exit 0
pnpm check:parse-guard :: exit 0
pnpm check:pm-close-cards :: exit 0
pnpm check:pm-expected-skips :: exit 0
pnpm check:pm-fleet-write-dispatch :: exit 0
pnpm check:pm-fleet-write-execute :: exit 0
pnpm check:pm-fleet-write-validate :: exit 0
pnpm check:pm-governed-merges :: exit 0
pnpm check:pm-issue-transfer :: exit 0
pnpm check:pm-post-stamped :: exit 0
pnpm check:pm-record-recognisers :: exit 0
pnpm check:pnpm-acquisition :: exit 0
pnpm check:pnpm-filter-targets :: exit 0
pnpm check:pnpm-flag-spellings :: exit 0
pnpm check:ratchet-remedy-authority :: exit 0
pnpm check:refd-timer-probe :: exit 0
pnpm check:required-contexts :: exit 0
pnpm check:scripts-symbol-anchors :: exit 0
pnpm check:shard-attestation :: exit 0
pnpm check:sourcemap-no-sources-content :: exit 0
pnpm check:stall-guard-budget :: exit 0
pnpm check:stall-guard-headroom :: exit 0
pnpm check:type-check-coverage :: exit 0
pnpm check:type-check-debt :: exit 0
pnpm check:watch-hint-literal :: exit 0
pnpm check:workflow-status-functions :: exit 0
pnpm check:workflow-step-name-quoting :: exit 0
pnpm check:pm-dispatch-gates :: exit 0
```
Also at 0a383d6: `cd ui && pnpm exec vitest run` on the three
`ui/scripts/__tests__` files that import `scripts/ci-shard-matrix.mjs`
(`select-affected-tests-wiring`, `select-affected-tests`,
`test-file-timings`): 3 files, 95 tests passed.
</details>
Tier H: `.github/workflows/ci.yml` is a governed surface, so the
maintainer merges this by hand. `skip-changeset`: the diff touches only
a workflow and root `scripts/`, which no package publishes.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01QsR2jSkaG5iii6WC7w4qSX)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent f647430 commit e253f3a
3 files changed
Lines changed: 90 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1041 | 1041 | | |
1042 | 1042 | | |
1043 | 1043 | | |
| 1044 | + | |
| 1045 | + | |
| 1046 | + | |
| 1047 | + | |
| 1048 | + | |
| 1049 | + | |
| 1050 | + | |
| 1051 | + | |
| 1052 | + | |
| 1053 | + | |
| 1054 | + | |
| 1055 | + | |
| 1056 | + | |
| 1057 | + | |
| 1058 | + | |
| 1059 | + | |
1044 | 1060 | | |
1045 | | - | |
| 1061 | + | |
1046 | 1062 | | |
1047 | 1063 | | |
1048 | 1064 | | |
| |||
1580 | 1596 | | |
1581 | 1597 | | |
1582 | 1598 | | |
| 1599 | + | |
| 1600 | + | |
| 1601 | + | |
| 1602 | + | |
| 1603 | + | |
1583 | 1604 | | |
1584 | 1605 | | |
1585 | 1606 | | |
| |||
2716 | 2737 | | |
2717 | 2738 | | |
2718 | 2739 | | |
| 2740 | + | |
| 2741 | + | |
| 2742 | + | |
| 2743 | + | |
| 2744 | + | |
2719 | 2745 | | |
2720 | | - | |
| 2746 | + | |
2721 | 2747 | | |
2722 | 2748 | | |
2723 | 2749 | | |
| |||
3083 | 3109 | | |
3084 | 3110 | | |
3085 | 3111 | | |
3086 | | - | |
| 3112 | + | |
| 3113 | + | |
| 3114 | + | |
| 3115 | + | |
| 3116 | + | |
3087 | 3117 | | |
3088 | 3118 | | |
3089 | 3119 | | |
| |||
4147 | 4177 | | |
4148 | 4178 | | |
4149 | 4179 | | |
| 4180 | + | |
| 4181 | + | |
| 4182 | + | |
| 4183 | + | |
| 4184 | + | |
| 4185 | + | |
| 4186 | + | |
4150 | 4187 | | |
4151 | | - | |
| 4188 | + | |
4152 | 4189 | | |
4153 | 4190 | | |
4154 | 4191 | | |
| |||
4373 | 4410 | | |
4374 | 4411 | | |
4375 | 4412 | | |
4376 | | - | |
| 4413 | + | |
| 4414 | + | |
| 4415 | + | |
4377 | 4416 | | |
4378 | 4417 | | |
4379 | 4418 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
83 | 90 | | |
84 | 91 | | |
85 | 92 | | |
| |||
1740 | 1747 | | |
1741 | 1748 | | |
1742 | 1749 | | |
| 1750 | + | |
1743 | 1751 | | |
1744 | 1752 | | |
1745 | 1753 | | |
1746 | 1754 | | |
1747 | | - | |
| 1755 | + | |
1748 | 1756 | | |
1749 | 1757 | | |
1750 | 1758 | | |
| |||
2293 | 2301 | | |
2294 | 2302 | | |
2295 | 2303 | | |
| 2304 | + | |
| 2305 | + | |
| 2306 | + | |
| 2307 | + | |
| 2308 | + | |
| 2309 | + | |
| 2310 | + | |
| 2311 | + | |
| 2312 | + | |
| 2313 | + | |
| 2314 | + | |
| 2315 | + | |
| 2316 | + | |
| 2317 | + | |
| 2318 | + | |
| 2319 | + | |
| 2320 | + | |
| 2321 | + | |
| 2322 | + | |
| 2323 | + | |
| 2324 | + | |
| 2325 | + | |
| 2326 | + | |
| 2327 | + | |
| 2328 | + | |
| 2329 | + | |
| 2330 | + | |
| 2331 | + | |
| 2332 | + | |
| 2333 | + | |
| 2334 | + | |
| 2335 | + | |
| 2336 | + | |
| 2337 | + | |
2296 | 2338 | | |
2297 | 2339 | | |
2298 | 2340 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
217 | 217 | | |
218 | 218 | | |
219 | 219 | | |
220 | | - | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
221 | 223 | | |
222 | 224 | | |
223 | 225 | | |
| |||
0 commit comments