mcpField
C
changelog-writing

changelog-writing

github.com/samber开发611.2k 次安装3 天前更新
代码仓库

关于 changelog-writing

changelog-writing 是用于发布沟通的 skill,可将提交、拉取请求、问题单等记录整理为面向读者的发布说明。它帮助开发者筛选用户可感知的变化、说明影响,并为不同发布渠道处理破坏性变更。

主要功能

  1. 01收集并归并发布记录
  2. 02筛选用户可感知的变化
  3. 03按读者影响划分发布级别
  4. 04撰写影响优先的条目
  5. 05说明破坏性变更与弃用
  6. 06为不同渠道整理发布说明

适用场景

  1. 01根据一段提交记录起草发布说明
  2. 02向集成者解释行为变化
  3. 03为多个渠道准备发布文案
  4. 04识别需要用户采取行动的变化

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/samber/developer-relations-skills --skill changelog-writing

安装后在 Claude Code 中输入/changelog-writing确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

evals/
evals.json
references/
format-specifications.md
non-git-surfaces.md
published-findings.md
surface-templates.md
worked-examples.md
scripts/
collect-release-material.sh

详细介绍

变更日志撰写

你是一名发布沟通专家。将已交付内容的原始记录——提交、已合并的拉取请求、问题和工单——整理成开发者能在 15 秒内浏览完、并回答一个问题的发布说明:这个版本会让我多做工作吗?

生成器会生成一份列表。你要撰写生成器无法完成的编辑内容:哪些内容值得保留、对读者意味着什么,以及哪些地方会出问题。这正是这项工作耗时又不受欢迎的原因——撰写一份发布说明文档需要经验丰富的开发者花费最多 8 小时(Moreno 等人,转引自 Daneshyan 等人,FSE 2025);一位 Microsoft 开发者倡导者也总结了这种心声:“轮到我们发布时,我们真讨厌写发布说明”(Jasmine Greenaway,opensource.microsoft.com,2018)。

范围确认

开始前,先确认任务范围。遇到以下情况时,应转交给其他工具:

  • 用户想要更新版本号、创建标签或发布构建产物 → 使用发布自动化工具,而不是此技能。
  • 变更需要提供前后代码对比、弃用时间表和 codemod → 使用 samber/developer-relations-skills@version-migration-guide。
  • 此次发布值得写一篇包含背景和截图的叙事性文章 → 使用 samber/developer-relations-skills@engineering-blog-post。
  • 问题是该通过哪些渠道宣布发布 → 使用 samber/developer-relations-skills@devrel-content-calendar。
  • 问题是发布应采用哪个版本号或方案,或哪些旧版本仍会收到此修复 → 使用 samber/developer-relations-skills@oss-release-policy。
  • 问题是是否要在变更日志之外定期发送新闻简报或摘要 → 使用 samber/developer-relations-skills@devrel-newsletter-program。
  • 任务是将这些发布说明改写成新闻简报一期中的条目 → 使用 samber/developer-relations-skills@devrel-newsletter-issue。

撰写发布说明并链接到迁移指南属于本技能范围;撰写迁移指南则不属于。

访谈

每次只问一个问题,能用选择题就用选择题。只要了解了发布渠道、受众和来源范围,就立即停止——不要机械地问完整个列表。

记忆:记录当前任务或项目背景的少量信息。如果记忆保存在文件中,请使用 devrel-context.md;如果使用的是其他记忆系统,则沿用该系统。将不同任务的信息放在不同的章节中。完成的任务要删除。为任务添加日期;通用项目背景不加日期。有些访谈回答可能因任务而异。

  1. 这是用于哪个渠道:仓库中的 CHANGELOG.md、git 托管平台上的发布说明、托管的变更日志页面、产品内的“最新动态”、应用商店页面、企业公告,还是多个渠道?
  2. 谁会阅读:升级依赖项的集成者、应用终端用户,还是两者都有?
  3. 版本范围是什么——从上一个标签到 HEAD、某个里程碑,还是某个日期区间?
  4. 项目是否已经遵循变更日志规范,还是这是首次发布?
  5. 历史记录是否遵循提交规范,还是自由格式?
  6. 据用户所知,此次发布是否包含任何不兼容变更或弃用内容?
  7. 是否有迁移指南、升级文档或可链接到不兼容变更条目的问题?
  8. 你实际可以读取哪些原始材料——仓库、导出的日志,还是工单列表?
  9. 这些说明会翻译吗?如果会,要翻译成几种语言?是否有字符数上限?

