Skip to content

Commit b65fe91

Browse files
claude[bot]zhuangjianguoclaude
authored
fix(release): key the publish lane on npm presence, not on pending changesets (#5442) (#5774)
* fix(release): key the publish lane on npm presence, not on pending changesets (#5442) The publish half of `changeset-release.yml` asked "are changesets pending?" while being read as if it asked "did this version ship?". The two come apart on every release: the version PR is cut from `main` at T and merged at T+n, `main` takes ~18 merges a working day, and the merge does not remove the changesets that landed in between. Those belong to the next version — but keyed on them, the version this commit just bumped to is skipped and the next version PR bumps past it. Measured on bc21c70: 16 of the 90 versions `packages/core/CHANGELOG.md` declares never reached npm, and the repo says 17.6.0 where `dist-tags.latest` says 17.5.0. The `lane` job now also answers "is the declared version already on npm?" from the same sparse checkout, and the release job's push half turns on that instead. It is cheaper as well as more correct: an ordinary landing does not move the manifest version, so it skips the expensive job, where the old predicate ran it in full on every landing that happened to find `.changeset/` empty. `changesets/action@v1` picks its branch from repository state, so the publish lane clears pending changesets from the runner's working tree before invoking it — never committed, never pushed. And it ends with a loud check: the defect was a green run that published nothing, so the lane now reads the registry back and fails if the version it exists to ship is still absent. The refresh lane is untouched and still denied publishing twice over: no `publish:` input, no npm credentials. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0124Qg8rLvpXnQDwCmpKUmaJ * docs(release): write the `changesets/action@v1` pin's rationale beside the pin (#5442) ⛔ Comments only. This commit is a NO-OP to the workflow's execution: the pinned version, every input, every `if:` and every step body are byte-identical, and `yaml.safe_load` of the file before and after parses to structurally identical objects. Verified mechanically, not by eye. Dependabot proposed changesets/action v1 -> v2 in both repositories and it was declined in both — objectstack#9208 (closed unmerged 2026-08-19) and objectui#4945 (closed unmerged 2026-08-23). objectstack recorded the reasoning in its own repo (objectstack#9916); objectui had no equivalent, and #5442 makes that urgent: before it the pin rested on one v1 property, after it on two. The block states why v1 is pinned (safety properties asserted against v1's source, not a version preference), the two properties an upgrade must re-verify — the `!hasChangesets && hasPublishScript -> runPublish` dispatch table, and that `runPublish` never commits and never pushes a branch — and the five v2 changes readable from its CHANGELOG that would break this file. The second property is the sharp one: it is what makes the clear step's runner-local deletion safe, and v2's #692 moves pushes to the GitHub API by default, which is a different code path than the one that verification covers. It also records the plausible wrong answer explicitly: the Changesets CLI generation is NOT what pins us. v2's #699 directs CLI v2 users to @v1, and this repository is on CLI v3 (`^3.0.0`, lockfile 3.0.1). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0124Qg8rLvpXnQDwCmpKUmaJ --------- Co-authored-by: os-zhuang <zhuangjianguo@steedos.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
1 parent 13f36db commit b65fe91

3 files changed

Lines changed: 467 additions & 32 deletions

File tree

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
---
3+
4+
CI only — this publishes nothing, declared explicitly with an empty frontmatter rather
5+
than left undeclared.
6+
7+
`.github/workflows/changeset-release.yml` keys its publish lane on **"is the version this
8+
commit declares already on npm?"** instead of on **"are changesets pending?"**
9+
(objectui#5442, maintainer ruling 2026-08-22, Option B).
10+
11+
The two predicates read as interchangeable and come apart exactly where it costs a
12+
release. The version PR is cut from `main` at T and merged at T+n; `main` takes ~18
13+
merges a working day and the merge does not remove the changesets that landed in
14+
between. Those belong to the *next* version, but keyed on them the version this commit
15+
just bumped to is skipped, and the next version PR bumps straight past it. Measured on
16+
`bc21c704b`: of the 90 versions `packages/core/CHANGELOG.md` declares, 16 never reached
17+
npm, and the repository said `17.6.0` while `dist-tags.latest` said `17.5.0`.
18+
19+
The npm predicate is also cheaper than the one it replaces rather than a trade against
20+
it: an ordinary landing does not move the manifest version, so it answers "already
21+
published" and the expensive job is skipped.
22+
23+
Alongside it, a **loud check**. The defect was never a red run — run 3370 on `cfeb378b5`
24+
completed `success` having published nothing — so the publish lane now reads the registry
25+
back and fails if the version it exists to ship is still absent. A repo/npm divergence is
26+
a failing run, not something an audit finds 16 versions later.
27+
28+
The refresh lane is untouched and still cannot publish: no `publish:` input and no npm
29+
credentials in its `env:`, the double denial that keeps a scheduled tick from releasing
30+
something nobody merged.

0 commit comments

Comments
 (0)