mcpField
W
writing-release-notes

writing-release-notes

github.com/osmontero开发1664 次安装今天更新
代码仓库

关于 writing-release-notes

面向需要决定是否升级的读者,指导编写软件发布说明。它将代码变更转化为读者可见的影响,区分发布说明、变更日志与升级指南,并突出不兼容变更及所需操作。

主要功能

  1. 01以读者影响描述变更
  2. 02区分发布说明、变更日志和指南
  3. 03按类别整理变更
  4. 04突出不兼容变更和必要操作
  5. 05采用带版本和日期的格式

适用场景

  1. 01起草软件版本发布说明
  2. 02解释 API 不兼容变更
  3. 03将提交记录转化为读者影响

安装

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

$npx skills add https://github.com/osmontero/opencode-skills --skill writing-release-notes

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

详细介绍

编写发行说明

概述

默认的失败做法是直接粘贴提交日志。它准确、完整,却毫无用处——因为它描述的是代码发生了什么变化,而读者需要知道这对自己意味着什么。

**核心原则:**读者要做两个决定——要不要升级,以及升级后会有什么问题。每一行要么服务于其中一个决定,要么就是噪音。

**相关技能:**面向组织内部受众的 writing-internal-comms,用于编写条目所链接文档的 coauthoring-docs,以及当发行版本包含破坏性变更时使用的 evolving-apis-and-schemas。

铁律

EVERY ENTRY STATES WHAT CHANGED FOR THE READER, NOT WHAT CHANGED IN THE CODE

Refactored the auth middleware to use the new token store 是提交消息。Sessions now survive a server restart 是发行说明。同一个变更,只有后者回答了读者关心的问题。

如果某个条目没有读者可感知的影响,就完全不要将其写入发行说明。提交日志已经存在,点一下就能查看。

第 1 步:明确你在写哪种文档

有三种不同的文档都被称为“发行说明”。把它们混为一谈,对谁都没有好处。

文档受众形式
CHANGELOG追溯历史的所有人简洁、累积,每项变更占一行,按类型分组,最新版本在前
发行说明正在决定是否立即升级的人先列重点,再列完整清单。重点内容使用散文形式
升级指南已经决定升级的人仅包含破坏性变更,每项都列出变更前后的情况和操作步骤

小型库只需要 CHANGELOG。包含破坏性变更的发行版本需要这三种文档,发行说明应链接到升级指南,而不是将其内容直接写入其中。

第 2 步:收集,然后转换表述

git log --oneline v1.4.0..HEAD
git log v1.4.0..HEAD --format='%s%n%b' | grep -iE 'BREAKING|deprecat'
git diff v1.4.0..HEAD --stat -- '*.proto' 'migrations/' 'openapi.yaml'

最后一条命令最重要:它能找出提交主题通常不会提到的接口变更。

然后用一个问题来转换每个候选条目的表述:**读者现在能做什么以前做不到的事,或者现在有什么行为会发生变化?**如果答不上来,就删掉它。

第 3 步:分类

按以下六类顺序排列,空类别则省略。破坏性变更始终放在最前面,无论相较于其他变更它们看起来有多微小。

类别包含内容
破坏性变更需要读者更改代码、配置或数据的任何内容
新增新功能
变更发生变化但保持兼容的现有行为
弃用仍可使用,但将被移除——注明移除版本
移除已移除且此前已弃用的内容
修复Bug,按读者遇到的症状来描述
安全始终单独成节,始终靠近顶部,绝不能埋在“修复”中

**弃用信息需要注明日期或版本,不能只写“很快”。**没有移除目标版本的弃用通知会被忽视,之后移除时就会让人措手不及。

**安全条目应说明严重程度,以及是否需要采取行动。**如果已分配 CVE,请将其列出。如果利用漏洞需要特定配置,请说明是哪种配置——读者需要知道自己是否受到影响,而不只是知道应该升级。

第 4 步:编写条目

每条都要说明:变更内容、影响对象,以及详细信息链接。在 CHANGELOG 中写一行;主要功能则写两三句话。

不要这样写应这样写
Fix null pointer in handler修复了上传无扩展名文件时发生的崩溃
Bump deps已更新至 OpenSSL 3.2.1,解决了 CVE-2024-XXXX(无需采取任何操作)
Add caching layer对于包含 10k+ 份文档的工作区,仪表板查询现在可在 200ms 内返回
Refactor config parsing(省略——对读者不可见的效果)
Change API response破坏性变更: GET /documents 现在返回 items 而非 results。升级前请更新客户端;详见升级指南
Improve performance导入 100MB CSV 的速度提升约 4 倍(参考数据集上从约 90s 降至约 22s)

