EmDash Changeset 编写与评审指南:从补丁记录到面向读者的发布文档
2026/9/23 2:36:35 网站建设 项目流程

EmDash Changeset 编写与评审指南:从补丁记录到面向读者的发布文档

【免费下载链接】emdashEmDash is a full-stack TypeScript CMS based on Astro; the spiritual successor to WordPress项目地址: https://gitcode.com/gh_mirrors/emdas/emdash

EmDash 是一个基于 Astro 的全栈 TypeScript CMS,采用 Changesets 工具链管理多包仓库的版本发布与 CHANGELOG 生成。本指南基于仓库根目录下.changeset/README.md的完整规范,结合仓库内config.json配置与真实 changeset 案例,系统讲解何时添加 changeset、如何撰写面向读者的变更描述、如何选择 bump 类型,以及如何像评审文档一样评审 changeset。读完本文,你将掌握为 EmDash 及其子包(如emdash@emdash-cms/admin@emdash-cms/cloudflare)提交高质量变更记录的全部实操方法。

Changeset 是什么,为什么它如此重要

在 Changesets 工作流中,一个 changeset 决定了两件事:

  1. 版本号如何提升:它声明被影响的包和 bump 类型(patch/minor/major),发布时据此计算新版本号;
  2. CHANGELOG 的正文来源:它的描述会作为该包 CHANGELOG 中的公开文档条目,被读者在决定“要不要升级、怎么升级”时反复阅读。

因此,.changeset/README.md开篇给出的核心写作准则非常关键:

Write and review it for someone who runs the package, not someone who has read the pull request or diff.

即:为“运行这个包的人”而写,而不是为“看过 PR 或 diff 的人”而写。读者没有你的 PR 上下文,他们只能从这段描述判断这次发布是否与自己相关、升级后需要做什么。

仓库的每个变更记录都以 Markdown 文件形式存放在 .changeset/ 目录下,文件名通常是无意义的随机短语(如fuzzy-lions-check.mdquiet-workers-start.md),真正的信息都在文件 frontmatter 与描述正文里。例如:

--- "emdash": minor --- Adds `GET /_emdash/api/health` so external tools can confirm an EmDash site is reachable and whether its plugin registry is enabled.

frontmatter 声明了受影响的包与 bump 类型,正文则描述用户可感知的新能力。

何时需要添加 Changeset

必须添加的场景

任何对已发布包行为或 API 的改动都需要 changeset,包括 bug 修复、新特性,以及改变行为的重构。文档中特别强调:没有 changeset 的改动不会触发发布("Without one, the change will not trigger a release")。

多包场景的规则如下:

场景规则
改动涉及多个包只需一个 changeset,在 frontmatter 中列出所有受影响包
一个 PR 包含多个独立改动可以每个改动一个 changeset,各自成为独立的 CHANGELOG 条目
多个 PR 共同构建同一特性(如互相依赖的 PR 栈)只写一个描述完整用户可见能力的 changeset,放在栈中某一个 PR 里,而不是记录实现顺序
独立可发布的 PR除非发布协调能保证所有 PR 同时发布,否则每个 PR 需要各自的 changeset

不需要添加的场景

仅涉及文档、测试、CI/工具链、demo 和模板的改动不需要 changeset。原因是这些改动不改变已发布包对外的行为。

这一规则在 .changeset/config.json 中有直接体现——ignore数组明确列出了从发布流程中排除的包,包括各类 demo(@emdash-cms/demo-cloudflare@emdash-cms/playground)、模板(@emdash-cms/template-blog@emdash-cms/template-marketing等)、测试用插件(@emdash-cms/plugin-api-test)以及docs包。这些包不参与版本发布,自然也不需要 changeset。

创建 Changeset 的命令

在仓库根目录执行:

pnpm changeset

随后编辑生成的 Markdown 文件,在 frontmatter 中由 PR 作者选择受影响的包和 bump 类型。

.changeset/config.json可以看到该仓库的 Changesets 配置细节:

  • changelog使用@changesets/changelog-github插件,仓库为emdash-cms/emdash,生成的 CHANGELOG 会关联 GitHub PR/issue;
  • fixed数组将emdash@emdash-cms/admin@emdash-cms/auth@emdash-cms/blocks@emdash-cms/cloudflare@emdash-cms/gutenberg-to-portable-text@emdash-cms/x402create-emdash绑定为同一版本组——这意味着这些包在发布时会一起提升版本,因此涉及它们的变更通常要写进同一个 changeset;
  • commit: false表示不会自动把 changeset 提交到版本控制;
  • baseBranchmain

选择 Bump 类型:patch、minor 与 major

