news 2026/9/17 12:49:33

nodejs.org 仓库的 Changesets 发布流程:从编写 changeset 文件到自动发布 npm 包

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
nodejs.org 仓库的 Changesets 发布流程:从编写 changeset 文件到自动发布 npm 包

nodejs.org 仓库的 Changesets 发布流程:从编写 changeset 文件到自动发布 npm 包

【免费下载链接】nodejs.orgThe Node.js® Website项目地址: https://gitcode.com/GitHub_Trending/no/nodejs.org

nodejs.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,它确立了三条核心规则:

  1. 该目录下的每个 changeset 文件,描述的都是已发布包的用户可见变更(user-facing changes);
  2. 新增 changeset 的唯一方式是运行交互式 CLI:
pnpm changeset
  1. 生成的 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 repository's 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/config@3.1.4/schema.json", "changelog": [ "@changesets/changelog-github", { "repo": "nodejs/nodejs.org" } ], "commit": false, "fixed": [], "linked": [], "access": "public", "baseBranch": "main", "updateInternalDependencies": "patch", "ignore": [] }

各字段在本仓库语境下的含义:

字段本仓库取值作用
changelog@changesets/changelog-github+repo: nodejs/nodejs.org使用 GitHub 风格的 changelog 生成器,生成的版本条目会关联到本仓库的 PR,方便从 changelog 追溯改动来源
commitfalse版本发布时不自动git commit 版本变更,交由 CI 工作流以独立 PR 的方式管理(见下文chore: version packagesPR)
fixed[]没有强制锁步升版本的包集合;packages/下的各包独立演进版本
linked[]没有需要联动升版本的包组
accesspublic发布到 npm 时使用 public access,与根目录releasescript 中pnpm publish -r --access=public的显式参数保持一致
baseBranchmainmain分支作为"哪些 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必须为true(GPG 签名已验证);
  • committer 邮箱必须是noreply@github.com(即提交确实经由 GitHub merge queue 合入,而非直接向 main 推送)。

任一检查失败立即exit 1。这保证了只有经过合并队列的受控改动才能触发包发布。

4.2 创建版本 PR 或直接发布

核心步骤调用 Changesets 官方 Action(v1.9.0,publish-packages.yml):

- name: Create release pull request or publish packages id: changesets uses: changesets/action@a45c4d594aa4e2c509dc14a9f2b3b67ba3780d0d # 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的 PR;
  • publish: node --run release—— 当版本 PR 合入后再触发时,Action 运行releasescript(即 package.json 中的pnpm --filter './packages/*' --if-present run build && pnpm publish -r --access=public),构建并发布所有新升版的包;
  • commitMode: github-api—— 版本变更通过 GitHub API 提交,保证提交者身份可被上面的签名校验识别;
  • id-token: write权限(workflow 顶层声明)支撑 npm trusted publishing(OIDC 换取发布凭据),全程不需要在仓库中存放 npm token。

这与 包发布指南 描述的六步完全对应:合并队列 → changeset 汇总为版本 PR → 版本 PR 更新版本号与 changelog → 走常规评审与合并队列 → 构建并发布新升版包 → 发布结果通知到#nodejs-web-infra-alerts。工作流末尾的 "Notify" 步骤(publish-packages.yml)用jqpublishedPackages输出格式化成带 npm 版本链接的 Slack 消息,并附上触发者与 commit 链接。

指南中给出的整体流程图:

指南同时强调:包版本不应被手动编辑或手动发布;发布失败时,排障后直接从 GitHub Actions 重试即可。

五、PR 侧的强制门禁:Pull Request Policy 工作流

changeset 不是"建议提交",而是被 CI 强制的。Pull Request Policy 工作流 的触发条件(pull-request-policy.yml):

on: pull_request: branches: [main] paths: - packages/** types: [opened, edited, synchronize, reopened, ready_for_review]

即只有改动触及packages/**的 PR 才会运行 Changesets 检查,其检查逻辑只有一行(pull-request-policy.yml):

pnpm changeset status --since origin/main

changeset 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.x,Node >= 24.11.0),对贡献者的操作清单:

  1. 修改packages/*下任何会影响发布产物的代码后,在仓库根目录运行pnpm changeset
  2. 如实勾选受影响的包、选择正确的 semver 级别、撰写面向消费者的变更描述,并把生成的.changeset/*.md文件与代码改动一起提交;
  3. 纯内部工具性改动用pnpm changeset add --empty豁免;
  4. pnpm changeset:version只用于本地验证升版步骤的产出,日常流程中该命令由 CI 的changeset version步骤执行并管理产物;
  5. 永远不要手动改package.json里的版本号或手动执行发布——版本号、changelog、npm 发布全部由chore: version packagesPR 与 Publish Packages 工作流统一产生。

从源码结构看,这套机制把"变更声明"(changeset 文件)、"变更门禁"(changeset status)与"版本执行"(changeset version+release)分别放在开发者、PR CI、main 分支 CI 三个环节,任何一环都无法被单人绕过,是 monorepo 多包独立版本管理的一个完整可参照实现。

【免费下载链接】nodejs.orgThe Node.js® Website项目地址: https://gitcode.com/GitHub_Trending/no/nodejs.org

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 12:45:58

STM32C5串口调试实战:从引脚映射到printf重定向

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/17 12:45:57

AlpacaEval 反超 GPT-4 的 Xwin-LM,用 TaoToken Key 对照跑分怎么验证?

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/17 12:45:13

从零手写Linux LED驱动:设备树+GPIO子系统+字符设备全解析

1. 为什么一盏LED灯能讲透Linux设备驱动开发1.1 一个“点灯”需求背后牵出的完整知识链很多朋友第一次接触嵌入式Linux驱动&#xff0c;都是从点亮一颗LED开始的。当年我也是这样&#xff1a;手里拿着一块开发板&#xff0c;想着“单片机里点灯就是写寄存器的事&#xff0c;Lin…

作者头像 李华
网站建设 2026/9/17 12:44:53

LY-E252:EtherCAT从站同封装替换实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/17 12:44:16

微信小程序点餐系统设计与实现:从购物车到支付回调全解析

简介&#xff1a;一份面向毕业设计场景的微信小程序点餐系统完整设计文档&#xff0c;适合计算机相关专业学生或餐饮软件开发者参考。文档从项目背景、开发意义、技术选型入手&#xff0c;系统覆盖可行性分析、功能需求分析、流程图与ER图设计&#xff0c;以及数据库表结构设计…

作者头像 李华