Astro 仓库 main→next 合并中的 stale changeset 清理:预发布版本一致性维护实战指南
2026/9/8 23:31:00 网站建设 项目流程

Astro 仓库 main→next 合并中的 stale changeset 清理:预发布版本一致性维护实战指南

【免费下载链接】astroThe web framework for content-driven websites. ⭐️ Star to support our work!项目地址: https://gitcode.com/GitHub_Trending/as/astro

Astro 官方 Monorepo 采用main(稳定分支)与next(预发布分支)并行的发布策略,其中所有包的版本号与变更记录都由 Changesets 为主体,结合.changeset/目录下的真实配置与变更文件、merge技能的整体流水线定义,给出这套“识别 → 判定 → 移除 → 校验”的 stale changeset 清理完整流程,帮助理解并安全执行 main→next 的版本合并维护工作。

这套流程解决什么问题:预发布分支的“陈旧 changeset”问题

要理解为何需要专门的清理步骤,首先要还原 Astro Monorepo 的版本演进模型:

  • main是稳定发布分支,release 会“消费”掉一批.changeset/*.md文件,将其合并为各包的 CHANGELOG 与版本号提升;
  • next是预发布分支,处于 Changesets 的 pre-release 模式,同一分支上的发布生成的是beta/rc这类预发布版本号。

问题发生在两者合并时:如果next在某个 release 之前就已经从main分叉,那么当main被合并进next时,那些“已经被main上的 release 消费掉”的 changeset 文件,在 git 看来仍然是以新增文件(Added)形式出现的新内容。若不清理,next下一次发布 pre-release 版本时会把这些早已作为稳定版发布过的改动再次计入版本号提升,于是出现同一改动先以beta后以更低序的稳定版发布的版本倒挂。

这正是文档中给出的冲突实例:@astrojs/sitemap@3.6.1-beta.3被发布在@astrojs/sitemap@3.7.0之后。预发布版本号反而大于其对应稳定版的下一个 patch 语义,破坏了 semver 的预期排序。

开始前的前置条件与执行边界

文档明确列出两条执行前置条件,任何运行此流程的人或 Agent 都应先核对:

  1. 工作目录必须是仓库根目录,且已 checkout 在 merge 分支上。因为后续所有git diffgit rm命令都假定你在正确的分支与工作区执行。
  2. 依赖可能尚未安装——禁止运行任何依赖node_modulespnpm命令。清理 changeset 本质上是纯 git 文件操作,不应触发安装、构建或发布动作。

此外文档明确限定执行范围:不要派生子任务/子 AgentDo not spawn tasks/sub-agents),整个清理过程应当是单个执行者顺序完成的线性流程。

理解 .changeset 目录:被清理对象与不可动文件

在 Astro 仓库根目录,[.changeset/](https://link.gitcode.com/i/61df7e245fe9ef5655c242678c64c051)目录集中存放所有 changeset 文件与 Changesets 工具的运行时配置。当前仓库中可以看到:

  • .changeset/config.json—— Changesets 的全局配置;
  • 若干形如better-lines-show.mdgreat-moons-shine.mdtidy-pumas-attack.md的随机名词命名 changeset 文件(由pnpm changeset自动生成文件名);
  • .changeset/README.md—— 工具自动生成的说明文件。

关于这些文件应建立三条关键认知:

(1).changeset/config.json是发布行为的基准配置,绝不能删除。当前仓库的配置内容如下:

{ "$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json", "changelog": ["@changesets/changelog-github", { "repo": "withastro/astro" }], "commit": false, "linked": [], "access": "public", "baseBranch": "origin/main", "updateInternalDependencies": "patch", "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { "onlyUpdatePeerDependentsWhenOutOfRange": true } }

其中baseBranch: "origin/main"定义了主基准分支,changelog使用 GitHub 上withastro/astro的仓库生成 changelog。这套配置意味着稳定分支即发布基准,也是判定“某个 bump 是否已被发布”的对照来源。

(2)changeset 文件有严格的 frontmatter 格式。每个 changeset 都是一个 Markdown 文件,frontmatter 中声明受影响的包名与 semver bump 类型(patch/minor/major),正文是面向用户(而非代码评审者)的 CHANGELOG 描述。仓库中现有的真实示例:

great-moons-shine.md:

--- 'astro': patch --- Updates Astro's remaining internal warnings and errors to be written through the configured logger instead of directly to the console, when possible

tidy-pumas-attack.md:

--- '@astrojs/vercel': patch --- Updates the development image service to forward every argument it receives to Astro's Sharp service, including the new `logger` parameter

注意包名必须与对应包的package.jsonname字段完全一致(如'astro''@astrojs/vercel''@astrojs/sitemap'),这正是清理时判定“该 changeset bump 的是哪个包”的解析依据。仓库的merge技能姊妹篇 changeset/SKILL.md 进一步规定:每个修改包的 PR 都必须附带 changeset(仅examples/*改动豁免),核心astro包的major/minorbump 会被 CI 拦截、需要维护者评审——这意味着出现在next上的“新功能/破坏性变更”型 changeset 往往与主分支无关,应被保守保留。

(3).changeset/pre.json只会在 pre-release 模式下存在。它记录预发布状态(当前处于 pre 模式的版本前缀、以及 pre 模式下已登记但尚未发布的 changeset 列表)。只有当仓库当前处于 pre-release 模式时才存在;若存在,它很可能在changesets数组中引用若干 changeset 文件名,清理时需要同步确认不应再引用被移除的条目。清理时不能删除整个pre.json——它一旦缺失会破坏 pre-release 状态机。

完整清理流程:六个步骤详解

步骤 1:用 diff 识别出“相对 next 是新增”的 changeset

合并分支准备好后,第一步是找出所有相对origin/next属于新增(Added)的 changeset 文件:

# 列出 changeset 下、在 next 中尚不存在的 .md 文件 git diff --name-only --diff-filter=A origin/next -- .changeset/

--diff-filter=A把输出限定为“新增文件”,正是main合入后会把已发布 changeset 重新带进来的通道;路径过滤-- .changeset/把比较范围严格限定在 changeset 目录,避免无关文件干扰。

步骤 2:逐个核对每个新 changeset 是否“已被 main 发布”

对步骤 1 输出的每个文件,做两层检查:

  • 读文件内容,从 frontmatter 中解析出它 bump 了哪些包、是什么 bump 类型(patch/minor/major);
  • 对照origin/main上这些包当前的package.json版本,判断“文件里描述的那次 bump 是否已经被发布过了”。

判断依据是版本发布史:如果在origin/main上,该包的版本号已经推进到包含这次 bump 的程度(例如该 bump 的内容已经写进了对应包的 CHANGELOG、版本已经越过它),那么这个 changeset 就是 stale(已消费但残留),应当被清理。以文档中的冲突为例:当origin/main上的@astrojs/sitemap已是3.7.0、而其 changeset 描述的内容已在 3.7.0 中发布时,出现在next上的对应 changeset 就会把next3.6.1-beta.x序列错误地推到3.6.1-beta.3,与已发布的3.7.0产生版本倒挂——这正是必须删除的典型对象。

步骤 3:同步检查.changeset/pre.json

如果.changeset/pre.json存在,务必读取它:确认它记录的 pre-release 状态与changesets数组不会引用任何将要被移除的 changeset。被移除的 changeset 若仍被pre.json引用,后续changesets version阶段会因找不到对应文件而报错或产生悬空引用。所以“删文件”与“改 pre.json 登记表”必须配套处理。

步骤 4:删除被判定为 stale 的 changeset 文件

使用 git 跟踪的删除方式,确保删除动作被暂存、能被 merge 提交携带:

git rm .changeset/<stale-file>.md

git rm而非普通文件删除,是为了让删除操作进入索引,方便后续由编排者统一提交。

步骤 5:校验剩余 changeset 的合法性

清理完成后检查剩下的 changeset 文件是否都格式完好:frontmatter 中的包名合法、bump 类型属于patch/minor/major三者之一、正文存在。格式良好的 changeset 是后续 CI 校验和 changelog 生成的前提。

步骤 6:不要提交、不要安装依赖

最后一步是明确的工作交接边界:不要执行git commit,也不要运行pnpm install。提交、安装、构建与发布由编排者(orchestrator)统一处理——这也与前置条件中“依赖可能尚未安装”呼应,清理阶段应保持工作区只包含 changeset 的调整。

决策规则:什么时候该删,什么时候该留

stale changeset 清理最需要审慎的是判定边界。文档给出了清晰的红线:

  • 只删“已被发布”的 changeset:唯一可靠的删除依据是“它在main上的那次 bump 已经发布过”。任何缺少这一证据的 changeset 都不能凭猜测删除。
  • 绝不删除next专属 changeset:那些描述next上正在开发的 major 变更或新特性的 changeset,正是预发布版本存在的意义,必须原样保留。
  • 绝不删除.changeset/config.json:它是 Changesets 的全局配置基准(含baseBranch: "origin/main"等),删除会导致整个发布配置失效。
  • 绝不删除.changeset/pre.json:它维护 pre-release 模式状态,删除会破坏next的预发布版本推进机制。
  • 不确定时保守保留:若无法判断一个 changeset 是否 stale,宁可保留,留给人工评审者后续裁决。过度删除比少量残留风险更高——残留至多造成一次多余的版本号提升,而误删则可能丢失真实的变更记录与 CHANGELOG 内容。

这一“宁可保守”的原则在仓库的 merge 技能评测用例 中被固化为验收标准:合成场景中,仅有明确发布证据的 sitemap changeset 被移除并同步从pre.jsonchangesets数组中剔除,而next专属的 major 变更与“发布状态未被证明”的 node changeset 都被保留。

执行输出与校验闭环

流程结束时,需要返回被移除的 changeset 文件清单作为执行结果。这份清单既是 merge 分支改动的摘要,也是后续人工复核与pre.json同步的核对依据。

整个清理是仓库merge技能流水线的一个环节。父技能 merge/SKILL.md 把 main→next 合并拆成三个阶段依次执行:resolve-conflicts.md(解决 git 冲突)→ 本文的 clean-changesets.md(移除 stale changeset)→ fix-ci.md(修复 CI 暴露的构建、类型与测试问题)。三者按step参数分派,共享“merge 分支处于仓库根目录、依赖可能未安装、最终由编排者提交/安装”的统一上下文;其中 resolve-conflicts 阶段会“先对 conflict 双方均接受”保留 changeset,把判定与清理职责专门交给 clean-changesets,避免冲突解决与发布语义判断互相干扰。理解这一点,就能把本文的六个步骤放到完整的合并工作流中看待:它是保证next预发布版本序列不被主分支历史污染、杜绝beta晚于稳定版发布的版本倒挂现象的最后一道关卡。

【免费下载链接】astroThe web framework for content-driven websites. ⭐️ Star to support our work!项目地址: https://gitcode.com/GitHub_Trending/as/astro

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询