在 changeset frontmatter 中需要选择版本提升类型,规则如下:

  • patch:用于 bug 修复和小改进;
  • minor:用于新的向后兼容特性;
  • majorEmDash 在 1.0 之前不接受majorbump("EmDash does not currently acceptmajorbumps while it is pre-1.0")。

破坏性变更或重大默认值变更需要事先获得维护者批准,并且要使用与维护者商定的包与 bump 策略。这一点在规范中反复出现:不要自行决定破坏性变更的发布方案。

仓库中的真实案例印证了这套规则。例如 .changeset/quiet-workers-start.md 是一个典型的patch:它修复了 Cloudflare Worker 的启动性能问题(懒加载依赖、降低启动 CPU),不改变外部行为,因此使用patch并同时列出@emdash-cms/cloudflareemdash两个受影响包。而 .changeset/editor-link-search.md 是新增的向后兼容能力(富文本编辑器链接输入框按标题搜索已有内容),因此声明为minor

以发布行为开头:第一句话就要说清“发生了什么”

规范要求 changeset 描述以现在时动词开头,如FixesAddsUpdatesRemovesDeprecates。开篇句子需要做到:

  • 当读者能识别时,点名用户可见的 API、选项、命令、组件或行为
  • 说明谁受影响、他们现在能做什么,或描述被修复的可观察问题
  • 描述发布后的行为,而不是文件名、私有函数、重构细节、查询或实现选择。

细节的多少要与影响成正比:

  • 一个patch通常一句具体的话就足够;
  • 一个重要的minor特性通常需要包含:能力说明、基本用法、默认值与兼容性、受影响环境,以及读者需要采取的任何行动;
  • 最重要的能力要放在最前面,不要埋没在附带修复或实现细节之下。

破坏性变更与默认值变更必须“不容误解”

规范强调:Breaking changes and default changes must be unmistakable。必须说明:

  1. 谁受影响;
  2. 之前的行为和当前的行为;
  3. 迁移所需采取的行动;
  4. 在可能的情况下,如何恢复之前的行为。

优先提供最小配置示例或 before-and-after 示例,而不是笼统的警告。在维护者批准包的发布策略之前,不要提交破坏性变更

三个完整的撰写示例解析

规范给出了三个可以直接套用的完整示例,下面逐一解析其结构。

示例一:patch 条目——点名命令与可观察问题

--- "emdash": patch --- Fixes `emdash migrate --json` so progress messages go to stderr, allowing scripts to parse stdout as JSON.

要点:点名了受影响的命令emdash migrate --json,并描述了脚本作者能观察到的具体问题(进度消息污染了 stdout,导致无法把 stdout 当作纯 JSON 解析)。这正是“为运行包的人而写”的典范——脚本作者读完立刻知道这个修复对自己意味着什么。

示例二:minor 特性——能力、用法与退出码契约

--- "emdash": minor --- Adds `--check` to `emdash migrate` so deployment pipelines can detect pending or unknown migration records without changing the database. Run the check after deploying the application artifact that produced the migration manifest: ```sh pnpm exec emdash migrate --check ``` The command exits with `0` when the database matches the build, `2` when known migrations are pending, and `3` when the database contains migration records unknown to the build. It works with every database adapter supported by the migration manifest.

要点:先说明新能力与它的价值(让部署流水线在不修改数据库的情况下检测迁移状态),再给出最小可用命令,然后完整定义退出码契约(0一致、2有已知迁移待执行、3存在构建未知的迁移记录),最后说明适用范围(迁移清单支持的所有数据库适配器)。这类“退出码契约”信息对部署流水线的维护者是关键决策依据。

示例三:经批准的默认值变更——影响与回退路径显式化

--- "emdash": minor --- Updates `memoryCache()` to use a five-minute default TTL instead of one hour, so sites using the in-memory object cache refresh cached pages more frequently after an upgrade. Sites that depend on the previous one-hour lifetime can keep it explicitly: ```ts objectCache: memoryCache({ defaultTtl: 3600 }); ``` #### What should I do? Set `defaultTtl: 3600` before upgrading if the shorter cache lifetime would add unacceptable load to your site.