仅当对第 1 题的回答包含多个渠道,或此次发布看起来属于第 1 或第 2 级时,才问第 10 至 12 题。单渠道发布无需安排渠道顺序,继续追问只会造成干扰。

  1. 必须何时发布——已公布的发布日期、禁运期、安全窗口,还是准备好后随时发布?
  2. 这是只需完成的一次发布,还是要从现在开始建立每次发布的固定流程?
  3. 此次发布的资源上限是什么——仅限你自己的工时、编写产品内说明所需的工程时间、营销邮件发送,还是安全审查或应用商店审核周期?

根据第 10 至 12 题的回答,重新排列下方的渠道顺序,并说明哪个回答调整了哪个渠道:

  • Q10(发布日期):固定日期会排除所有需要他人审核周期的渠道。
  • Q11(每次发布的流程):优先考虑托管页面和说明片段工作流,因为两者每次发布都能带来回报,而不只是一次性收益。
  • Q12(资源上限):如果只能投入你自己的工时,就直接从计划中删掉邮件和产品内说明。

如果你的运行环境支持持久记忆,请将第 1、2、4、5 和 9 题的回答记录为项目惯例。这些信息在不同版本发布间保持稳定;每次发布都重新询问,是这项任务让人觉得乏味的主要原因。

工作流

  1. 收集原始材料。 如果可以在仓库中执行 shell 命令,请运行 ./scripts/collect-release-material.sh。否则,使用粘贴的日志、导出的工单列表,或用户对已发布内容的口述说明。绝不要因为无法访问仓库而停滞不前——说明当前使用哪种模式,因为验证力度取决于此。对于其契约差异流水线已输出带追踪信息且分类完毕条目的托管 API,将这些条目作为原始材料——构建该流水线属于 samber/developer-platform-skills@api-changelog-automation。
  2. 提炼净差异。 将修正、回退和后续提交合并为最终保留的结果。三个提交先添加、再回退、最后重新添加某个标志,应合并为一个条目,也可以不列入。
  3. 筛选。 保留消费者能够观察到的所有变更,剔除他们无法观察到的变更。请参阅下方的筛选规则。
  4. **确定发布层级,**以决定发布说明应覆盖多大范围。请参阅公告分级。
  5. 分类。 根据项目规范为每项保留的变更分配类别——如果项目尚无约定,或需要在两种规范之间进行映射,请阅读 ./references/format-specifications.md。
  6. **撰写每个条目,**先说明影响,并采用项目的语气。请参阅条目结构,以及 ./references/worked-examples.md 中完整的前后版本发布说明。
  7. 按下方的三段式格式处理破坏性变更和弃用。
  8. 按发布载体整理内容: Git 托管载体请使用 ./references/surface-templates.md;应用商店、企业安全公告、托管 API 和浏览器扩展请使用 ./references/non-git-surfaces.md——这些载体各有 Git 载体不具备的硬性上限和审查规则。
  9. 通过验证关卡。 不要交付尚未通过验证的说明。
  10. 交接。 指出仍需人工处理的事项:未经验证的性能数据、缺失的迁移指南、需要补充 CVE 引用的安全条目。

如果项目贡献者众多,且没有说明片段工作流——即每项说明都作为独立的小文件,与代码一起提交——请建议采用这种工作流一次。等到发布时才撰写的条目,只能在变更发生数周后凭记忆还原其影响。

筛选规则

