Skip to content

ci(type-check): the affected speed builds the packages the repo-root setup program imports (objectui#12272) - #12277

Merged
objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-12272-typecheck-root-dist
Oct 12, 2026
Merged

objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-12272-typecheck-root-dist

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #12272
Clause-②: no

Since objectui#12222 (PR #12251) a pull request or queue build type-checks the affected set, pnpm type-check "--filter=...[BASE]". That run builds only the dependencies of what it selects, so on a diff outside every package it builds nothing, and the root step pnpm type-check:vitest-setup cannot resolve the five workspace packages the root vitest.setup.* files import (PR #12262: four TS2882, one TS2307, job red). This PR adds one step, on the affected speed only, that builds those packages before the root program; push and schedule are unchanged.

What changed

  • .github/workflows/ci.yml, the type-check job only: a new step Build the packages the repo-root programs import between Run type-check and Type-check repo-root vitest setup files, gated on scope == 'affected' (plus the job's should_run). It runs pnpm exec turbo run build with one --filter per package, replayed from the restored cache when the hash did not move, and prints turbo's own Cached: line as one ::notice (job logs are not readable from a seat container; annotations are). It asks for no run summary, so Report what the turbo cache replayed still reads Run type-check's. The comment on the vitest-setup step names the new step.
  • scripts/select-type-check-scope.mjs: --root-builds prints the packages, read on every run out of tsconfig.vitest-setup.json's paths with TypeScript's own config parser (each target walked up to its package, so ./packages/i18n/dist/* is @object-ui/i18n), never copied; a target in no package throws. The affected verdict also lists them, so the decide step's log says what the build step will build.
  • scripts/__tests__/select-type-check-scope.test.ts: the empty-affected case (the PR ci(spec-main-shape-gate): drop the merge_group trigger now the context is out of the required set (objectui#12252) #12262 diff shape) and the affected-set-without-the-five case (@object-ui/plugin-ai alone) both name the five; --root-builds prints exactly them; the derivation equals the @object-ui/* packages the setup program's files import; a target outside every package throws; the step's wiring (position, scope == 'affected', turbo run build, set -o pipefail, no run summary).
  • content/docs/guide/ci-cd-pipeline.md: the type-check row names turbo run build (the doc pin requires every command the job runs) and says why it runs.

Route, measured first

measurement (turbo 2.10.9, dry runs on 7af0ab37) five packages' build in the run
turbo run type-check --filter=...[BASE], empty diff none (0 tasks)
turbo run type-check --filter=...@object-ui/plugin-ai (a package-only diff) 2 of 5 (fields, plugin-dashboard, plugin-grid missing)
route A as worded: turbo run type-check plus --filter for each of the five 3 of 5: plugin-dashboard and plugin-grid missing, because type-check waits on ^build (dependencies' builds) and never builds a named package's own
turbo run type-check plus PKG#build on the command line 5 of 5, but turbo also adds the five packages' type-check and the uncached e2e root task (23 tasks on an empty diff)
route B: a root task //#type-check:vitest-setup with dependsOn on the five builds 5 of 5 when named with the //# prefix (18 tasks on an empty diff, 20 on the plugin-ai diff); named bare, the filter drops it (0 tasks)
chosen: turbo run build with a --filter per package, its own step 5 of 5 (16 tasks run)

Why this one over route B: the full battery stays exactly as it is (the new step is skipped on push and schedule); the root program keeps its deliberately direct, uncached step (the reason is written on that step: no cache key may decide its verdict); turbo.json is untouched, which keeps this PR's own diff package-less, so its own Type Check run takes the defect's path; and the package list is derived from the tsconfig instead of being a second copy in dependsOn. Route C (skip on an empty set) was not taken: the plugin-ai row shows a non-empty set failing the same way.

The other root programs this job compiles need nothing built: type-check:scripts and type-check:vitest-config each pin that their program imports no workspace package, and the e2e program's two @object-ui/* occurrences are stub-map keys in e2e/sidebar-offcanvas-geometry.spec.ts and e2e/toast-under-modal.spec.ts, not imports.

Local proof: the YAML's own steps, run as CI runs them

A one-off harness (not committed) parses ci.yml and executes the run: text of every step from Decide which packages to type-check through Type-check repo-root vitest setup files as a pull_request event, with GITHUB_OUTPUT, RUNNER_TEMP, the if: conditions and the env: expressions evaluated; no dist/ anywhere before each run.

run tree result
defect reproduced 7af0ab37 (origin/main then), empty diff, the three commands by hand selector scope=affected, turbo "No tasks were executed", vitest-setup exit 2 (the same five errors as PR #12262)
fix, cold cache b1b76e03 build step 16 tasks, 1 cached, turbo 2m3s on the shared 4-core box; vitest-setup exit 0
fix, warm cache (H1) bf00a181 build step Cached: 16 cached, 16 total, turbo 138 ms, step 1.1 s; vitest-setup exit 0
fix, final head 24c8c17c, base 1fb1ced3 4 files changed, zero packages; build step 16 of 16 cached; vitest-setup exit 0
affected set without the five a never-pushed probe commit on 24c8c17c touching packages/plugin-ai/src/AIFormAssist.tsx selector lists @object-ui/plugin-ai alone; Run type-check 10 tasks; build step 16 of 16 cached; vitest-setup exit 0
ablation, empty diff bf00a181 with ci.yml replaced by the base's (the step gone), the committed selector untouched vitest-setup exit 2, the five errors again
ablation, plugin-ai probe the plugin-ai probe with the same ci.yml swap vitest-setup exit 2, exactly fields, plugin-dashboard and plugin-grid

Each ablation restored ci.yml with git checkout HEAD -- .github/workflows/ci.yml, then compared the blob hash with the HEAD blob (match) and read git diff HEAD empty. A test-level ablation at bf00a181 (the same ci.yml swap) turns the new wiring test red: 1 failed, 19 passed; restored, 20 passed.

Verification (local, at 24c8c17c)

  • Every test file that reads ci.yml, turbo.json, the CI doc, the selector or tsconfig.vitest-setup.json (selected by git grep): 76 files, 2,541 tests passed.
  • Gates, hand-derived from this repository's workflows (the objectstack derivation script refuses a sister repository): check-control-bytes, check-action-ref-convention, check-shell-escape-residue, check-bash32-floor, check-doc-links, check-doc-example-ids, check-doc-component-types, check-doc-json-fences, check-doc-fence-languages, check-new-cross-file-line-citations (0 new), check-type-check-coverage, check-required-check-set --self-test, check-pre-install-import-graph, check-test-path-roots, check-lint-coverage, check-changeset-presence (none owed: no published source changed), check-entry-guard, check:docs-route-closure, pnpm type-check:scripts, eslint with --no-inline-config over the changed script and test, a strict YAML parse of ci.yml, a control-byte scan of the four files: all exit 0. check-governed-queue-guard --test answers NOT GOVERNED for the four paths; the card sets this PR to draft anyway (Tier H for workflows).
  • origin/main (PR ci(test): the coverage lane runs eight shards, then both test matrices shard by measured duration (objectui#12208, objectui#12256) #12263, 1fb1ced3) merged in, not rebased; one conflict in two adjacent rows of the CI doc's job table, resolved as this branch's type-check row and main's test row.
  • NOT MEASURED here: this PR's own Type Check run, which is the live package-less case (its four files are outside every package and none is a root-rule file); PR ci(spec-main-shape-gate): drop the merge_group trigger now the context is out of the required set (objectui#12252) #12262 after this lands; actionlint (not installed); repo-wide pnpm lint (CI's Lint job).

Acceptance notes

  • tsconfig.vitest-setup.json's own comment says the ci.yml step "sits after pnpm type-check" so the declarations exist; since objectui#12222 that holds on the full and workspace speeds only, and the new step covers the affected one. Not edited here: it is outside the card's file surface, and a root tsconfig*.json is a root-rule file, so editing it would move this PR to scope=workspace and lose the live run of the defect's path. Carrier: none.
  • scripts/__tests__/vitest-setup-type-check.test.ts's ordering pin still locates the bare pnpm type-check line (the full and workspace branch); the affected branch's ordering is pinned in select-type-check-scope.test.ts.

维护者速读(草稿)

改了什么:Type Check 作业在「只检查受影响包」的快速档(PR 与合并队列)新增一步:在类型检查之后、仓根 vitest.setup.* 的 tsc 之前,用 turbo run build 构建这些 setup 文件引用的五个包(components、fields、plugin-dashboard、plugin-grid、i18n)。包清单每次从 tsconfig.vitest-setup.json 的 paths 读出,不另抄一份;未变的包直接从缓存回放。push 与每小时 schedule 的全量档完全不变。

为什么改:#12251 上线两档速度后,一个不碰任何包的 PR(如只改 workflow 或文档的 PR #12262)选中零个包、什么都不构建,仓根那一步找不到这五个包的类型声明而报错,Type Check 变红;只改 plugin-ai 这类选中了包、但依赖闭包里没有这五个的 PR 同样会红。卡片原文的路线 A(把五个包加进 type-check 的过滤器)经实测不够:type-check 只构建依赖,不构建被点名包自己,plugin-dashboard 与 plugin-grid 仍缺。

风险与代价(含回滚):快速档多一次 turbo 构建;缓存命中时本地实测约 1 秒,冷缓存约 2 分钟(16 个任务,共享 4 核机器)。全量档不受影响。回滚:revert 本 PR 即恢复原状(届时不碰包的 PR 会重新变红)。

席位意见:

你要做的:审阅后给一条批准(本轮 workflow 改动按 Tier H 停在 draft);落地后由席位把 origin/main 合进 PR #12262 并读它的 Type Check。


Generated by Claude Code

…setup program imports (objectui#12272)

Since objectui#12222 a pull request or queue build type-checks only the
affected set, `pnpm type-check --filter=...[BASE]`. A change outside every
package selects zero packages, so nothing built and the root step
`pnpm type-check:vitest-setup` failed to resolve the five workspace
packages the root `vitest.setup.*` files import (four TS2882, one
TS2307; PR #12262). A non-empty affected set can lack them too: a change
to `packages/plugin-ai` alone leaves fields, plugin-dashboard and
plugin-grid unbuilt.

A new step between `Run type-check` and the root program, on the affected
speed only, runs `turbo run build` for those packages (replayed from the
restored cache when unchanged). Which packages is read on every run out
of `tsconfig.vitest-setup.json`'s `paths` by
`scripts/select-type-check-scope.mjs --root-builds`, never copied. Adding
the names to the type-check filter instead was measured and does not
work: that task waits on `^build` and builds no named package's own
declarations. `push` and `schedule` are unchanged.

Claude-Session: https://claude.ai/code/session_01LqNgdPZB2Jnr5HpGbaqLeB
Co-authored-by: Claude <noreply@anthropic.com>
…ig, not a directory walk (objectui#12272)

The markdown-input ledger reads a test that walks a directory and names a
`.md` path as one that may read markdown; this one does neither now.

Claude-Session: https://claude.ai/code/session_01LqNgdPZB2Jnr5HpGbaqLeB
Co-authored-by: Claude <noreply@anthropic.com>
…eck-root-dist

One conflict, content/docs/guide/ci-cd-pipeline.md, two adjacent table
rows: the `type-check` row is this branch's, the `test` row is main's.

Claude-Session: https://claude.ai/code/session_01LqNgdPZB2Jnr5HpGbaqLeB
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读(终稿)· PR #12277 · 席位已对照 diff 逐行校正,2026-10-12T22:28Z

改了什么:ci.yml 的 type-check job 在「按改动范围 type-check」和「根目录 vitest setup 文件 tsc」之间加一步:把根目录 setup 文件 import 的那几个包先 build 出来(@object-ui/components、fields、plugin-dashboard、plugin-grid、i18n)。这一步只在 PR / 合并队列的「受影响」模式跑,push 和每小时全量跑一个字节没变。包名不是写死的:scripts/select-type-check-scope.mjs --root-builds 每次从 tsconfig.vitest-setup.json 的 paths 推出来。选择器的测试加了 7 个用例(空集、受影响集不含这几个包)。

为什么改:#12262 红的原因——PR #12251 之后,不碰任何包的 PR 选包为零、什么都不 build,根目录那步 tsc 找不到这五个包的类型。dev 实测了三条路:卡上写的 A(把五个包加进 type-check 的 filter)只会 build 其中 3 个;B(turbo 根任务)要动 turbo.json 并改全量路径;只在空集时跳过不够(受影响集不含这五个包时同样红)。最后是「单独一步 build」。

风险与代价(含回滚):这一步在 turbo 缓存命中时约 1 秒(本地 16/16 命中;main 的缓存已经在回放 build),冷启动约 2 分钟。本 PR 自己的 diff 正好不碰任何包,所以它自己的 Type Check run 就是现场验证——已绿(22:24Z),而 #12262 同一步是红的。回滚:删掉这一步即可。

席位意见:建议批准。修在根因处、不削弱任何检查、全量路径未动、现场已证明。

你要做的:在 PR 上 Approve;席位翻正式入队,落地后把 main 合进 #12262,它转绿后你挂的 auto-merge 自动合。

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 12, 2026 22:57
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 12, 2026 22:57
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 12, 2026
Merged via the queue into main with commit 48fb558 Oct 12, 2026
31 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-12272-typecheck-root-dist branch October 12, 2026 23:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd configuration documentation Improvements or additions to documentation tests

Projects

None yet

2 participants