要点:默认值变更被提升为minor(已获批准)。描述包含:前后行为对比(五分钟 vs 一小时)、受影响用户(使用内存对象缓存的站点)、迁移动作(显式设置defaultTtl: 3600)、以及恢复旧行为的方法。文档中还示范了较长条目使用 Markdown 标题的规范——从 h4(####)开始,因为 changeset 会被嵌入到生成的 CHANGELOG 标题之下,使用 h2/h3 会破坏文档层级结构。

破坏性变更的同等要求

规范明确指出,破坏性变更需要同样级别的细节:第一句话点名被移除或改变的 surface,然后给出最小可行的迁移方案。在维护者批准其包与发布策略之前,不得提交破坏性变更。

好与坏的描述对比:把“技术相关”变成“发布文档”

规范给出了三组 diff 对比,直观展示两类描述的区别:

- Fixes a bug in media handling. + Fixes R2 media uploads larger than 10 MB failing before the upload begins.
- Refactors `hydrateEntryBylines` to chunk SQL IN clauses. + Fixes D1 errors when loading an entry with more bylines than the database bind-parameter limit.
- Updates migration status handling and exit codes. + Adds `emdash migrate --check` so deployment pipelines can detect pending or unknown migrations without changing the database.

左侧是“技术相关的散文”,描述了内部机制(重构、chunk SQL IN 子句、处理迁移状态);右侧是“有用的发布文档”,描述用户能观察到的行为变化(R2 上传大于 10 MB 失败、D1 绑定参数超限错误、新增的检查命令)。这正是评审 changeset 时要做的核心判断。

仓库中的真实条目同样遵循这一风格。例如 .changeset/forms-webhook-deferred.md 描述表单 webhook 静默失效的根因与修复:fetch只在传输层错误时 reject,因此 4xx、5xx 以及认证端点重定向后的登录页都被当作“成功”处理、不留痕迹;修复后通过after()注册到 host 保证执行完成,并通过比较最终 URL(而非Response.redirected,因为插件 HTTP 访问自行跟随重定向、总是报告redirected: false)识别重定向场景。而 .changeset/calm-datetimes-normalize.md 则示范了修复类条目如何同时说明迁移行为:所有内容 datetime 以固定毫秒的 UTC ISO 字符串存储,管理端按站点时区转换,API/MCP/CLI 写入要求Z或显式 UTC 偏移;迁移在修改前报告非规范值,遇到夏令时重复/跳过的时段会停止写入并报告需要显式偏移的行。

不要只把解释写在 changeset 里

规范有一条容易被忽略但很重要的要求:

Do not keep useful explanations or examples only in a changeset or PR description. Add them to the canonical feature or upgrade documentation too; the CHANGELOG is usually read once, while the docs remain the reference.

即:不要把有用的解释或示例只留在 changeset 或 PR 描述里。CHANGELOG 通常只被读一次,而官方文档是长期参考。因此,重要的特性或升级说明必须同步写入正式的功能文档或升级文档。

像评审文档一样评审 Changeset

评审 changeset 时,frontmatter 的有效性和技术准确性是必要但不充分的条件("Frontmatter validity and technical accuracy are necessary but not sufficient")。遇到以下情况应要求重写:

  • 描述含糊不清;
  • 只描述内部机制;
  • 读起来像 commit message;
  • 把重要能力埋在附带细节之下;
  • 无助于读者判断“这次发布对我是否重要”。

正确的做法是:把描述当作文档来评审,与 bump 类型和包列表一并审查

实践建议:把规范落到 EmDash 日常贡献中

结合上述规范与仓库实际情况,提交 EmDash 变更时建议按以下流程操作:

  1. 在仓库根目录运行pnpm changeset生成新的变更文件;
  2. 在 frontmatter 中列出所有受影响包(若涉及fixed版本组中的包,注意它们会一起发布);bug 修复用patch,向后兼容新特性用minor,1.0 之前不使用major,破坏性变更先与维护者确认策略;
  3. 正文以Fixes / Adds / Updates / Removes / Deprecates开头,点名用户可见的命令、API 或行为,描述发布后的行为而非实现细节;
  4. 需要时补充最小可用示例与默认值/退出码等契约信息;默认值变更与破坏性变更必须写明前后行为、迁移动作与恢复方法;
  5. 超过一段的条目用####及以上标题组织,避免破坏生成的 CHANGELOG 层级;
  6. 把重要的用法说明同步补充到正式文档,而不是只留在 changeset 中。

对于不发布版本的包(见 .changeset/config.json 的ignore列表)以及纯文档、测试、CI/工具链、demo 和模板改动,则无需创建 changeset。

遵循这套规范,EmDash 的每个 CHANGELOG 条目都会成为一份独立可读、信息完整、面向升级决策者的发布文档——这正是.changeset/README.md以及整个 Changesets 工作流想要达成的目标。关于 Changesets CLI 与配置的更多行为细节,可参阅 Changesets 官方文档(仓库内.changeset/config.json即其配置的落地实例)。

【免费下载链接】emdashEmDash is a full-stack TypeScript CMS based on Astro; the spiritual successor to WordPress项目地址: https://gitcode.com/gh_mirrors/emdas/emdash

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

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

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

立即咨询