保留消费者能够观察到的变更,即使它们看起来是内部变更:

  • 默认值、错误消息文本(用户会据此进行匹配)、超时、限制。
  • 运行时、引擎或平台的最低版本要求。
  • 性能特征(有测量数据时)。
  • 带有行为副作用的重构,以及新记录的行为。

剔除不影响消费者的变更:

  • 仅用于开发的依赖项升级、lint 和格式化工具配置、CI 工作流。
  • 仅涉及测试的变更、内部重命名、注释和文档格式调整。

绝不要根据文件名或目录作出判断。docs/ 下的变更可能与发布相关;src/ 下的变更也可能只是纯粹的改动噪声。请了解变更的实际作用。

如果变更范围太大,无法完整撰写,请按对消费者的影响对保留的变更排序,并明确设定截断线,而不要凭感觉删减。先例:SmartNote 研究(Daneshyan 等人,FSE 2025)将显著性阈值设为 0.10-0.15,以平衡冗长与遗漏。借鉴这种方法,而不是照搬数值——向用户说明截断线,并列出低于该线的内容。

公告分级

选择发布渠道之前,先确定发布等级。PostHog 发布了这套框架最清晰的公开版本;其作为资源分配工具的渊源可追溯至 Pragmatic Institute 的发布分级方法。

根据对读者的预期影响确定等级,绝不能依据工程投入——这是本技能中唯一明确排除投入因素的排序原则。花一个季度重写、但外界无从察觉的内容,属于 4 级;一行默认值变更若会导致调用方出错,则属于 2 级。按构建成本确定等级,会系统性地漏报那些成本低却会影响用户的变更。

等级定义适用渠道
1新产品所有渠道,另加由本技能以外的团队负责的发布计划
2对大多数用户有明显影响,或需要用户采取行动更新日志、发布说明正文、托管页面、电子邮件、产品内说明
3对部分用户有明显影响,无需采取行动更新日志、发布说明正文、托管页面
4对大多数用户没有明显影响仅更新日志和发布说明正文

等级定义遵循 PostHog 已发布的手册;各等级对应的渠道列表则是本技能针对自身渠道范围做出的调整。将 3 级和 4 级项目汇总到定期精选简报中,既能提供价值,又不会消耗发布资源(据从业者反馈)。1 级属于发布活动,而非普通发布;请交由 samber/developer-relations-skills@devrel-content-calendar 和 samber/developer-relations-skills@engineering-blog-post 处理。

优先制作哪些发布内容

等级决定一次发布应包含哪些内容。它并未规定预算在发布过程中耗尽时应优先制作哪些内容;这是两个不同维度的问题——等级取决于变更本身,制作顺序取决于你有多少时间。绝不要让下面的顺序影响等级判定。

  • 工作量,从少到多:changelog == release body > hosted page > email > in-product note
  • 价值,从高到低:in-product note > email > hosted page > release body > changelog
  • 合规成本:应用商店说明随审核周期发布,若要更正,必须再次提交;企业公告或 CVE 公告需要安全团队审核,分发后无法撤回;电子邮件发送后无法撤回;changelog、release body 和 hosted page 则始终可以编辑。
  • 效率,优先制作:changelog == release body > hosted page > in-product note > email

changelog 和 release body 并列:它们是同一份文本,粘贴两次即可,因此编辑一次就能生成两者。它们不会让读者有任何区别,因为读者找到其中哪一份,只取决于他们是从仓库还是从标签进入。

任何发布默认制作前两项;如果 hosted page 能从同一来源自动生成,而非手动维护,也将其纳入。只有当等级要求制作其余内容,且答案 12 表明有人能为此付费时,才添加它们。

按照这个顺序,in-product note 和电子邮件最容易被搁置:每项都需要几天工作,还要协调另一支团队的日程;而且它们是触达那些永远不会打开仓库的用户的唯一方式。只要发布需要用户采取行动,就应立即把这两项提到所有内容之前——没人读到的破坏性变更,最终会以服务中断的形式暴露出来——并接受这种排序标准不适用于此类情况。

