Skip to content

test(ui-merge): the ui gate-wiring pins read the root ci.yml that runs them; pins on jobs it did not port retire - #25879

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-6qe56u
Oct 26, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/project-thread-6qe56u

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Tesla · project thread

Part of #25712 (4b PR 2d-1: the ui/scripts/__tests__ files that read ui/.github/workflows/ci.yml read the root ci.yml instead, or retire).
Part of objectstack#25677.

Clause-②: no
Metadata-protocol: none

维护者速读(草稿)

  • 改了什么: ui/scripts/__tests__ 里有 28 个测试文件读的是嵌套的 ui/.github/workflows/ci.yml,而这个文件在 monorepo 里根本不会运行(GitHub 只运行仓库根目录的 .github/workflows/)。本 PR 新增一个小 helper,按路径读根目录的 ci.yml。17 个文件改为断言根 ci.yml 里真正运行的 type-check-ui / test-ui / build-e2e-ui 任务;另外 11 个文件里,凡是断言对象是根目录没有移植的 objectui 任务(coverage、Build Docs、shard 汇总、timings 上传、两个选择器、turbo 缓存规则)的用例,都退役,并在原处写明由 tooling(ui-wiring): objectstack-side inert wiring for the ui/ workspace — workspace globs, root turbo tasks, path-filtered ui test/typecheck/lint/E2E jobs, spec change compiles the Console; pin gates retire at cutover (parent #25677, 3/6) #25697 workflow 清单的哪一行承接。其中 4 个文件没有别的内容,整文件删除。
  • 为什么改: 2d-3 要删除 ui/.github/。删之前这 28 个文件必须先不依赖它,否则删除时会红 28 个文件。改完以后,无论 ui/.github/ 在不在,这 28 个文件都是绿的。
  • 风险与代价(含回滚): 只动测试和一个测试 ledger,不动任何会运行的代码、workflow 或受管面。退役的 pin 不会悄悄消失:每一条都列在下面的 follow-up 表里。其中一条是真问题:根目录 type-check-ui 的 Turbo 缓存保存没有 objectui#6577 的上限(把那组 pin 指向根任务,6 条里 5 条红)。按 PM 的裁定不在本 PR 里改根 workflow,只列为 follow-up。回滚 = revert 本 PR。
  • 席位意见:(留空)
  • 你要做的: 无。Tier S,由席位落地。

席位核对

(left for the dispatch seat)

Why

GitHub runs only the repository root's .github/workflows/. Since the cutover (#25825), objectui's own ci.yml sits at ui/.github/workflows/ci.yml and runs nowhere. Its four jobs that matter were ported into the root ci.yml by #25697: Type Check became type-check-ui, Test became test-ui, Build & E2E became build-e2e-ui, and lint.yml's Lint became lint-ui.

The 2d census (local, main e167956e plus 2c, with ui/.github/ deleted; per-file table below) found that deleting ui/.github/ reds 81 ui/scripts/__tests__ files. Thirty of them read ui/.github/workflows/ci.yml. Two of those thirty, markdown-test-inputs.test.ts and select-affected-tests-wiring.test.ts, belong to #25851 and are not touched here. This PR is the other 28. The 51 files that scan the workflow directory or read other single workflows are 2d-2 and 2d-3.

The rule for each pin, per the dispatcher's ruling: retarget it to the root workflow by path, or, when the root did not port its subject, retire it and name the roster row (#25697, comment 6388182608) or the root job that now carries the subject. Nothing is skipped, and nothing is folded into a root workflow here; work worth folding is listed as follow-up rows.

What changes

  • New ui/scripts/__tests__/helpers/root-ci.ts. It reads <workspaceRoot()>/.github/workflows/ci.yml and never a copy under ui/. It provides:
    • jobBlock(ci, key), which throws on a missing job, so a renamed job is a red pin and never an empty block;
    • triggerBlock and withoutComments;
    • uiFilterGlobs, the filter job's ui: paths filter, which throws on an empty list;
    • globMatches and repoPath;
    • uiRun(alias), which returns pnpm --dir ui run <alias>, the root's spelling of objectui's commands.
  • 17 files retargeted to the root jobs. The ordering pins keep their meaning inside the root job: "after pnpm install --frozen-lockfile", "before or after turbo's type-check task", "fetch-depth: 0 above the step". The three path-filter pins asserted that objectui's push paths-ignore did not hide a surface. They now assert two things: the root triggers carry no path filter at all, and the filter job's ui: globs cover each surface the gate judges, which is what the job's if: reads.
  • 11 files retire pins on jobs the root did not port. Each retirement is a comment where the pin was, naming its row. Four files had nothing else and are deleted: coverage-shard-reporter-readability, coverage-shard-width, docs-build-trigger and turbo-cache-save-bound. The pure-module cases in the other seven stay, for example check-test-shard-results's budget sizing, which reads only constants.
  • ui/scripts/markdown-test-inputs.mjs drops two ledger rows: docs-build-trigger.test.ts (deleted) and check-action-forward-parity.test.ts, whose only markdown literal (content/docs/guide/ci-cd-pipeline.md, an argument to the old matcher self-check) went with the retargeted pin. markdown-test-inputs.test.ts itself is not touched. Without these two removals it reports stale-test.

Disposition table (28 files)

# File What it read in ui/.github/workflows/ci.yml Disposition Carried by now
1 check-action-forward-parity step after install; push paths-ignore retarget type-check-ui; no trigger path filter; ui: globs cover every SURFACES file
2 check-doc-example-shared-reader the step retarget type-check-ui
3 check-handler-key-read-sites the step retarget type-check-ui
4 check-i18n-call-site-keys step after install retarget type-check-ui
5 check-i18n-designer-table-parity step after install; paths-ignore retarget type-check-ui; ui: globs cover the designer table and the gate
6 check-i18n-en-drift step after install; fetch-depth: 0; paths-ignore retarget type-check-ui (fetch-depth: 0); ui: globs cover the 10 packs, the ledger and the designer table
7 check-lucide-icon-record-names pnpm <alias> anywhere retarget root ci.yml run: pnpm --dir ui run <alias>
8 check-object-metadata-write-doors the step retarget type-check-ui
9 check-package-self-import step after install, in type-check retarget type-check-ui
10 check-phantom-dependencies step after install, in type-check retarget type-check-ui
11 check-unreferenced-sources step after install, in type-check retarget type-check-ui
12 check-published-tsconfig-tooling-exclude the step; published-dist-gate.yml retarget; workflow half retired type-check-ui; published-dist-gate.yml is roster row 23 (kept, follow-up port)
13 check-pending-changeset-literals the Decide whether this change needs a full run exclude pathspecs retarget test-ui reads the ui output; ui: globs cover scripts/ and packages/ test sources
14 scripts-type-check type-check job, step after install retarget type-check-ui
15 vitest-config-type-check after install, before pnpm type-check retarget type-check-ui, before pnpm exec turbo run type-check
16 vitest-setup-type-check after pnpm type-check retarget type-check-ui, after pnpm exec turbo run type-check
17 ensure-chromium-ready ci.yml and live-e2e.yml use the script, no --with-deps retarget; live-e2e half retired build-e2e-ui; live-e2e.yml is roster row 17 (kept, follow-up port)
18 check-doc-expression-carriage node scripts/check-doc-expression-carriage.mjs in docs 1 case retired roster row 7 Build Docs (@object-ui/site) (kept, follow-up port); the page-row pin stays
19 check-test-shard-results test-aggregate wiring; the Test (shard N/M) name 8 cases retired, budget case kept roster row 7 Test (the shard aggregate) (dropped until cutover; port with objectstack's shard attestation)
20 shard-headroom headroom step in test-aggregate and coverage-report 2 cases retired roster row 7 aggregate and coverage
21 test-file-timings test job name, timing reporter, upload; refresh --shards 4 cases retired roster row 28 test-shard-timings-refresh.yml (→ sub-issue 4; "restore Test UI's timings reporter and upload"); test-ui's comment records the wait
22 select-affected-tests the Select the tests this change affects wiring 4 cases retired roster row 7 Test (shard n/16): test-ui runs the whole suite and does not wire the selector
23 select-type-check-scope tc-scope step, TURBO_FORCE, root-programs build 5 cases retired roster row 7 Type Check: type-check-ui uses turbo ...[base] and its own root-programs build step
24 report-turbo-cache type-check prune and save; every workflow's turbo cache 7 cases retired the four root * UI jobs carry objectstack's cache steps (job key, build-core fallback, push-only save, no prune or report); follow-up F2
25 coverage-shard-reporter-readability (deleted, 4 cases) test-coverage reporter flags retired roster row 7 coverage (kept, follow-up port)
26 coverage-shard-width (deleted, 5 cases) test-coverage and coverage-report width retired roster row 7 coverage (kept, follow-up port)
27 docs-build-trigger (deleted, 17 cases) docs job's docs-changes decision step retired roster row 7 Build Docs (kept, follow-up port)
28 turbo-cache-save-bound (deleted, 6 cases) type-check's split, bounded cache save retired type-check-ui carries the save but not the bound; measured below; follow-up F1

Follow-up rows (fold-worthy, not done here)

Row What Why it is not in this PR
F1 Bound the root * UI jobs' Turbo cache saves the objectui#6577 / #7048 way: split restore and save, timeout-minutes, continue-on-error, the cache-hit guard, and a ceiling that leaves the verdict room. Then restore turbo-cache-save-bound's pins against type-check-ui. A real finding. Its six pins, pointed at the root type-check-ui job by a scratch copy, fail 5 of 6. Only "save after the last command" holds. The other five fail because the job keeps a combined actions/cache (the pnpm store), its save has no bound, continue-on-error or cache-hit guard, and its ceiling is 40 minutes. Fixing it is a root ci.yml edit (Tier H), and the dispatcher ruled no folds into root workflows in these PRs.
F2 Decide whether the root ui jobs run report-turbo-cache.mjs (prune before save, restored-key notice), or retire the script. Root cache design is objectstack's; a fold.
F3 Test UI shard aggregate at the required set: port with objectstack's shard attestation, or retire check-test-shard-results.mjs and shard-headroom.mjs. Roster row 7, the maintainer's required-set call.
F4 Coverage lane: push lane vs objectstack's coverage-nightly.yml, then restore the reporter and width pins. Roster row 7, kept, follow-up port.
F5 Build Docs (@object-ui/site): port, then restore docs-build-trigger's derived closure and the carriage-census wiring pin. Roster row 7, kept, follow-up port.
F6 Timings reporter and upload on test-ui with the refresh workflow, then restore test-file-timings's ci pins. Roster row 28 (sub-issue 4).
F7 Wire select-affected-tests.mjs into test-ui once its git diff paths are cwd-relative, or retire it, and the same for select-type-check-scope.mjs. Roster row 7.
F8 live-e2e.yml (row 17) and published-dist-gate.yml (row 23) ports bring their workflow halves back. Kept, follow-up port.

Verification

Run from ui/ per ui/AGENTS.md, at this head (main c475b45b plus this commit):

Run Result
The 24 modified test files plus markdown-test-inputs.test.ts, with ui/.github/ present 25 files, all passed
The same 24 files with ui/.github/ moved aside (the 2d-3 layout) 24 passed (779 tests). markdown-test-inputs.test.ts fails at collection on ENOENT ui/.github/workflows/ci.yml; that file is #25851's.
Whole scripts/__tests__ suite, --shard=1/4 through 4/4, under scripts/pm/os-verify-lock.sh 5,447 passed, 26 failed, 2 skipped
pnpm type-check:scripts the one error is packages/components/src/renderers/action/resolve-icon.ts(265,69) TS2339, identical on unmodified main here; none in a touched file
pnpm exec eslint (touched files), pnpm lint:root, lint:coverage, check:test-path-roots, check:ui-root-lookups, check:lint-rule-coverage, check:entry-guard, check:vi-mock-override-shape; root pnpm check:test-source-alias all exit 0; no lint warning in a touched file

Of the 26 suite failures, one is the owned row from 2c (check-pre-install-import-graph, unresolved: scripts/objectstack-pin.mjs; it clears in 2d-3 with the nested workflows). The other 25 are date-only-zone-pins-10183 ×23 and unit-registry-absence-collision ×2. They fail identically on a clean main checkout here ("ran no case at all" on this unbuilt box), so they are not this diff's.

Derived gates (node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack from this diff): 18 families, all exit 0 at this head. --ran reconciles 18 run, 0 NOT-MEASURED, 0 UNRUN. The slowest were check:query-options-erasure (308 s), check:type-check-debt (287 s) and check-comment-mask-corpus (208 s).

The 2d census: what deleting ui/.github/ reds (81 files; 30 read ci.yml)

Local, main e167956e plus 2c, whole suite in two shards with ui/.github/ deleted. 83 files fail. Two of them (date-only-zone-pins-10183, unit-registry-absence-collision) fail identically on clean main on that box. The other 81 read ui/.github/.

  • ui/.github/workflows/ci.yml (30 files): rows 1–28 above, plus hourly full run: red on main (Lint & Type Check) #25851's markdown-test-inputs and select-affected-tests-wiring.
  • The workflow directory as a population (27 files, 2d-2): check-doc-component-types, check-doc-example-ids, check-doc-example-types, check-doc-json-fences, check-doc-snippet-types, check-hand-rolled-comment-mask, check-i18n-dead-keys, check-lint-rule-coverage, check-lockfile-dedupe, check-lockfile-integrity, check-pre-install-import-graph, check-prompt-component-keys, check-published-dist-tooling, check-readme-exports, check-shell-escape-residue, check-skill-eval-tokens, check-skill-examples, check-skills-paths, check-vi-mock-inherit, check-vi-mock-specifiers, ci-setup-pnpm-wiring, dependabot-merge-gate, docs-links-workflow, merge-queue-reporting, workflow-cache-save-bound, doc-version-claims, labeler-package-coverage (.github/labeler.yml).
  • Single workflows (24 files, 2d-2/2d-3):
    • repo-gates.yml: check-action-ref-convention, check-control-bytes, check-doc-fence-languages, check-doc-snippet-emitted-census, check-docs-route-eager-closure;
    • lint.yml: bash32-floor-wiring, check-test-path-roots, check-vi-mock-override-shape, entry-guard-wiring, lint-workflow;
    • changeset-presence.yml: check-changeset-claims, check-changeset-presence, render-changeset-claims-comment;
    • changeset-guard.yml: check-changeset-no-major, check-changeset-overwrite;
    • performance-budget.yml: check-eager-closure-budget, ci-cd-pipeline-doc, render-budget-comment;
    • one file each: check-governed-queue-guard (governed-surface-guard.yml), check-links-workflow (check-links.yml), check-merge-queue-head (merge-queue-head-patrol.yml), check-new-cross-file-line-citations (line-citation-gate.yml), check-required-check-set (dependabot-auto-merge.yml, required-check-set-patrol.yml), shadcn-check-report (shadcn-check.yml).

🤖 Generated with Claude Code

https://claude.ai/code/session_01A6SEitNngAMugGbuJHWsDS

…s them; pins on jobs it did not port retire

GitHub runs only the repository root's .github/workflows/. objectui's ci.yml
under ui/.github/ runs nowhere, yet 28 ui/scripts/__tests__ files read it.

- New scripts/__tests__/helpers/root-ci.ts reads the root ci.yml by path
  (workspaceRoot()), slices a job, reads the filter job's ui: globs, and
  spells objectui's commands as `pnpm --dir ui run <alias>`.
- 17 files retarget their wiring pins to the root type-check-ui, test-ui and
  build-e2e-ui jobs. The path-filter pins now assert that the root triggers
  carry no path filter and that the ui: filter globs cover each gate's
  surface.
- 11 files retire pins on objectui jobs the root did not port: the coverage
  lane, Build Docs, the shard aggregate, the timings upload, the
  affected-test and type-check-scope selectors, objectui's turbo-cache rule
  and its cache-save bound. Each retirement comment names the workflow
  roster row that carries it. Four of these files had nothing else to pin and
  are deleted, and markdown-test-inputs.mjs drops the two ledger rows whose
  literals went with them.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A6SEitNngAMugGbuJHWsDS
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 26, 2026
@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 26, 2026 02:54
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 26, 2026 02:54
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 26, 2026
Merged via the queue into main with commit 6e0597f Oct 26, 2026
58 of 59 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-6qe56u branch October 26, 2026 03:04
os-tesla pushed a commit that referenced this pull request Oct 26, 2026
…st-ui job through helpers/root-ci

Claude-Session: https://claude.ai/code/session_015oJuSyTy7Y3cm91KJMEW2m
Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

⛔ merge queue 构建失败 — 先分诊,再决定要不要重排

队列构建 40261620902 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集),
所以失败的测试可能在本 PR 没碰过的包里 —— 那不是重排能修的。每次盲目重排都会让排在后面的所有 PR 重建一轮。

分类:failure —— 按下面的日志分诊。

失败的 job(日志抽取,best effort):

  • Test UI (11/16) — 失败步骤: Run the ui tests (shard 11/16)

    × finds no pre-install gate reaching a package 11ms
    FAIL   unit  scripts/__tests__/check-pre-install-import-graph.test.ts > the real tree — every step objectui#6148 measured is still derived > finds no pre-install gate reaching a package
      ↳ 失败原因: AssertionError: a script this repository runs before `pnpm install` needs `node_modules` to load: expected [ Array(1) ] to deeply equal []
    

↳ 失败原因 是判读的关键:超时(Test timed out in … / Hook timed out in …)多半是负载/时序,不是本 PR 的回归;
断言(AssertionError: …)才指向真实的行为改变。两者的 FAIL 行长得一模一样,只有这一行能区分。

⚠️ 断言这一侧有一类例外,判据是断言在测什么,不是它是不是 AssertionError。 断言的对象是产品行为(一个值、一个形状、一次拒收)⇒ 照上面读:真实的行为改变,去查,⛔ 不要重排掉;
断言的对象是这次实验自身的有效性前提(跑完的耗时、负载下的先后、任何只在时间预算内才成立的条件)⇒ 它跟超时是同一类,同样对负载敏感,重排一次是合法的判别手段。
识别是机械的:断言的消息或它比较的值本身点名了一段时长、一个时间戳、一个耗时计数。实测过的一对 —— AssertionError: SecurityPlugin.init() ran: expected false to be true 测的是产品行为(真回归);
AssertionError: this run took over a second, so second-precision stamps could have differed too: expected 1006 to be less than 1000 测的是实验前提:它守护的那条不变式当时是绿的,同一个 head 原样重排一次即成功。
穿着 AssertionError 外衣的时间测量,仍然是时间测量。(⛔ 这只改「怎么读一次红」,不改「哪些测试可以重排」——后者由别处管。)

跨 PR 相同签名(24h,按失败测试文件聚合):

历史信号:

  • 本 PR 过去 24h 无队列失败记录(首次)。
  • 过去 24h 队列共有 8 个失败构建(不含本次)。

分诊清单:

  1. 失败测试在本 PR 改动的包里 → 真回归,修 PR。
  2. 失败测试与本 PR 无关 → 看上面的「跨 PR 相同签名」;已有汇总 issue ⇒ flaky/环境问题实锤,去那张 issue 上谈,修好前重排只会再烧一轮全队列。
  3. 两者都不是 → 可能与同组 PR 语义冲突;等前面的 PR 落地或失败出队后再重排一次即可,不要连续重排。

Generated by Claude Code · merge-queue-triage workflow (#4859)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/xl skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants