使用 Changesets 简化发布工作流
发布 npm 包本不应该需要自定义脚本、手动版本号更新,或者记住自上次发布以来哪些包发生了变化。然而,许多团队仍在拼凑脆弱的发布流程,这些流程往往在最糟糕的时候出问题。
Changesets 通过在贡献时捕获发布意图,然后自动化其余部分来解决这个问题。本文介绍如何构建现代化的 Changesets 发布工作流——包括 npm 可信发布、使用 Changesets 进行 monorepo 版本管理,以及 GitHub Actions 包发布——而无需承担维护负担。
核心要点
- Changesets 通过 markdown 文件在贡献时捕获发布意图,这些文件指定受影响的包和语义化版本升级类型
- 使用 OIDC 令牌的 npm 可信发布消除了长期凭证,并为您的包添加了加密来源证明
- 通过
linked、fixed和updateInternalDependencies等配置选项,monorepo 版本管理变得可控 - 常见的 CI 陷阱包括权限问题、PR 自动化冲突和遗忘的 changesets
Changesets 核心发布工作流
工作流遵循三个阶段:
- 贡献者添加 changeset 文件,描述发生了什么变化以及变化的重要程度(patch、minor、major)
- CI 创建版本管理 PR,将所有 changesets 聚合为版本升级和变更日志条目
- 合并 PR 触发发布到 npm,并提供适当的来源证明
每个 changeset 都是 .changeset/ 中的一个 markdown 文件,包含指定受影响包和语义化版本升级类型的前置元数据,以及人类可读的摘要。当存在多个 changesets 时,Changesets 会计算每个包所需的最高版本升级——两个 minor 变更不会变成两次 minor 升级。
对于 monorepos,这一点尤为重要。当一个 workspace 包依赖于另一个正在发布的包时,Changesets 会自动处理内部依赖更新。
GitHub Actions 包发布:现代化方法
大多数教程展示的工作流使用 NPM_TOKEN secrets。这种方法有效,但存在安全风险——长期令牌可能泄露,需要手动轮换。
使用 OIDC 令牌的 npm 可信发布现在是首选方法。您的 GitHub Actions 工作流不再存储凭证,而是在发布步骤期间直接从 npm 请求短期令牌。该令牌仅在该作业期间存在,无法被提取或重用。
启用此功能的步骤:
- 在 npm 的包设置中将您的 npm 包链接到 GitHub 仓库
- 使用
id-token: write权限配置您的工作流 - 确保启用来源证明(npm 可以为可信发布者自动生成,或在较新的 CLI 上通过
--provenance标志)
npm 来源证明添加了加密证明,证明该包是从您仓库中的特定提交构建的。用户可以准确验证哪些源代码生成了已发布的制品。
**需要了解的当前限制:**npm 可信发布需要公共仓库。私有仓库仍需使用传统的 NPM_TOKEN 方法。此外,官方 changesets/action 对 OIDC 的支持仍在演进——请查看最新文档了解当前的集成模式。
Discover how at OpenReplay.com.
使用 Changesets 进行 Monorepo 版本管理
Changesets 从一开始就是为 monorepos 设计的。.changeset/config.json 中的关键配置选项控制多包行为:
linked:将应始终共享相同版本号的包分组fixed:类似于 linked,但即使只有一个包发生变化,所有包也会一起升级updateInternalDependencies:控制当依赖项更新时,依赖方是否获得 patch 升级
当贡献者在 monorepo 中运行 changeset CLI 时,他们会选择其变更影响哪些包。然后版本管理 PR 会准确显示哪些包将发布以及发布什么版本。
常见 CI 陷阱
权限问题导致大多数工作流失败。GitHub 令牌需要写入权限才能创建 PR 和推送标签。对于 npm 发布,请确保您的令牌(或 OIDC 配置)具有发布到您作用域内所有包的权限。
PR 自动化冲突发生在分支保护规则阻止机器人推送版本提交时。要么允许 GitHub Actions 机器人绕过保护,要么使用具有适当权限的专用机器人账户。
多包发布顺序在包相互依赖时很重要。Changesets 会自动处理这个问题,但发布过程中的网络故障可能会使您的 monorepo 处于不一致状态。changesets/action 包含重试逻辑,但了解这种故障模式有助于恢复。
遗忘的 changesets 是贡献者最常见的错误。Changeset bot 会在缺少 changesets 的 PR 上发表评论,但您也可以添加 CI 检查,在需要但缺少 changesets 时失败。
构建您的当前工作流
大多数团队在每次推送到 main 分支时运行 Changesets action。当存在未发布的 changesets 时,该 action 会打开或更新”Version Packages”PR,或在版本 PR 合并时发布包。
这创建了一个自然的发布节奏:整周合并功能,然后在准备发布时合并版本 PR。无需手动编辑版本,无需忘记更新变更日志,无需发布错误的包。
结论
配置良好的 Changesets 发布工作流消除了包发布的认知开销。贡献者预先声明意图,CI 处理协调,npm 可信发布确保安全、可验证的制品。
从单包设置开始了解流程,然后根据需要扩展到 monorepos。初始配置投资很快就能通过减少发布焦虑和减少”糟糕,版本错了”的时刻获得回报。
常见问题
Changesets 适用于单个包和 monorepos。对于单个包,工作流更简单,因为您只需跟踪一个包。从单包设置开始学习基础知识,然后在需要时扩展到 monorepos。无论包数量如何,添加 changesets、创建版本 PR 和发布的核心工作流保持不变。
Changeset bot 会自动在缺少 changeset 文件的 pull request 上发表评论。您还可以配置 CI 检查,在需要但缺少 changesets 时失败。这可以防止在没有适当发布文档的情况下合并变更,尽管您可以将某些 PR 标记为不需要 changesets,例如仅文档更新。
当您将包标记为 major 版本升级时,Changesets 会检查哪些其他包依赖于它。updateInternalDependencies 配置选项控制依赖方是否自动接收 patch 升级。对于紧密耦合的包,使用 linked 或 fixed 选项确保相关包的版本号保持同步。
不可以,使用 OIDC 令牌的 npm 可信发布目前需要公共仓库。对于私有仓库,您必须使用传统的 NPM_TOKEN 方法,将长期访问令牌存储为仓库 secret。请保护好这些令牌,并定期轮换以最小化安全风险。
Understand every bug
Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.