
nodejs.org 仓库的 Changesets 发布流程从编写 changeset 文件到自动发布 npm 包【免费下载链接】nodejs.orgThe Node.js® Website项目地址: https://gitcode.com/GitHub_Trending/no/nodejs.orgnodejs.org 是一个 pnpm monorepo其中packages/下的包如node-core/ui-components、node-core/rehype-shiki会被独立发布到 npm。仓库用 Changesets 工具链来描述这次改动对已发布包意味着什么你在本地运行pnpm changeset生成一个 Markdown 文件并随 PR 提交后续的 CI 流水线会自动消费这些文件来更新版本号、生成 CHANGELOG最终通过 trusted publishing 发布到 npm。读完本文你能掌握该仓库 changeset 文件的格式与写法、.changeset/config.json 中每个配置项的作用以及从 PR 合并到 npm 发布的完整自动化链路和安全校验设计。一、.changeset/目录的定位与基本工作流整个流程的入口说明在 .changeset/README.md它确立了三条核心规则该目录下的每个 changeset 文件描述的都是已发布包的用户可见变更user-facing changes新增 changeset 的唯一方式是运行交互式 CLIpnpm changeset生成的 Markdown 文件必须与对应的包改动一起提交发布工作流会消费这些文件在发布到 npm 之前更新包版本和 changelog。对应的 npm script 定义在根目录 package.json 中{ scripts: { changeset: changeset, changeset:version: changeset version } }也就是说pnpm changeset实际调用的是changesets/cli根目录 devDependencies 中锁在^2.31.1。运行后 CLI 会交互地要求你勾选本次受影响的包、为每个包选择 semver 升级级别major / minor / patch、写一段用于 CHANGELOG 的摘要然后在.changeset/目录下生成一个随机词组命名的 Markdown 文件例如import-aliases-no-preconditions.md。完整的发布过程monorepo 结构、发布流程六步、时序图在仓库的 包发布指南 中有系统描述该指南明确指出对已发布包的修改应该在同一个 PR 中包含 changeset如果某次包改动只影响内部工具、不需要发版则应运行pnpm changeset add --empty来标记无需版本变更。二、changeset 文件的真实格式以仓库现有两个实例为例仓库当前恰好保留了两个未发布的 changeset 文件是理解格式的绝佳样本。2.1 patch 级别示例.changeset/import-aliases-no-preconditions.md--- node-core/ui-components: patch --- Resolve the #ui/* import alias to the compiled output by default, so consumers of the published package no longer need to opt into a bundler-specific rolldown resolution condition. The uncompiled sources stay reachable through the new source condition, which this repositorys own tooling opts into.2.2 minor 级别示例.changeset/shiki-more-more.md--- node-core/rehype-shiki: minor --- Add support for all Shiki languages when the minimal preset is not selected.两个文件共同展示了 changeset 的标准结构YAML frontmatter以---包裹键是包名如node-core/ui-components值是升级级别major/minor/patch。一个文件可以同时声明多个包正文一条面向最终消费者的 CHANGELOG 条目。注意两份示例的写法都是描述对使用者的影响如消费方不再需要 opt into bundler-specific 的 resolution condition而不是罗列内部实现细节——这正是 changeset 与 commit message 的区别文件名随机词组如shiki-more-more由 CLI 生成无实际语义避免多人协作时命名冲突。这两个包都位于 packages/ 工作区目录下workspace 成员在 pnpm-workspace.yaml 中声明为packages/*、apps/*、platforms/*它们的 CHANGELOG.md 会在版本发布时由changesets/changelog-github生成器自动写入这些条目。三、.changeset/config.json配置项逐项解析仓库的 Changesets 配置见 .changeset/config.json全部内容如下{ $schema: https://unpkg.com/changesets/config3.1.4/schema.json, changelog: [ changesets/changelog-github, { repo: nodejs/nodejs.org } ], commit: false, fixed: [], linked: [], access: public, baseBranch: main, updateInternalDependencies: patch, ignore: [] }各字段在本仓库语境下的含义字段本仓库取值作用changelogchangesets/changelog-githubrepo: nodejs/nodejs.org使用 GitHub 风格的 changelog 生成器生成的版本条目会关联到本仓库的 PR方便从 changelog 追溯改动来源commitfalse版本发布时不自动git commit 版本变更交由 CI 工作流以独立 PR 的方式管理见下文chore: version packagesPRfixed[]没有强制锁步升版本的包集合packages/下的各包独立演进版本linked[]没有需要联动升版本的包组accesspublic发布到 npm 时使用 public access与根目录releasescript 中pnpm publish -r --accesspublic的显式参数保持一致baseBranchmain以main分支作为哪些 changeset 尚未发布的基线来比较updateInternalDependenciespatch当一个已发布包依赖了另一个本仓库内的包且后者升版时会自动以 patch 级别更新内部依赖版本ignore[]没有需要排除在 Changesets 管理之外的包其中commit: false是一个值得注意的选择它把版本变更落盘的动作从本地工具转移到了 CI配合后文的 merge queue 与版本 PR 机制使得版本号永远只由流水线统一产生杜绝了人工改版本。四、发布流水线changeset 如何变成 npm 上的新版本发布完全由 Publish Packages 工作流 自动化main分支上的每次 push 都会触发它。其关键步骤可以从源码逐层确认4.1 只信任 merge queue 产出的已签名提交工作流先执行 Verify commit authenticity 步骤publish-packages.yml通过 GitHub API 拉取本次 commit校验两点——commit.verification.verified必须为trueGPG 签名已验证committer 邮箱必须是noreplygithub.com即提交确实经由 GitHub merge queue 合入而非直接向 main 推送。任一检查失败立即exit 1。这保证了只有经过合并队列的受控改动才能触发包发布。4.2 创建版本 PR 或直接发布核心步骤调用 Changesets 官方 Actionv1.9.0publish-packages.yml- name: Create release pull request or publish packages id: changesets uses: changesets/actiona45c4d594aa4e2c509dc14a9f2b3b67ba3780d0d # v1.9.0 with: commit: chore: version packages title: chore: version packages version: node --run changeset:version publish: node --run release commitMode: github-api参数含义version: node --run changeset:version—— 当 main 上存在未发布的 changeset 时Action 会运行changeset version把所有 changeset 文件消费掉更新各package.json版本号、写入 CHANGELOG.md并开/更新一个标题为chore: version packages的 PRpublish: node --run release—— 当版本 PR 合入后再触发时Action 运行releasescript即 package.json 中的pnpm --filter ./packages/* --if-present run build pnpm publish -r --accesspublic构建并发布所有新升版的包commitMode: github-api—— 版本变更通过 GitHub API 提交保证提交者身份可被上面的签名校验识别id-token: write权限workflow 顶层声明支撑 npm trusted publishingOIDC 换取发布凭据全程不需要在仓库中存放 npm token。这与 包发布指南 描述的六步完全对应合并队列 → changeset 汇总为版本 PR → 版本 PR 更新版本号与 changelog → 走常规评审与合并队列 → 构建并发布新升版包 → 发布结果通知到#nodejs-web-infra-alerts。工作流末尾的 Notify 步骤publish-packages.yml用jq把publishedPackages输出格式化成带 npm 版本链接的 Slack 消息并附上触发者与 commit 链接。指南中给出的整体流程图指南同时强调包版本不应被手动编辑或手动发布发布失败时排障后直接从 GitHub Actions 重试即可。五、PR 侧的强制门禁Pull Request Policy 工作流changeset 不是建议提交而是被 CI 强制的。Pull Request Policy 工作流 的触发条件pull-request-policy.ymlon: pull_request: branches: [main] paths: - packages/** types: [opened, edited, synchronize, reopened, ready_for_review]即只有改动触及packages/**的 PR 才会运行 Changesets 检查其检查逻辑只有一行pull-request-policy.ymlpnpm changeset status --since origin/mainchangeset status会检测自基线以来是否有对已发布包的改动但缺少对应 changeset若有则退出码非零、CI 红灯PR 因此被拒收。同时该 job 通过if条件排除了 Changesets Action 自动开出的changeset-release/main分支 PR避免版本 PR 自我卡死。另一个 job 则校验 PR 标题符合 conventional commits 格式type[scope][!]: description且不以句号结尾。这也解释了 包发布指南 中--empty用法的存在如果你的packages/改动只是内部工具性修改、确实不想触发发版运行pnpm changeset add --empty生成一个空 changeset 作为豁免凭证让changeset status能够通过。六、实用要点汇总结合仓库现状pnpm 11.18.0 workspace turbo Changesets 2.xNode 24.11.0对贡献者的操作清单修改packages/*下任何会影响发布产物的代码后在仓库根目录运行pnpm changeset如实勾选受影响的包、选择正确的 semver 级别、撰写面向消费者的变更描述并把生成的.changeset/*.md文件与代码改动一起提交纯内部工具性改动用pnpm changeset add --empty豁免pnpm changeset:version只用于本地验证升版步骤的产出日常流程中该命令由 CI 的changeset version步骤执行并管理产物永远不要手动改package.json里的版本号或手动执行发布——版本号、changelog、npm 发布全部由chore: version packagesPR 与 Publish Packages 工作流统一产生。从源码结构看这套机制把变更声明changeset 文件、变更门禁changeset status与版本执行changeset versionrelease分别放在开发者、PR CI、main 分支 CI 三个环节任何一环都无法被单人绕过是 monorepo 多包独立版本管理的一个完整可参照实现。【免费下载链接】nodejs.orgThe Node.js® Website项目地址: https://gitcode.com/GitHub_Trending/no/nodejs.org创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考