最能体现质量的规则:

  • 先说效果,不要先说实现机制。 读者关心的是是否需要重启,而不是令牌存储。
  • 给出量化数据。 “更快”无法验证;“导入 100MB 数据从 90s 降至 22s”是可核实的说法,也更有说服力。
  • 修复错误时说明症状。 读者会用自己遇到问题时的说法,在发行说明中查找相关信息。
  • 说明是否需要采取操作。 大多数条目都不需要;需要操作的条目必须格外醒目。
  • 提供链接,不要在条目中塞入细节。 迁移步骤、基准测试和 API 详情应放在链接的文档中。
  • 使用过去时、主动语态,不要营销腔。 “会话现在在重启后仍会保留。”而不是“我们很高兴地宣布,焕然一新的会话体验震撼登场。”

第 5 步:为破坏性变更提供迁移步骤

如果条目只说有变更造成了破坏,却不说明该怎么做,那这条目就不完整。

### Breaking

**`GET /documents` renames `results` to `items`**

The list envelope now matches every other collection endpoint.

Before:
```json
{ "results": [...], "total": 42 }
```

After:
```json
{ "items": [...], "total": 42 }
```

**Migration:** update clients to read `items`. The old field is still present
in 2.x and will be removed in 3.0. Clients reading `results` continue to work
until then, with a `Deprecation` header on every response.

最理想的情况是,迁移操作可以用一条命令完成——npx my-tool codemod v3——并且明确写出这条命令。其次是提供差异。最差但还能接受的情况是用文字说明。“用户应更新其集成”不属于以上任何一种。

格式

## [2.3.0] — 2026-03-14

### Security
- Fixed a path traversal in the archive importer that allowed writing outside
  the workspace directory (CVE-2026-XXXXX, high). Affects 2.0–2.2 with imports
  enabled. **Upgrade recommended.**

### Breaking
- `GET /documents` returns `items` instead of `results` ([upgrade guide](./UPGRADE.md#23))

### Added
- Full-text search across document bodies, with `search:` filters
- `--dry-run` on `import`, printing what would change without writing

### Changed
- Dashboard queries return in under 200ms for workspaces above 10k documents
- Default session lifetime is now 30 days (was 7); override with `SESSION_TTL`

### Deprecated
- `results` in list responses — removed in 3.0
- `POST /documents/bulk` — use `POST /documents` with an array; removed in 3.0

### Fixed
- Uploading a file with no extension no longer crashes the worker
- Timestamps in exports use the workspace timezone rather than UTC

**Full diff:** [v2.2.1...v2.3.0](https://github.com/org/repo/compare/v2.2.1...v2.3.0)

日期使用 ISO 格式,版本号放在方括号中——这种组合能让 CHANGELOG 被工具以固定方式解析,下游工具也依赖这一点。

版本信号

版本号本身也是信息的一部分。按照 semver,破坏性变更意味着主版本号递增——在次版本中发布破坏性变更,比延迟发布、按规范处理更损害信任。如果项目尚未达到 1.0,或采用其他版本方案,请在 CHANGELOG 顶部说明,让读者能够正确判断。

常见错误

直接粘贴提交日志。 内容详尽、按时间排序,却难以阅读,还会把内部命名暴露给根本不知道 ToolGateway 是什么的人。

把破坏性变更埋在列表中间,理由是它只是一个很小的差异。差异大小与对读者的影响无关。

遗漏没人报告的修复。 有人遇到了问题,却从未提交报告。发行说明能让他们知道问题已修复。

“修复了各种错误并进行了改进。” 这句话毫无信息量,读起来就像没人愿意认真编写文档的发行说明。

使用内部术语。 模块名称、工单编号和服务名称,对团队以外的人毫无意义。

逐条列出依赖项升级。 应将它们合并列出,除非其中某项涉及安全修复或行为变更——这种情况应单独列出。

没有日期。 读者会根据日期判断自己正在运行哪个版本。

发布标签时凭记忆编写。 应在进行变更时就添加条目,此时对读者可见的效果仍然一目了然。

评论

支持 Markdown