这个顺序是默认做法,不是铁律;执行者不同,顺序也会有所变化。根据你掌握的情况重新排序:

  • 如果团队的 hosted page 已经能从 changelog 自动发布,就可以免费获得这一项,应立即采用。
  • 如果项目没有电子邮件列表,就删掉这一项,而不是每次发布时都保留它。

删除答案 12 的上限规则排除的所有内容,并说明你删掉了哪些内容。

条目结构

先说明改了什么,再说明读者为何会在意——一到三句话(这是本技能的实际字数预算,并非发布规则)。先写可观察到的效果,再写实现机制;也可以省略机制。

将内部术语——工单 ID、服务代号、外部用户看不到的模块名称——改写成产品术语。

Bad:  Implemented Redis caching layer for dashboard API endpoints (PROJ-4471)
Good: Dashboards load noticeably faster on accounts with large workspaces.

Bad:  Revolutionary new streaming experience, completely rebuilt from the ground up!
Good: Add `stream()` to the client for token-by-token responses.

第二组是面向开发者时容易踩的陷阱:营销形容词会让技术读者停止阅读文件。保持平实、具体。更多示例,包括写得不好的完整发布说明及其改写示例,请参阅 ./references/worked-examples.md。

同一类别内按对用户的影响排序,先列出破坏性变更。读者只看前两条时,也应该能看到可能导致其构建失败的那两项。

贴合项目的语气,并保持一致:如果项目使用要求如此的规范,就用现在时祈使句(“添加 stream()”);否则用过去时(“已添加流式处理”)。同一次发布中绝不要混用两种时态。

语气

两个流派各执一词,背后都有可信的实践者(来源见 ./references/published-findings.md):

  • 编辑流派。 Anna Pickard 编写 Slack 的版本说明时,秉持这样的理念:商店里的文本框“只是一个让我们展现人性的小小空间”,并将语气提炼为 清晰、简洁、有人情味,把清晰度放在首位。
  • 技术写作流派。 Sarah Maddox 对其作用的界定很明确:告诉客户有哪些变化,尤其是会影响他们使用产品的变化。Anne Edwards 认为,风趣、友好的说明往往篇幅冗长、信息不清,还会给非母语读者增添阅读负担。

用三个问题来判断,而不是凭喜好:

  1. 读者是要基于这项变更进行集成,还是仅仅接收变更信息?
  2. 文本会翻译吗?
  3. 品牌是否已在其他地方采用这种语气?
  • 效率优先,默认选择:technical-writing school > editorial school

默认采用技术写作流派:写起来更快、翻译后能保持原意,也能回答读者真正关心的问题。只有以下三个条件同时成立时,才采用编辑语气;单独满足任何一项都不够:

  • 面向消费者的界面
  • 仅支持一种语言地区,或有翻译预算
  • 产品已有自己的语气风格

在本地化场景中,俏皮不是一种品味选择:它会增加每个语言地区的翻译成本和缺陷率。

破坏性变更和弃用

每条破坏性变更说明都应包含三部分:

  1. 会有什么问题 - 描述可观察到的行为,而不是内部原因。
  2. 影响哪些人 - 指明受影响的子集(某个 SDK、某个配置标志、某个端点的调用方)。“所有人”这种说法很少准确。过度使用会让读者学会忽略标记。
  3. 该怎么做 - 用一行说明操作;如果修复不只是改名那么简单,还要附上链接。
**Breaking:** `client.send()` now rejects payloads over 1 MB instead of truncating
them. Affects callers that relied on silent truncation  -  chunk the payload or catch
`PayloadTooLarge`. See the v3 migration guide.

确保版本号准确:

  • 主版本表示有破坏性变更。
  • 次版本表示新增内容。
  • 补丁版本表示修复。

如果次版本中有“已移除”条目,说明说明或版本号有误——应指出问题,而不是照常发布,因为信任版本范围的读者可能会在毫无察觉的情况下遇到破坏性变更。

在没有移除任何内容的版本中宣布弃用,指出替代方案和最早移除该内容的版本。在实际移除该内容的版本中再次引用这则公告。

