Skip to content

ci(release): 解堵 17.0.0-rc.2,并让空 changeset 不再吃掉一整轮发布 (#4898) - #4899

Merged
xuyushun441-sys merged 1 commit into
mainfrom
claude/ci-errors-i1t8fi
Aug 3, 2026
Merged

ci(release): 解堵 17.0.0-rc.2,并让空 changeset 不再吃掉一整轮发布 (#4898)#4899
xuyushun441-sys merged 1 commit into
mainfrom
claude/ci-errors-i1t8fi

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Closes #4898

17.0.0-rc.2 的版本号已经在 main 上(3cfd9f0),npm 上没有这个包。本该发布它的那次 Release run 30822140425 报的是 success:

Create Release Pull Request or Publish to npm ... 0s
All changesets are empty; not creating PR

changesets/action 只在零 pending changeset 时才进入 publish 分支。空 changeset 仍然计入 pending,于是「只剩空 changeset」的 main 两条路都不走 —— 不产生版本 PR,也不发布,published=false,整个 run 报绿。docker job 按 if: published == 'true' 一起 skipped,所以运行时镜像也没发,ghcr 最新仍是 17.0.0-rc.1

当时 main 上的 pending 集合正好是两个空 frontmatter 的 changeset(#4893 的和 #4896 的),任一个单独存在都足以触发

1. 解堵:删掉这两个空 changeset

空 frontmatter 的 changeset releases 为空,对任何包的 CHANGELOG 都不产生条目 —— 删掉不丢任何信息。它唯一的作用是满足 Check Changeset,而那两个 PR 几小时前就已经合并、闸门早已通过。

pending 集合清空后,下一次 main push 走 action 的正常 publish 分支,GitHub Releases、ADR-0087 D4 的 spec-changes 附件、npm、Docker 全都按原样产出。

所以本 PR 自己不带 changeset,改用 skip-changeset 标签。 如果这里再加一个空的,就会原样重建正在被移除的那个条件,并把这轮发布逼进下面那条降级路径。

2. 防复发:补一次幂等 publish + 漏发断言

在 changesets 步骤之后加一步,判据只取唯一真正要紧的事实 —— 仓库里的版本不在注册表上:

- name: Publish a release the Changesets action left behind
  id: recover-publish
  if: steps.changesets.outputs.published != 'true'

changeset publish 会跳过所有已发布的版本,所以它在正常路径上是 no-op(那时 main 的版本就是最后发布的那个),只在这条异常路径上才真正动作。它不会静默成功:补发之后版本若仍不在 npm 上,job 直接 ::error:: 退 1 —— 这正是今天缺的那个信号。

job 的 published / cli-version 两个 output 现在接受任一条 publish 路径,所以被救回来的发布仍然会发 Docker 镜像,而不是掉进同一个洞。

降级路径无法创建 GitHub Releases 和 spec-changes 附件(那些只存在于 action 自己的 publish 路径内),所以它用一条 warning 明说,而不是把这个缺口留给以后去发现。

验证

  • 两个 YAML 都能被 parser 解析;两个 job output 表达式在「action 发布」「fallback 发布」「都没发布」三种状态下取值都对。
  • 新步骤的 shell 通过 bash -n
  • 三条分支都用打桩的 npm/pnpm/git 实跑过:
    • 版本已在 npm 上 → 打印 already on npm,exit 0,不调用 publish;
    • 版本缺失 → 补发,GITHUB_OUTPUT 写入 published=true version=17.0.0-rc.2;
    • 版本缺失且补发后仍缺失 → ::error:: + exit 1。
  • packages/cli/package.json 路径核对过:@objectstack/cli @ 17.0.0-rc.2

顺带说明

同一次 run 里 hotcrm 那段 TS 报错与本问题无关,也不是没发布的原因 —— release.yml 在 pre 模式下刻意把 downstream smoke 降级为「报告但不阻塞」(#3600),该步骤 conclusion 是 success。它留下的义务是:changeset pre exit 之前必须发一个迁移过的 hotcrm 并上抬 HOTCRM_REF,否则闸门自动重新武装。

只动 CI workflow 与 changeset 文件,不涉及任何运行时代码。

🤖 Generated with Claude Code

https://claude.ai/code/session_01BbNVKv6KgPzuQ5p76nMgnf


Generated by Claude Code

…ing a release (#4898)

17.0.0-rc.2 is versioned in main (3cfd9f0) and absent from npm. The Release run
that should have published it reported success:

  Create Release Pull Request or Publish to npm ... 0s
  All changesets are empty; not creating PR

changesets/action reaches its publish branch only when there are ZERO pending
changesets. An EMPTY changeset still counts as pending, so a main carrying only
empty ones takes neither path — no version PR, no publish, published=false, and
a green run. `docker` skipped with it, so no runtime image shipped either.

Two pending changesets were on main, both empty-frontmatter: #4893's and
#4896's. Either one alone is enough. This is not an exotic state — `Check
Changeset` sanctions the empty changeset as the "this PR releases nothing"
declaration, so any docs/ci PR landing during the version-PR window produces it.

Unstick: delete both. An empty-frontmatter changeset declares no releases, so it
contributes no entry to any package's CHANGELOG — deleting it discards nothing.
Its only job was to satisfy `Check Changeset` for PRs that merged hours ago.
With the pending set empty, the next push to main takes the action's normal
publish path, which ships the GitHub Releases and the ADR-0087 D4 spec-changes
attachment along with npm and Docker.

This PR therefore adds no changeset of its own — it carries the `skip-changeset`
label instead. Adding an empty one would re-create the exact condition being
removed and force the release down the degraded fallback path below.

Prevent the silent recurrence: a recovery step after the changesets action,
gated on the only fact that matters — the version in the repo is not on the
registry. `changeset publish` skips versions already published, so it is a
no-op on the normal path (main's version IS the last released one) and a repair
on this one. It never succeeds silently: if the version is still missing after
publishing, the job fails. The job's `published` / `cli-version` outputs now
accept either publish path, so a rescued release still ships its Docker image
instead of losing it to the same hole.

The fallback cannot create GitHub Releases or the spec-changes attachment —
those live inside the action's own publish path — so it says so in a warning
rather than leaving the gap to be discovered later.

Verified: YAML parses, both job outputs resolve on each path, the step's shell
passes `bash -n`, and all three branches were exercised against stubbed
npm/pnpm/git — already-published (no-op, exit 0), missing (publishes, sets
published/version), and missing-after-publish (::error::, exit 1).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BbNVKv6KgPzuQ5p76nMgnf
@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 3, 2026 2:34pm

Request Review

@os-zhuang os-zhuang added ci/cd tooling skip-changeset PR has no user-facing published change; bypasses the changeset gate labels Aug 3, 2026 — with Claude
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation labels Aug 3, 2026
@os-zhuang os-zhuang removed the documentation Improvements or additions to documentation label Aug 3, 2026 — with Claude
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Aug 3, 2026
@xuyushun441-sys
xuyushun441-sys marked this pull request as ready for review August 3, 2026 14:37
@xuyushun441-sys
xuyushun441-sys added this pull request to the merge queue Aug 3, 2026
Merged via the queue into main with commit 89d2a4e Aug 3, 2026
29 of 30 checks passed
@xuyushun441-sys
xuyushun441-sys deleted the claude/ci-errors-i1t8fi branch August 3, 2026 14:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/cd documentation Improvements or additions to documentation size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

空 changeset 会静默卡死已 version 的发布:Release run 全绿,但 npm 和 Docker 什么都没发(17.0.0-rc.2 现在就卡着)

3 participants