ci(release): catch missing stable npm tags without failing in-flight publishes#6118
Conversation
v1.17.5 shipped as binaries and Homebrew while the npm `latest` dist-tag still pointed at 0.53.2 (esengine#5822) — every `npm update -g` / `pnpm update -g` user was silently downgraded to a months-old version. The npm line is triggered by its own tag namespace (npm-vX.Y.Z), and the stable npm tag was simply never pushed: 1.0.0 through 1.17.5 all went to npm as -rc.1 prereleases under `next`. release-npm.yml's verify step (added for esengine#5822) only guards runs that happen; nothing caught the run that DIDN'T. Add a freshness gate to the stable CLI release: after the public smoke, compare `npm view reasonix dist-tags.latest` against the version being released (sort -V). A stale `latest` fails the release with the exact remediation (push the npm-vX.Y.Z tag, or `npm dist-tag add` for an already-published version). Prereleases skip — npm latest does not move on prereleases. A `latest` NEWER than the tag passes, so re-releasing an older CLI tag is not blocked.
The migration guide and release runbook still documented the retired "latest stays pinned to 0.x, v2 lives under @next" policy — the exact policy that caused esengine#5822. Update both to the current reality: - MIGRATING.md: bare `npm i -g reasonix` installs the current 1.x stable; @next is the rc channel; 0.x stays installable by pinning [email protected]. - RELEASING.md: channels table shows latest = current 1.x stable with next/canary as pre-release buffers; the stable-ship step notes the npm-v* tag moves `latest` automatically and must not be skipped (release.yml now fails when npm latest lags); drop the manual "promote to default install" step — promotion is automatic.
|
追加 docs 同步(8b6fa8c):MIGRATING.md 和 RELEASING.md 仍在描述已退役的「latest 钉在 0.x、v2 走 @next」策略——正是造成 #5822 的那份文档。已更新为现状:裸 |
Review catch: the freshness check raced normal releases. The runbook pushes v*/npm-v*/desktop-v* together, the two workflows wait on the release environment independently, and npm dist-tags propagate asynchronously — so a single read of dist-tags.latest could fail the CLI release while the npm publish was merely awaiting approval or propagating, telling the operator to push a tag that was already pushed. Split the check into the two states the review named: - npm-v<version> tag missing (git ls-remote) -> hard fail. This is the esengine#5822 gap: nobody released to npm at all. - tag pushed but latest lagging -> poll 6x10s (matching release-npm's own verify cadence), then WARN and pass: the publish may still be awaiting its environment approval, and release-npm.yml's verify step owns asserting the dist-tag lands. RELEASING.md wording updated to match (fails on missing tag; pending publish only warns).
|
Valid P1 — fixed in d23d347. The race is real: the runbook pushes all three tags together, Reworked into the two states the review named, with different responses:
Three-state logic verified against the live registry: missing tag ( |
Summary
#5822 的流程性根因修复。排查结论:
latest卡在 0.53.2 的直接原因:1.0.0 到 1.17.5 从未发过一个稳定版 npm tag——所有npm-v*tag 全是-rc.1,按 build.mjs 的规则发到next。latest不是"没被 promote",是稳定版 npm 发布这一步在发版流程里整个缺失。立即止血(已执行):推了
npm-v1.17.5tag(指向与v1.17.5相同的 commit221a764),release-npm.yml 走 build.mjs 的稳定版路径,已发布 1.17.5 并把latest从 0.53.2 移过去;workflow 自带的 verify 步骤已断言 tag 落位。流程防线(本 PR):在稳定版 CLI 发布(release.yml,
v*非预发布)末尾加 npm 渠道守门:npm-v<version>tag 是否存在;不存在时 hard fail,并给出补救命令。这覆盖 [Bug]: latest dist-tag is stuck at 0.53.2 — pnpm update -g / npm update -g downgrades users to a months-old version #5822 的真正缺口:稳定版 npm tag 根本没推,release-npm.yml 的 verify run 不会发生。npm-v<version>tag 已推,但 npmlatest仍低于本次版本,则短轮询后只 warning 放行。这个状态可能只是 npm workflow 仍在等待releaseenvironment 审批、发布中,或 registry dist-tag 尚未传播;最终落位由 release-npm.yml 自己的 verify step 断言。latest等于或高于本次 tag 则通过。Verification
npm view reasonix dist-tags已显示latest: 1.17.5;止血发布完成。Cache impact
Cache-impact: none - release workflow only; no runtime code.
Cache-guard: not applicable.
System-prompt-review: N/A
Fixes #5822.