Skip to content

chore(release): exit Changesets pre mode (next), so the next version pass renders objectui's 18.0.0 GA - #13111

Draft
objectstack-fleet[bot] wants to merge 2 commits into
mainfrom
claude/issue-13108-changesets-pre-exit
Draft

objectstack-fleet[bot] wants to merge 2 commits into
mainfrom
claude/issue-13108-changesets-pre-exit

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #13108

Clause-②: no

Exits Changesets pre mode on main, on the maintainer's order 「objectui 退出预发布模式」. After this lands, the next version pass renders the GA: the 40-member fixed group goes from 17.7.0 to 18.0.0, not 18.0.0-next.0. Draft, for the maintainer to merge, because the merge sets when the version PR renders the GA.

⛔ No release act. No changeset version output is committed. Nothing was published or tagged, no workflow was dispatched, and neither release PR #11600 nor changeset-release/main was touched. The dry-run below ran in a scratch clone whose push URL is an invalid path.

Head 9e3c1a1408 = base df943a2a1a (origin/main at worktree creation, and still origin/main when this opened) plus two commits.

The change

  1. .changeset/pre.json, written by pnpm changeset pre exit (@changesets/cli 3.0.1) and committed as the tool wrote it (fda18fcdf9):

    content
    before { "mode": "pre", "tag": "next" }
    after { "mode": "exit", "tag": "next" }

    Same 2-space JSON with a trailing newline. Under CLI 3 the file holds only mode and tag, before and after; nothing else is expected or written.

  2. One test assertion in scripts/__tests__/sync-quick-reference-release.test.ts (9e3c1a1408). The first dry-run of the release lane on the exited tree went red on exactly one test, and the control on df943a2a1a is green, so the exit is what reddens it:

    • The test "rewrites the Version row when the fixed group moves" bumps the group to 99.9.9 and asserted that the doc no longer contains the old version as a raw substring.

    • With the group at 18.0.0, that string is a prefix of the Spec and Client rows' ^18.0.0-next.1. So a correct rewrite failed.

    • The assertion now reads the doc's version literals with the script's own VERSION_LITERAL and normalize, the tokens the gate (quick-reference-current-release-4143.test.ts) compares, and checks that none is the old version. That gate's header already states the rule: "Equality on extracted tokens, never toContain over the raw row".

    • It keeps its teeth. A probe of the script's own exports over QUICK_REFERENCE.md, at group versions 17.7.0, 18.0.0 and 18.0.0-next.0:

      group version correct rewrite: new / old assertion Version row left as is: new / old
      17.7.0 green / green RED / RED
      18.0.0 green / RED RED / RED
      18.0.0-next.0 green / green RED / RED
    • Why here and not in prose. The card expected the red, if any, to be release text that states a prerelease status, as on objectstack. objectui has none: it has no release pages, and a grep of the docs, READMEs and QUICK_REFERENCE.md finds no sentence that states objectui's own prerelease or "no GA" status. The only red is this test, which the GA render makes false. It is not a gate: no gate's scope or verdict changes, and it adds no check.

Dry-run of the version step (scratch clone, never pushed)

Setup:

  • A blobless clone of this branch from GitHub (--filter=blob:none, full history, --is-shallow-repository false, 12164 commits), so @changesets/git resolves every changeset's add-commit without the shallow-clone deepen loop.
  • pnpm run setup: the pin build copied from the machine store, then a frozen install. node_modules is a real directory, not a symlink.
  • The three steps Render the post-version tree, Validate the post-version tree and Restore the pre-version tree were extracted verbatim from .github/workflows/changeset-release.yml with a YAML parser. The workflow blob is 533cf01fe5 in the clone and on main, and the extracted bodies are byte-identical across the three legs. They ran under bash --noprofile --norc -eo pipefail with GITHUB_OUTPUT, GITHUB_STEP_SUMMARY and GITHUB_SHA pointed at scratch files, each heavy step under os-verify-lock.sh.
  • The job's earlier Build packages step was not replayed; see NOT MEASURED.
leg Render rendered version Validate Restore
head 9e3c1a1408 0 Version: 17.7.0 → 18.0.0 0: quick-reference check, control bytes, then Test Files 190 passed, 2 skipped (192) 0: "Pre-version tree restored: 857 pending changeset(s), working tree clean."
first commit fda18fcdf9 (exit only) 0 17.7.0 → 18.0.0 1: 1 failed, 189 passed, 2 skipped, the one test above 0, same line
control: base df943a2a1a (still mode: "pre") 0 17.7.0 → 18.0.0-next.0 0: 190 passed, 2 skipped 0, same line

