Repository navigation
Commit 6746140
test(ui): doc-version-claims anchors CI's Node on .nvmrc as well as literal node-version lines (#26432)
<!-- claude-projects-attribution: {"github_login":"os-steve"} -->
_Requested by **Steve** · [project
thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi9SjqqiS9xQoDXazomn1Ty1A)_
Fixes #26421
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:`ui/scripts/__tests__/doc-version-claims.test.ts` 的 Node
版本锚点,现在同时读字面 `node-version:` 与 `node-version-file: .nvmrc`(含
`.github/actions/` 下的 composite),后者按 `.nvmrc` 的 major 计。
- 为什么改:#26419 把约四十个 job 的 Node 改为从 `.nvmrc` 读取后只剩 1 行字面值,这个测试的 15
行下限变红;#26419 已于 03:41Z 合入 main,所以现在 main 上它是红的,本 PR 是 main-red 修复。
- 风险与回滚:只改一个测试文件,不发布任何包;回滚即 revert 本 PR(main 会重新变红)。
- 先看:`ui/scripts/__tests__/doc-version-claims.test.ts` 的
`workflowVersionDeclarations`、`ANCHOR_DECLARATION_FLOOR` 与 fixture 的
`.nvmrc` 分支。
- 两分钟验证:`pnpm --dir ui exec vitest run
scripts/__tests__/doc-version-claims.test.ts`,预期 29/29 通过。
- 需要你做的:无,席位落地。
## What changes
`doc-version-claims.test.ts` used literal `node-version:` lines in
`.github/workflows/*.yml` as the anchor for every Node version the docs
state, floored at 15. #26419 moved about forty jobs onto
`node-version-file: .nvmrc` (mostly through the new
`.github/actions/setup-workspace` composite), which left one literal
line and turned the file red over a CI whose Node had not moved. #26419
merged at 03:41Z (d15f99d), so the file is red on `main` today.
- **Anchor.** `workflowVersionDeclarations` now reads both spellings
`actions/setup-node` accepts, across `.github/workflows/*.yml` and every
`action.yml` under `.github/actions/`: a literal `node-version:` and a
`node-version-file:` reference, resolved against the checkout root and
read the way setup-node reads it (first non-blank, non-comment line).
Each declaration carries `via` (the version file, or null for a
literal). A `.nvmrc` that disagrees with a leftover literal is a split
vote; a missing or unreadable version file is an UNKNOWN declaration,
named, never agreement.
- **Comparison.** The per-entry comparison moved into
`workflowVersionFailures(check)`, so the corpus assertion and the
fixture run the same code. Failure text names both directories and
labels file-read values as `.nvmrc -> "22"`.
- **Floors.** Re-based on readings of both trees as
`ANCHOR_DECLARATION_FLOOR = 10` (readings in the next section). The old
15 was a reading of one shape of the tree; each further job moved into
the composite lowers the count by design, and a floor tight to today's
count would make the next such move a ui test edit again. A collapse to
zero or near it still goes red (ablation below).
- **Census cross-check.** Still honest, now over both keys:
`workflowKeyMentions(['node-version', 'node-version-file'])` walks the
same file list as the parser, and the two must name the same lines.
- **Fixture.** The two-direction fixture stays (now a root with
`.github/workflows/`), and gains a `.nvmrc` arm: a workflow and a
composite action that both read `.nvmrc`, compared against a page
stating `Node 22.x`. It is green at `.nvmrc` 22, red at `v24` (naming
the page line, major 24 and `.nvmrc -> "v24"`), a split vote when a
leftover literal `'22'` disagrees with `.nvmrc`, UNKNOWN at `lts/*`, and
reported (not dropped) when `.nvmrc` is missing.
- Header section and the three `workflowVersionKey` ledger reasons
updated to name the new anchor.
Forced test edits: none outside this file. The whole diff is this card's
own test file; no other test changed.
## Why
The workflow Node version is still single-sourced; the truth moved from
~forty literal lines into `.nvmrc`, which `check:node-version` already
holds the remaining literals to. The anchor has to follow it, or this
file reads a CI whose Node never moved as a CI with no Node.
## Tests
All runs under `scripts/pm/os-verify-lock.sh`, `pnpm --dir ui exec
vitest run scripts/__tests__/doc-version-claims.test.ts`.
| tree | head | result |
|---|---|---|
| (a) `main` at 9a0108c + this change | 79e6d72 | 29/29 passed,
VERDICT command-exit 0 |
| (b) scratch merge of #26419's head 2cb5ee1 onto (a), local, not
pushed | afc11ebf | 29/29 passed, VERDICT command-exit 0 |
| (c) `main` at 75afeff (#26419 landed) merged into this branch |
50e2f7b | 29/29 passed, VERDICT command-exit 0 |
| control: `main`'s ORIGINAL test file on tree (b) | afc11ebf | 2 failed
/ 27 passed: "expected 1 to be greater than or equal to 15" (both
floors), the premise reproduced |
<details><summary>Anchor readings per tree (floor probe:
ANCHOR_DECLARATION_FLOOR set to 1000 through
scripts/ablation-replace.mjs, restored, blob == HEAD)</summary>
- (a) 9a0108c: 59 declarations, all literal, all major 22. Parser and
key-only counter agree (59 = 59).
- (b) afc11ebf: 23 = 1 literal (`scaffold-e2e.yml`'s registry canary) +
22 `node-version-file: .nvmrc` (21 in workflows, 1 in
`setup-workspace/action.yml`). Parser 23 = counter 23.
- (c) 50e2f7b: 23, same shape. Cross-checked by `git grep`: 1 literal,
22 file references under `.github/`.
</details>
<details><summary>Ablation: the anchor pointed back at literals only
goes red on tree (b)</summary>
Both mutations through `node scripts/ablation-replace.mjs` (anchor hit 1
-> 0, blob d54c9e1 -> 0d6f06d8eb46 -> 666e75b1eab5; restored, blob
== HEAD d54c9e1, `git diff HEAD` empty):
1. Parser `-file` arm removed AND counter given only `node-version`: 3
failed / 26 passed.
- pins every workflow-anchored claim: "expected 1 to be greater than or
equal to 10"
- reads every declaration: "control for the agreement above … expected 1
to be greater than or equal to 10"
- fixture `.nvmrc` arm: "expected [] to deeply equal [ [ …(3) ], [ …(3)
] ]"
2. Parser `-file` arm removed only (counter keeps both keys): 3 failed /
26 passed, and the census cross-check names the loss: "the parser and a
counter that knows only the KEYS disagree … expected [ Array(1) ] to
deeply equal [ …(23) ]".
</details>
## Acceptance notes
- **Not touched, per the card:** `.github/**` (root `ci.yml`,
`ui/.github`), and the five ui jobs' pins (`ci-setup-pnpm-wiring`,
`turbo-cache-save-bound`, the eight `pnpm install --frozen-lockfile`
readers). Moving those jobs onto the composite is a later card that
needs a `ci.yml` edit.
- **Coverage gap, noted, not filed (needs `ci.yml`, out of bounds):**
`ci.yml`'s `ui` paths filter lists `.github/workflows/**` but not
`.nvmrc` or `.github/actions/**`. A PR that changes only `.nvmrc` (a
Node bump) or only the composite action does not run Test UI, so this
assertion would first see such a drift on the next ui-touching PR or
`main` run rather than on the PR that caused it. Carrier: the later
`ci.yml` card that moves the five ui jobs onto the composite.
- The floor is deliberately loose (10 against readings of 59 and 23);
its job is to catch a parser or file walk that stopped reading, not to
pin today's count.
- `type-check:scripts` was run locally; it reports 20 errors, all TS2307
/ TS7006 in five other `scripts/__tests__` files that import an unbuilt
`@objectstack/spec` dist in this container, and none in this file. CI's
Type Check UI is the authority.
## Verification
Local gate subset from `node scripts/pm/dispatch-gates.mjs --commands
--repo objectstack-ai/objectstack` (change set: this one file), 17
commands, all exit 0 on 79e6d72; re-run on the final head is reported
in the card's os-dev-report. Derived list:
`check-closing-keyword-parity` (+ `--self-test`),
`check-comment-mask-corpus`, `check:cross-package-test-inputs`,
`check:driver-memory-census`, `check:engine-double-contract`,
`check:gitlink-declared`, `check:nul-bytes`, `check:published-files`,
`check:query-options-erasure`, `check:refd-timer-probe`,
`check:tier-file-adoption`, `check:type-check-coverage`,
`check:type-check-debt`, `check:undeclared-dep-imports`,
`check:watch-hint-literal`, `check:where-matcher`. `eslint` on the file:
clean.
Test-only, publishes nothing: `skip-changeset` label on this PR, no
changeset.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01ADHkmPpSHhxJghrkXZFn8E)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent 55f845a commit 6746140
1 file changed
Lines changed: 390 additions & 113 deletions
0 commit comments