Repository navigation
ci(ui-merge): the seven @objectstack packages build once per run and the ui jobs replay them; every ui cache save is bounded - #25963
Merged
Conversation
…hand the ui jobs their turbo cache entries; bound every ui cache save Claude-Session: https://claude.ai/code/session_01XpG2CKzNjLujzcMmSxKCHy Co-Authored-By: Claude <noreply@anthropic.com>
…ff are pinned against the root ci.yml Claude-Session: https://claude.ai/code/session_01XpG2CKzNjLujzcMmSxKCHy Co-Authored-By: Claude <noreply@anthropic.com>
…oot jobs' prune and report (row F2) Claude-Session: https://claude.ai/code/session_01XpG2CKzNjLujzcMmSxKCHy Co-Authored-By: Claude <noreply@anthropic.com>
os-zhuang
approved these changes
Oct 26, 2026
os-zhuang
marked this pull request as ready for review
October 26, 2026 06:10
os-zhuang
enabled auto-merge
October 26, 2026 06:10
os-tesla
pushed a commit
that referenced
this pull request
Oct 26, 2026
One lint-ui hunk: the Repo Gates' built-type block stays, followed by #25963's prune step and bounded save, unchanged. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015MoCPtpv6AtTo899tF8Ktq
This was referenced Oct 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Tesla · project thread
Fixes #25869
Part of #25677 (post-cutover CI speed, item 3; rows F1, F2, F11 and F13).
Clause-②: no
Metadata-protocol: none
What changed
.github/workflows/ci.yml, the ui jobs only:ui-deps(Build UI Deps). It builds the seven @objectstack packages objectui consumes ONCE per run, with the sameturbo run buildcommand the ui jobs use, then prunes.turbo/cacheto that build's tasks (scripts/ci/prune-turbo-cache.mjs) and uploads those entries as the artifactui-deps-turbo-cache(36 tasks, ~27 MB, stored uncompressed because the entries are zstd already, kept one day). Itsif:is the union of the four ui jobs' conditions. The build carries Build Core's fourTURBO_*lines verbatim, followed byassert-turbo-remote-cache.mjs, so a queue ormainrun replays a closure that was already built from the remote cache. Apull_requestrun still gets no remote credentials.type-check-ui,test-ui,lint-ui,build-e2e-ui) nowneedui-depsand download the artifact into.turbo/cachebefore their unchangedBuild the @objectstack packages objectui consumesstep. That step then replays every task, measured locally at 1.2 s for 36 of 36 cached. The download iscontinue-on-error. Every job'sif:is byte-identical and starts with!cancelled(), so a red, cancelled or skippedui-depsnever skips a ui check: with no artifact, the job builds cold exactly as before. Nothing the ui jobs test changed.dist/.type-check-uiandlint-uirun further turbo tasks that depend on^build, and only a cache hit stops turbo rebuilding the seven packages there. Turbo still hashes every task, so an entry that does not match the tree gets rebuilt rather than trusted.turbo run build --dry=jsongives the same 36 task hashes with and without the env the jobs differ in (TURBO_RUN_SUMMARY,NODE_OPTIONS,TURBO_CACHE).actions/cache/savewithtimeout-minutes: 5andcontinue-on-error: true, placed after the job's last checking step and guarded on its restore'scache-hit. No ui job uses the combinedactions/cacheany more. The pnpm store is restored by every ui job and saved byui-depsalone.test-uiandbuild-e2e-uidrop their own turbo seed, since the seven-package build is their only turbo run.type-check-uiandlint-uikeep theirs.ui/scripts/report-turbo-cache.mjs. The prune before each seed save is objectstack'sscripts/ci/prune-turbo-cache.mjs(the same summary-driven prune, fed by job-levelTURBO_RUN_SUMMARY). The hit/miss report isassert-turbo-remote-cache.mjs's step-summary table onBuild UI Deps. The script retires with its last callers, the nestedui/.github/workflows/(tooling(ui-merge): governance in-repo — liveness evidence and spec tests stop citing objectui by commit, one sdui-parser, AGENTS.md / pm scripts dropobjectui#,ui/AGENTS.mdnests, 18 governance workflows merged or retired (parent #25677, 4b/6) #25712);report-turbo-cache.test.ts's retirement note now says so.lint-ui, using objectui's rule (smallest round number that is ≥ 3× the slowest successful run and ≥ that run + 15 min) over every successful job since the cutover. Lint UI: n=42, max 558 s, which gives 30 (unchanged). Build & E2E UI: n=51, max 457 s, which gives 25 (was 45; nothing backed the extra 15).ui-depsis 25 by the same rule.Build UI Depsamong the carriers.ui/scripts/__tests__/turbo-cache-save-bound.test.tsis restored, retargeted to the root jobs by path throughhelpers/root-ci.ts. It brings back the six pins #25879 retired, now over all five jobs: main-phase saves, bounded and non-fatal, ceiling at least twice the bound, saves after the last command, the same key with acache-hitguard, and ceilings not raised. It adds the hand-off pins:needs: ui-depswith an!cancelled()if:, a fail-open download before the build step, and a build command identical toui-deps's.⛔ Not touched: the lint-ui gate steps #25902 adds. That PR edits lines next to two of this PR's
lint-uihunks (theInstall dependenciesstep and the steps beforeSave Turbo cache). Whichever lands second takes a small textual merge. Re-derive Lint UI's ceiling when #25902's gates land, because they add a full ui-package build to that job.Measured before (the card's "before")
The 51 CI runs that scheduled ui jobs between the cutover (#25825) and 2026-10-26T05:30Z, step and job times taken from the Actions jobs endpoint:
A cold seed is the common case. The seeds are saved per job on
mainpushes, so a PR or queue entry whose closure differs from the newest seed's misses in all twenty jobs at once. Examples: queue entry 40271867662 (#25940, ui test files only) 70.2 runner-min; PR run 40266487909 74.0; push 40268844566 62.0.Expected after (ui-deps builds once): a cold full-lane run spends one build (~4 min) instead of ~70 runner-min. A warm run gains ~1.5 runner-min (one more job's setup and twenty ~27 MB downloads). On this window's mix that is roughly −900 of 1191 runner-min. The cost is wall clock: a ui job now starts after
ui-deps, about one job-setup plus one upload (~1–1.5 min) later than it used to start its own build. On a warm run that is pure wall-clock loss; on a cold run it largely offsets the ~3–4 min build each job no longer runs. This PR's own CI run (all lanes, sinceci.ymlis in theuifilter) gives the first after-reading; the card gets the per-job before/after table once comparable PRs have run.Option (b) of the card (a
pull_requestrun reads the signed remote cache) is not taken. Turbo reads the remote with the same token that writes it, and Build Core's "Turbo remote cache (#21186)" comment withholds both secrets from PR code on purpose. Giving PRs a read would reverse that ruling, which is the maintainer's call and not a seat's.Verification
ui/pnpm exec vitest run scripts/__tests__/turbo-cache-save-bound.test.tsat this headmain'sci.yml(17c5e68b), restored withgit checkout HEAD ----summarizepackages/spec/dist, from that cache dirFULL TURBO, 1.2 s,dist/restoredturbo run build --dry=jsonwith and withoutTURBO_RUN_SUMMARY/NODE_OPTIONS/TURBO_CACHEDerived gates (
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, 3 paths, atcd0ae004): 63 families. 62 exit 0.pnpm check:dual-build-cjs-loadsexits 3, PREREQUISITE NOT MET: it reads thedist/of every package, and this box has built only the ui closure. CI's Lint & Repo Gates runs it on a full build.--ranreconciles: "63 derived famil(ies) accounted for — 62 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)". The slowest, on a shared box:pnpm check:type-check-debt(410s),pnpm check:pm-dispatch-gates(346s),pnpm check:query-options-erasure(286s),node scripts/check-comment-mask-corpus.mjs(161s).Push-environment battery (
GITHUB_ACTIONS=true GITHUB_EVENT_NAME=push node scripts/pm/check-dispatch-gates.mjs, both tiers): it runs after this body was written, and its verdict line goes in the card report.Acceptance notes
ui/scripts/report-turbo-cache.mjshas no root caller now. It retires with its last callers, the nested workflows (tooling(ui-merge): governance in-repo — liveness evidence and spec tests stop citing objectui by commit, one sdui-parser, AGENTS.md / pm scripts dropobjectui#,ui/AGENTS.mdnests, 18 governance workflows merged or retired (parent #25677, 4b/6) #25712, 2d-3), not here: those workflows still call it, andrender-budget-comment.test.tsandturbo-lint-inputs.test.tsstill read it.type-check-ui's 40-minute ceiling is not derived here (F13 named Lint UI and Build & E2E UI). Over the same population its max is 1194 s; objectui's rule would give 60. It is pinned at 40 as "does not rise".维护者速读(草稿)
改了什么: ui 的四个 CI 作业以前各自构建同样的 7 个 @objectstack 包。现在新增一个
Build UI Deps作业,每次 CI 只构建一次,再把 turbo 缓存条目交给这四个作业,它们约 1 秒就能回放出构建结果。同时,所有 ui 缓存保存都加了时限,保存失败也不会让作业变红。Build & E2E UI 的超时按实测推导,从 45 分钟降到 25 分钟。为什么改: 合并后的 51 次运行里,有 27 次是每个 ui 作业各自冷构建一遍(全量运行每次 33–77 runner-min),这一步合计 1191 runner-min。缓存保存没有时限,上传一旦卡住,已经通过的检查会被取消,合并队列会把它当成失败(objectui#6577 出过这个事故)。
风险与代价(含回滚): ui 作业要等
Build UI Deps跑完才开始,墙钟大约多 1–1.5 分钟。冷构建时这部分基本被省下的构建时间抵消,热缓存时就是净增。下载失败时作业会自己冷构建,和现在一样,所以不会因此跳过或变红任何必需检查。回滚就是 revert 这个 PR。席位意见:
你要做的: 这是 Tier H(
.github/workflows/ci.yml),需要 os-zhuang 或 hotlong 批准。Generated by Claude Code