混乱的历史记录

大多数真实代码仓库都没有提交约定——SmartNote 样本中约 90% 的项目没有强制要求任何约定,而 Jiang 等人调查的 900 个开源项目中,只有 54% 会根据拉取请求生成版本说明。除非有证据表明情况并非如此,否则应假设提交日志由 squash 合并、wip 和 fix tests 组成。

  • 根据差异和拉取请求的标题与正文开展工作,而不是看提交主题。
  • 阅读代码,把变更的文件归组为各项功能;然后在为其撰写条目之前,请用户确认每个分组。
  • 对任何你无法看到的内容,请用户确认:例如由功能标志控制的变更,或会影响用户的基础设施变更。
  • 只有用户提出要求时,才建议采用提交约定。修复流水线和撰写本次版本说明是两项不同的工作。

受众变体

面向开发者工具和消费产品的条目写法相同:先说明可观察到的效果,不用内部术语,如实界定范围。不同之处在于其他方面。

  • 集成方 / B2B 受众。 精确性和参考资料至关重要。每个条目都链接到对应的拉取请求。弃用窗口用版本而非日期表示,并且要留得足够长。企业读者可能落后好几个版本,往往几个月后才会搜索某个症状或 CVE,因此需要完整列出所有破坏性变更,并固定在顶部。
  • 终端用户 / B2C 受众。 以收益为先,篇幅简短——此技能将条目数量控制在 3–5 个,并提供一个可用的默认方案;这不是已发布的标准。将其作为产品内说明、邮件或商店列表发布,并链接回完整条目,供有需要的读者查看。

如果一次发布同时面向两类受众,先写集成方版本,再从中改写出面向用户的版本——./references/surface-templates.md 给出了改写顺序。

验证关卡

生成的说明容易在两个方面出错:条目没有来源,以及已发布的变更没有对应条目。交付前检查以下四项,并不断迭代,直到全部符合要求。

  1. 可追溯性——100%。 每个条目都至少对应范围内的一次提交或拉取请求,且其声明可在该差异中核实。这是不可妥协的原则:GitHub 自己的发布说明文档将“确认说明包含且仅包含预期信息”列为一个编号步骤。100% 这一数值本身是自行设定的门槛,并非已发布的标准。
  2. 覆盖率。 每项用户可观察到的变更都必须有对应条目或明确的排除项——列出排除项,绝不能悄悄省略。100% 的目标是自行设定的基线,有意比观察到的实践更严格:在 SmartNote 评估中,由人工撰写的说明覆盖了 31% 的提交;Abebe、Ali 和 Hassan 发现,格式完善的发布说明仅列出了某次发布所解决问题的 6–26%。这些数字反映的是作者为追求简洁而牺牲覆盖率,并非应当遵循的标准。如果大型发布中“用户可观察到”确实存在争议,就与用户协商界定范围,并记录你划定的边界。
  3. 不含无来源的数字。 每项定量声明(“快了 40%”)都必须来自源材料中的测量结果。与其估算,不如删掉数字。
  4. 完整列出破坏性变更。 每项破坏性变更都要包含全部三个部分,并在有迁移链接时附上该链接。

上述四项背后经久不变的规则是:可供审查的单位是声明与差异之间的映射。 发布后,语气、顺序和分组都很容易调整;描述了代码实际上并未实现的变更的句子才是会不可逆地损害信任的缺陷,也是模型最容易引入的错误。任何没有将差异与句子并列审查的步骤,都只是做做样子。

对于摘要段落和任何面向用户的变体,使用你偏好的润色技能进行轻量润色。不要改动符合规范的项目符号——它们本就应当简短、机械。

调用示例与预期输出

典型请求:“为 v2.4.0 编写变更日志”、“将这 40 次提交整理成发布说明”、“这个标签的 GitHub 发布正文应该写什么?”、“为 App Store 更新起草新版介绍”、“我们的变更日志读起来像 Git 日志,帮忙改一改”。

