Repository navigation
ci(ui): regenerate the SDUI manifest in Build & E2E UI and compare it with the committed bytes (#26137 PR A) - #26315
Merged
Conversation
… with the committed bytes (#26137) check-sdui-manifest judges freshness from committed per-package source digests, so it cannot see an edit to @objectstack/sdui-parser, to a package the registry imports, or two queued PRs whose effect only shows together. Build & E2E UI now runs scripts/gen-sdui-manifest-node.mjs after its @objectstack build and fails when sdui.manifest.json differs from what this tree generates. The 36 @objectstack tasks replay from Build UI Deps; the 27 @object-ui builds plus the enumeration cost 213 s cold on 4 cores. - ci.yml `ui` filter: turbo.json's globalDependencies and the manifest's own four files, so a diff that moves only those still runs the step. - Build & E2E UI ceiling re-derived 25 -> 35 (457 + 213 s), with the pin in ui/scripts/__tests__/turbo-cache-save-bound.test.ts. - lint.yml and check-sdui-manifest.mjs prose, and releases-maintenance.md, point at the new step. The digest check stays until this is green on main. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A6SEitNngAMugGbuJHWsDS
Contributor
Author
|
Check Changeset: the one red check on
|
os-zhuang
approved these changes
Oct 26, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to a conflict with the base branch
Oct 26, 2026
#26278 widened the ci.yml `ui` filter (every root workflow, .github/prompts, skills/objectui). Both sides kept: main's entries, then this PR's turbo globalDependencies and the SDUI manifest's four files. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A6SEitNngAMugGbuJHWsDS
This was referenced Oct 27, 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
Part of #26137 (PR A of two: the CI comparison; PR B retires the per-package records once this is green on
main). Tier H (.github/workflows/**).Part of objectstack#25677.
Clause-②: no
Metadata-protocol: none
维护者速读(草稿)
Build & E2E UI多了一步:用node scripts/gen-sdui-manifest-node.mjs从本树重新生成sdui.manifest.json,再和提交的文件逐字节比较,不一致就红,并打印差异和修复命令。ci.yml的ui过滤器加了 turbo 的四个全局依赖文件,以及清单自己的四个文件。原来 lint 里按源码摘要判新鲜度的检查保留不动。src/,看不见三类变化:解析器@objectstack/sdui-parser的改动、registry 运行时引用的@objectstack包的改动、两个排队 PR 合起来的效果。实测:在main上改manifestFromConfigs一行,现有检查仍是绿的,而重新生成的清单差了 87 行。现在 PR 和合并队列的合并树上都会重新生成并比较。main重新生成与提交的字节完全一致。@object-ui包冷构建 3m25s,枚举 8s;36 个@objectstack任务从 Build UI Deps 回放)。今天 22 次绿 run 里 ui 尾部都比它长,所以墙钟时间增加 0。Build & E2E UI超时按规则重算为 35 分钟。席位核对
(left for the dispatch seat)
Why
check-sdui-manifest(lint, every PR) judges the committedsdui.manifest.jsonfresh when each registry package'ssrc/digest equals its one-line record underscripts/sdui-manifest.sources/(#26051, #26120). That digest is blind to everything outside thosesrc/trees that moves the artefact:@objectstack/sdui-parser, which the generator imports frompackages/sdui-parser/dist. Since the lockstep gate retired (chore(sdui-parser): retire the objectui lockstep gate and its vendored record #26221) nothing ties a parser edit to the records, and after 2g PR 2 deletesui/packages/sdui-parserthe records stop reaching any parser at all (devx(sdui): CI regenerates the sdui manifest and compares it to the committed artefact, so ui PRs conflict only on real contract changes and the merge queue catches combined effects #26137 comment 6420796812);@objectstackpackages the registry imports at runtime (spec,client,core,formula,types), and anypackage.jsonor lockfile change;Before: the gap on
main, measuredOn
main81bba6c, inpackages/sdui-parser/src/index.tsmanifestFromConfigs,isContainer: c.isContainer→isContainer: c.isContainer ?? false:node scripts/check-sdui-manifest.mjs: exit 0, "present, intact … each package's digest current in its record";node scripts/gen-sdui-manifest-node.mjs:sdui.manifest.json1 file changed, 87 insertions(+).So a stale manifest passes today. With this PR, the same edit reds
Build & E2E UIon the PR, becausepackages/sdui-parser/**is inui_consumersand the step serialises through the parser the job just built.What changes
ci.yml,Build & E2E UI: the comparisonA new step, "The committed SDUI manifest is the one this tree generates", after "Build the @objectstack packages objectui consumes" and before the Console build:
Build UI Depsbuilds and hands over, and they replay from the downloadedui-deps-turbo-cache. The other 27 are the@object-uiregistry closure.mainis byte-identical to the committed file (sha2561f6e1ccb925a…, 106 components), and two runs agree.pull_request, 6merge_group, 2push). The ui lane's tail afterBuild UI Depswas 8.4–14.2 min in the same runs, so the added wall time measured 0 in all of them. Lint UI builds the 27 too, but it runs on theuioutput only, so a PR that changes only the parser or one of the five packages would skip it (devx(sdui): CI regenerates the sdui manifest and compares it to the committed artefact, so ui PRs conflict only on real contract changes and the merge queue catches combined effects #26137 comment 6424273287).check-sdui-manifestuntil PR B.ui/apps/console/vite.config.tsaliases every workspace package to itssrc/, so the dist this step builds does not reach it.ci.yml, theuifiltertsconfig.json,tsconfig.base.json,tsconfig.test.base.json,tsup.config.tsturbo.json'sglobalDependencies. Every build task hashes them, so they move what the ui jobs build. The digest never saw them either.sdui.manifest.json,scripts/sdui-manifest.record.json,scripts/gen-sdui-manifest-node.mjs,scripts/check-sdui-manifest.mjsThe registry's runtime closure, walked over
dependenciesandpeerDependenciesfrom the 17 seeds, is the 27 ui packages plusspec,client,core,formulaandtypes. All of them were underui/**orui_consumersalready. Cost of the additions: in the 30 days to 2026-10-26, 2 merged PRs moved one of the eight paths and no other ui path (#26120, #25833); each would have run the ui lane once more.ci.yml, the ceilingBuild & E2E UIis re-derived by the rule in the comment above Lint UI. The slowest successful run was 457 s; adding 213 s gives 670 s (11.2 min), somax(33.5, 26.2)⇒ 35, up from 25. The pin inui/scripts/__tests__/turbo-cache-save-bound.test.tsmoves with it.Prose
lint.yml: thecheck-sdui-manifeststep comment says where the regeneration now runs. The stale reference to the retired lockstep neighbour goes.scripts/check-sdui-manifest.mjsheader: "What this deliberately does NOT do" and check 3's "What is NOT forced" now name the CI step that does it.docs/releases-maintenance.md: one paragraph on the CI comparison.Widening or narrowing
This is a widening. It adds a check, and no case that the current check refuses passes now: the current check stays on, unchanged. The step goes red only when the committed manifest differs from this tree's regeneration. That is exactly a stale manifest, so nothing an author can write is refused that is not stale.
What PR B does, after this is green on
mainIt retires check 3 in-tree (the per-package digests) and
scripts/sdui-manifest.sources/. It also updates their readers:scripts/gen-sdui-manifest-node.mjs;scripts/check-changeset-no-major.mjs(L1368–1371, L4879, L4966);docs/releases-maintenance.md;cut-rc.ymlandrelease.ymlprose.After that, PRs conflict only when the manifest's bytes really change. Whichever of PR B and 2g PR 2 lands second rebases on
scripts/sdui-manifest.sources/sdui-parser.json.Verification
Head
d36dc4280, onmainff918954e. 5 files, +79 / −23, one commit. Tier H:check-governed-merges --testexits 3 for.github/workflows/ci.ymland.github/workflows/lint.ymland 0 for the other three paths.mainhere already carries feat(sdui-parser)!: one parser body in @objectstack/sdui-parser (#25712 2g PR 1) #26211's parser. Ond36dc4280,node scripts/gen-sdui-manifest-node.mjswrote byte-identical bytes: sha2561f6e1ccb925a…, 106 components,git statusclean, no record rewritten. So the new step should be green on this PR. With main moved, that run rebuilt 62 of 63 tasks locally in 7m25s; in CI,Build UI Depssupplies 36 of them.check-sdui-manifest:--self-test29 cases behave; the production run is green.ui/scripts/__tests__/turbo-cache-save-bound.test.tsandensure-chromium-ready.test.tspass 52/52, with the 35-minute pin.ci.ymlandlint.ymlboth parse (14 jobs each).build-e2e-uireadstimeout-minutes: 35, and the new step sits between "Build the @objectstack packages objectui consumes" and "Build the Console for E2E".node scripts/pm/dispatch-gates.mjs --commandsderives 79 gates. They ran on468450e19, this commit before its rebase from4f7e0414atoff918954e; nothing onmainbetween those touched the five files. 78 exited 0.check:dual-build-cjs-loadsexited 3 (prerequisite: no workspacedist), then exited 0 afterpnpm build.--ranreconciles 79 derived, 79 run, 0 NOT-MEASURED, 0 UNRUN.GITHUB_ACTIONS=true GITHUB_EVENT_NAME=push node scripts/pm/check-dispatch-gates.mjs) on468450e19: 2164 cases pass, 0 fail, EXIT 0 (1586 s).d36dc4280.🤖 Generated with Claude Code
https://claude.ai/code/session_01A6SEitNngAMugGbuJHWsDS