Readings on the head's post-version tree:

  • Fixed group: 40 of 40 members at 18.0.0. One of them, object-ui, is private, so 39 are publishable. This was read from the manifests. changeset publish-plan was not run.
  • Changesets consumed: 857, which is every .changeset/*.md except README.md (pending_before=857). .changeset/ afterwards holds only README.md and config.json.
  • .changeset/pre.json is deleted by the pass. On the base leg it survives as mode: "pre" and the 857 move to .changeset/pre/.
  • Paths moved: 939. That is 858 deletions (857 changesets plus pre.json), 40 package.json files whose only changed line is "version", 40 CHANGELOG.md files that each gain a ## 18.0.0 section, and QUICK_REFERENCE.md, whose Version row now reads 18.0.0.
  • No dependency range moved: zero @objectstack/* lines change in the 40 package.json diffs.
  • On the post-version tree: check-changeset-no-major exits 0 ("No changeset declares a major bump.") and check-changeset-fixed exits 0.
  • The publish dist-tag after the GA version commit would be latest. getReleaseTag (@changesets/cli 3.0.1, getPublishPlan.mjs) returns preState.tag only while a pre state exists, and the pass deletes pre.json. This is a reading of the code; nothing was published.

PR #12401's two gate edits, judged on the exited tree

edit keyed on pre mode? verdict
scripts/check-changeset-no-major.mjs: the computed admission of the one synchronized major (group's current major + 1 = the @objectstack/spec range's major), with OBJECTUI_ALLOW_MAJOR retired No. The script reads no pre.json and no mode. Its only pre-mode clause is that it does not read .changeset/pre/, and that was its behaviour before PR #12401 too (that PR's body says so). Kept. It is the maintainer's GA-time version-alignment rule (ruling on objectui#12030), and the next objectstack major needs it again. On the exited pre-version tree, pnpm changeset:check still admits the sync major and exits 0. On the 18.0.0 tree, a probe "@object-ui/core": major gives exit 1, "carries the group from 18 to 19, but its @objectstack/spec range names 18". So it re-arms, and refuses every other major.
scripts/check-spec-range-floors.mjs: reads a prerelease lower bound (^18.0.0-next.N) as a floor No. It reads dependency ranges and no changeset state: no pre.json, and no mode. The ranges are objectstack's prerelease line, which @objectstack/* 18 sets (its header says so). objectui's own mode does not set them. Kept. The exit does not move a range, and neither does the GA render (zero @objectstack lines in the version diff). At publish, objectstack-floor.mjs raises the ranges to the computed floor, and that floor is itself a prerelease whenever the earliest published spec release that contains the pin is one. Its pins, check-spec-range-floors.test.ts, pass on the exited tree and inside the post-version scripts/__tests__ run. The live gate was not run here (NOT MEASURED below).

Neither edit is reversed. No gate is weakened or added.

The dispatch's mechanism hypotheses, measured

  1. Holds, with the count corrected. The version pass renders the sync major onto 18.0.0 and consumes every pending changeset: 857. The card's 860 counts every entry under .changeset/, including README.md, config.json and pre.json. pre.json itself is deleted by the pass.
  2. Falsified. Neither gate edit's condition is pre mode (table above).
  3. Holds. The sync writes 18.0.0 into the Version row, and nothing in objectui's docs states objectui's own prerelease status. The Spec and Client rows keep ^18.0.0-next.1 because those rows are the declared @objectstack/* ranges, derived from the manifests, and that is correct. They move when a range moves, not when objectui exits pre mode.

Order note (for the maintainer; not a code change)

pnpm changeset:publish runs objectstack-floor.mjs, then check-published-dist-tooling.mjs, then check-spec-range-floors.mjs, then changeset publish.

  • Today the first step refuses. node scripts/objectstack-floor.mjs --dry-run at the pin f4755a68a7 exits 2: "No published @objectstack/spec release contains the pin … the newest published release is 18.0.0-next.5. Nothing is published until objectstack releases a commit that contains the pin." Exit 2 is by design, and it writes nothing.
  • The same answer with git, from a full-history objectstack checkout: merge-base --is-ancestor with the pin and the @objectstack/spec@18.0.0-next.5 tag commit 820fd5aef0 gives exit 1. The control leg, with the 18.0.0-next.3 tag commit 2c9bf9430a, which is older than the pin, gives exit 0. The pin (2026-10-19 10:57Z) comes after the next.5 version commit (08:58Z the same day).
  • So objectui 18.0.0 cannot publish before objectstack publishes a spec release whose tag contains the pin. In practice that release is objectstack's 18.0.0 GA (chore: version packages objectstack#24524). The steps do not read npm's latest tag. The floor is the earliest published version, by semver precedence, whose tag contains the pin, and the floor gate fetches that exact version.
    • If objectstack 18.0.0 is the first release that contains the pin, the floor is 18.0.0, and objectui's published ranges become ^18.0.0.
    • If an 18.0.0-next.6 that contains the pin were published first, the floor would be that prerelease, even after 18.0.0 GA. objectui 18.0.0 would then ship ^18.0.0-next.6 ranges. Those resolve to 18.0.0 once it exists, but they name a prerelease floor.
  • Consequence for the release order: merge objectstack's GA and let it publish first. Then refresh objectui's version PR, check that it renders 18.0.0, and merge it. If the objectui version PR is merged first, its publish lane goes red at the floor step, and nothing is published.
  • Merging this PR publishes nothing. The lane's guard asks whether the commit's anchor version is on npm, and @object-ui/core@17.7.0 is (dist-tags.latest = 17.7.0).

Changeset and labels

No changeset. node scripts/check-changeset-presence.mjs: "No source or published contract of a released package changed in this range, so no changeset is owed." This matches objectui's precedent for tooling-only PRs. No label is written; objectui's path labels come from labeler.yml.

Gates (local, at 9e3c1a1408, exit codes captured before any pipe)

  • pnpm changeset:check 0 (both halves; the no-major half prints "Every major is the synchronized one").
  • pnpm check:changeset-claims 0, pnpm check:pending-changeset-literals 0.
  • node scripts/check-changeset-presence.mjs 0, node scripts/check-changeset-overwrite.mjs 0.
  • pnpm check:new-line-citations 0 (0 new), pnpm check:control-bytes 0, pnpm check:test-path-roots 0, pnpm check:pre-install-import-graph 0, pnpm quick-reference:check 0.
  • node scripts/check-governed-queue-guard.mjs --test on both paths: "NOT GOVERNED".
  • pnpm run type-check:scripts 0. tsc --listFilesOnly lists the changed test file.
  • eslint on the changed test file: 0.
  • pnpm exec vitest run on sync-quick-reference-release, quick-reference-current-release-4143, check-changeset-no-major, check-spec-range-floors, check-changeset-presence and doc-version-claims: 6 files, 169 tests passed.
  • The whole scripts/__tests__ directory ran green on the post-version tree inside Validate (table above).
  • NOT MEASURED:
    • the workflow's Build packages step before Validate, because Validate's three commands read sources, manifests and docs, and all three are green without it;
    • the live pnpm check:spec-floors, because it needs a build of the floored packages and its input ranges are byte-identical across the exit and the render;
    • changesets/action itself, which is a GitHub Action;
    • the full pnpm test, which is CI's.
  • CI check-runs: see the report comment on the card.

Acceptance notes

  • Do not merge chore: release packages (next) #11600 as it stands. It still renders 18.0.0-next.0 from a pre-mode tree. After this merges, dispatch the refresh_version_pr run (or wait for the six-hourly one), which re-renders it at 18.0.0. If the stale render were merged after this PR instead, it would version 18.0.0-next.0 with pre.json at mode: "exit". Under CLI 3 that tree still publishes to the next tag, and the next pass renders the GA. That is a reading of the code, not a measurement, and the floor step would refuse its publish today anyway.
  • The 18.0.0 CHANGELOG sections are large. The 40 CHANGELOG.md files gain 22,251 lines in total, measured on the head's render.
  • File surface. The claim's declared surface named .changeset/pre.json, PR release(v18): objectui's first 18.x release — the sync major, Changesets pre mode on next, and the two gate edits (objectui#12334) #12401's pre-mode gate edits and release prose. The test assertion in item 2 is outside it. It is here because it is the only thing the GA render reddens, and the dispatch allows a change at the real producer when it is named here.

Wanted, mapped

  • pre.json written by pnpm changeset pre exit, in the repo's shape: done (The change, item 1).
  • Dry-run: the fixed group renders 18.0.0, and every gate of the version step and its validation stays green, each named: done. Render, Validate (quick-reference check, control bytes, scripts/__tests__) and Restore all exit 0 on the head, and the base control renders 18.0.0-next.0.
  • PR release(v18): objectui's first 18.x release — the sync major, Changesets pre mode on next, and the two gate edits (objectui#12334) #12401's two gate edits, judged one by one: both are kept, with the reasons (table).
  • Release text that states a prerelease or "no GA" status: objectui has none. The one red is a test assertion, changed here (item 2).
  • Draft, and no release act: held.

维护者速读(草稿)

改了什么:objectui 退出 Changesets 预发布模式。.changeset/pre.json 由 pnpm changeset pre exit 写出,模式从 pre 改为 exit。另外改了一条工具测试的断言,原来它按子串比较版本号,在 18.0.0 下会误报。没有改任何门禁、工作流或发布包源码,也没有 changeset。

为什么改:执行您的指令「objectui 退出预发布模式」。在临时克隆里原样重放了发版工作流的版本步骤。退出后,下一次版本 PR 会把 40 个固定组包从 17.7.0 定为 18.0.0,不再是 18.0.0-next.0,并消费全部 857 条 changeset。只退出模式时,校验步骤有一条测试变红:QUICK_REFERENCE 里 Spec 行写着 ^18.0.0-next.1,包含子串 18.0.0。断言改成按完整版本号比较后,渲染、校验、还原三步全部为 0。对照的 base 仍渲染 18.0.0-next.0。

风险与代价(含回滚):

  • 本 PR 合并本身不发布任何东西,npm 上已有 17.7.0。
  • 发布顺序有硬约束:objectui 发版的第一步按 .objectstack-sha 计算 @objectstack 下限。今天它退出 2,原因是 npm 上还没有任何一个 objectstack 版本包含这个 pin(最新是 18.0.0-next.5)。所以 objectstack 18.0.0 必须先发布,objectui 18.0.0 才发得出去。顺序反了,发布这一步会变红,但什么都不会发出去。
  • 现在的版本 PR chore: release packages (next) #11600 还是 18.0.0-next.0,不要直接合并它。本 PR 合并后先刷新一次。
  • 回滚:版本 PR 合并之前直接 revert 本 PR,恢复 mode: "pre" 即可。GA 发布到 npm 之后无法回滚。

席位意见:

你要做的:

  1. 决定 GA 时机,合并本 PR。
  2. 等 objectstack 18.0.0 发布到 npm(chore: version packages objectstack#24524)。
  3. 触发 objectui 版本 PR 刷新,确认它渲染为 18.0.0,再合并版本 PR。

Generated by Claude Code

…nders 18.0.0

`.changeset/pre.json` as `pnpm changeset pre exit` (`@changesets/cli` 3.0.1)
wrote it: `mode` goes from `pre` to `exit`, `tag` stays `next`, same
2-space JSON with a trailing newline. No `changeset version` output is
committed.

Claude-Session: https://claude.ai/code/session_01FM29ZqLTrnPNXxijioZwMp
Co-authored-by: Claude <noreply@anthropic.com>
…, so the 18.0.0 render validates

`sync-quick-reference-release.test.ts` asserted the bumped doc does not
contain the old version as a raw substring. With the fixed group at
`18.0.0` that string is a prefix of the Spec and Client rows'
`^18.0.0-next.1`, so the release lane's `pnpm test scripts/__tests__`
went red on a correct rewrite of the GA render. The assertion now reads
the doc's version literals with the shared `VERSION_LITERAL` and
`normalize`, the tokens the gate compares, and still fails when the
Version row keeps its old literal.

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

Copy link
Copy Markdown
Contributor Author

维护者速读

改了什么:只改两个文件。

  • .changeset/pre.json 从 mode: pre 改成 mode: exit,由 pnpm changeset pre exit 写出。
  • scripts/__tests__/sync-quick-reference-release.test.ts 里一条断言原来是原始子串比较。整组升到 18.0.0 后,18.0.0 恰好是 ^18.0.0-next.1 的前缀,这条断言就会误报失败。现在改成按完整版本号比较,测试并没有放松。

为什么改:你下的指令「objectui 退出预发布模式」。objectui 现在的发版 PR #11600 渲染的是 18.0.0-next.0,objectui 的 18.x 一个版本都还没发布过。

实测(开发在临时副本里原样重放了发版工作流的 Render / Validate / Restore):

风险与代价(含回滚):

  • 合入本 PR 本身不会发布任何东西。
  • 发布顺序(硬约束):objectui 发布时,objectstack-floor.mjs 要求 npm 上已经有一个包含固定版本的 @objectstack/spec 正式发布。目前 npm 上最新的是 18.0.0-next.5,还不包含。所以必须先发 objectstack 18.0.0(#24524),objectui 18.0.0 才能发。
  • chore: release packages (next) #11600 不要原样合:本 PR 合入后,要先让 chore: release packages (next) #11600 刷新一次(等 6 小时一次的定时运行,或手动 refresh_version_pr),它才会变成 18.0.0。原样合入会把 next.0 发到 next 标签上,不过 floor 检查目前也会拦下来。
  • 回滚:revert 即可。

席位意见:建议在 objectstack 18.0.0 发布之前或同时合入本 PR,然后刷新 #11600,确认渲染出 18.0.0,再按顺序先发 objectstack、后发 objectui。

你要做的:

  1. 合入本 PR。
  2. 刷新 chore: release packages (next) #11600。
  3. 发版时先 objectstack #24524,后 objectui chore: release packages (next) #11600。

席位核对

ACCEPT · objectui domain:devx seat 1 (#5748) · os-warren · session_01FM29ZqLTrnPNXxijioZwMp · 2026-10-20T02:43Z · head 9e3c1a1408 · card #13108 (claim 6281363328, file-surface addendum 6282059630)

  • Form.
    • Draft, base main, first line Fixes #13108, assignee os-warren.
    • Two files, +8 / −2.
    • node scripts/pm/check-governed-merges.mjs --pr objectstack-ai/objectui#13111 → NOT governed.
    • git merge-tree against objectui main df943a2a1a is clean.
    • The card keeps it draft for the maintainer's merge.
  • The diff, read.
    • .changeset/pre.json: "mode": "pre" → "mode": "exit", in the same two-key shape.
    • The test's not.toContain(anchors.version) becomes [...result.doc.matchAll(VERSION_LITERAL)].map(normalize) with not.toContain. These are the script's own exports and the 4143 gate's stated rule.
  • Dry-run (the dev's, verbatim steps of changeset-release.yml, blob 533cf01fe5).
    • At head: Render exit 0 (17.7.0 → 18.0.0, 857 consumed, 939 paths), Validate exit 0 (scripts/__tests__ 5708 passed), Restore exit 0 and clean.
    • At the exit-only commit: Validate exit 1, on exactly the test this PR fixes.
    • At BASE: renders 18.0.0-next.0.
  • PR release(v18): objectui's first 18.x release — the sync major, Changesets pre mode on next, and the two gate edits (objectui#12334) #12401's two gate edits. Neither is keyed on pre mode, so both are kept.
    • check-changeset-no-major admits the sync major and re-arms on the 18.0.0 tree (a probe major exits 1).
    • check-spec-range-floors reads the @objectstack ranges only.
  • Order note (for the maintainer, not a gate). objectstack-floor.mjs --dry-run exits 2: "No published @objectstack/spec release contains the pin … the newest published release is 18.0.0-next.5". objectui 18.0.0 cannot publish before objectstack publishes a spec release whose tag contains the pin. In practice that is objectstack 18.0.0, chore: version packages objectstack#24524. The step reads npm versions and tags, not the latest dist-tag.
  • Gates.
    • The dev's local battery, all exit 0: changeset:check, check:changeset-claims, check:pending-changeset-literals, check-changeset-presence, check-changeset-overwrite, check:new-line-citations, check:control-bytes, quick-reference:check, type-check:scripts, and eslint on the test.
    • Check-runs at 9e3c1a1408: 35, all completed: 32 success, 3 skipped.
  • Carried.
    • Release PR chore: release packages (next) #11600 must be refreshed after this merges, not merged as it stands.
    • The floor sits at the earliest published spec version containing the pin. A published 18.0.0-next.6 would floor objectui's ranges there. This is by design.

⛔ Not readied or queued by this seat: the maintainer merges it.


Generated by Claude Code

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chore(release): exit Changesets pre mode (next), so the next chore: release packages PR renders objectui's 18.0.0 GA

2 participants