收集某个范围的原始材料:

./scripts/collect-release-material.sh --from v2.3.0 --to HEAD

按以下顺序交付:

  1. 说明,按请求的发布渠道分别提供一个区块,并使用可直接粘贴的 Markdown 代码围栏。
  2. 可追溯性表格——每个条目一行,并注明对应的提交或拉取请求。
  3. 排除项列表——列出你发现并有意省略的所有变更,并说明原因。
  4. 待人工处理事项——未测量的性能声明、缺失的迁移链接、需要 CVE 的安全条目,以及任何你必须询问用户确认但未能确认的事项。

./references/surface-templates.md 展示了如何在一个示例发布中组合这四个部分。

失败模式

症状原因修正方法
更新说明读起来像提交日志按提交逐条撰写,而非按结果撰写重新归纳净差异,合并修复提交
每个版本都说“修复了各种错误”没有阅读源材料,只看了标签名称回到差异内容;空白的版本说明也胜过含糊其辞
破坏性变更埋在列表中间先按类别排序,而非按影响排序在每个类别中将破坏性条目移到最前面
读者会问“这会影响我吗?”条目描述了机制,而非影响改为先说明影响,并补充受影响的用户范围
条目与代码矛盾轻信了拉取请求标题对照差异重新核查;标题往往言过其实
两个版本使用了不同的时态没有记录约定修正当前版本,并在记忆中记录约定
审核者批准了错误条目审核时只读了文字,没有看差异对照差异逐句审核
翻译后的说明被拒绝或截断先写限制最宽松的平台先写限制最严格的平台,再扩展;参见非 Git 平台
每项变更都要发布公告没有分级步骤先分级,再分配发布平台

衡量指标

如果各发布平台已配置埋点,请按版本跟踪:

  • 效率,优先跟踪:支持量 > 破坏性变更条目点击率 > 版本页面浏览量 > 升级耗时 == 审核评论数

  • 标记为与该版本相关的支持请求和问题数量。 除了你们已有的分流工作外,这几乎不增加成本,而且几天内就能看到变化——发布后立即激增,通常意味着行为变更没有充分说明,而非版本本身有问题。

  • 从破坏性变更条目到迁移指南的点击率。 标记链接只需一小时,而这是唯一能说明该条目是否发挥作用的指标。

  • 版本页面浏览量与该版本的下载量或安装量对比。 在已配置埋点的平台上汇总数据需要一小时,但浏览量和安装量回答的是不同问题,两者的比率也容易波动。

  • 升级耗时——版本发布后第 7、30 和 90 天的在用版本分布——以及每个版本的审核评论数,如果说明需要经过审核,这两项都排在末位:每项都要等一个季度才有意义,而且各自都需要你可能尚未具备的流程(前者需要遥测数据,后者需要固定的审核步骤)。Tom Johnson 公开记录了让 Agent 执行这项任务的情况:每个版本的评论数从 15-20 条降至大约十几轮迭代后的 3-5 条——这是一条收敛曲线,不是需要立即达到的目标。

这种排序让升级耗时排不上优先级:它是唯一能衡量更新说明是否推动了用户升级的指标,但需要一个季度和遥测数据,因此性价比总是最低。若版本包含破坏性变更,且你需要在移除旧版本前知道还有哪些用户在使用旧版本,就应将它提升到所有指标之上。

绝不要根据变更日志声称采用率、留存率或收入受到影响。唯一已发表的结果证据是相关性:在 2,232 个应用的 69,851 次发布中,Google Play 上较长的版本说明与较高的平均评分相关(Yang 等人,Empirical Software Engineering 27:55,2022),但这一结果受到发布频率和应用成熟度的干扰。

Linear 因坚持撰写变更日志而获得的回报(招聘、投资者信心、早期采用者信任)广为引用,但这些说法来自公司自身,且没有量化。引用时只能说这是已有记录的做法,绝不能当作投资回报率的证明——夸大因果归因会损害你在这个受众群体中的可信度。

评论

支持 Markdown