进阶 约 20 分钟 2026-10-17 04:50:40 · 22 阅读

rea-changelog-update 技能实操:把 Git 历史写成有据可查的 Release Notes

一个反向的技能:管发布说明,不管代码

morluto/rea 仓库里有两个 Agent Skill(产品档案)。第一个 reverse-engineer-anything 教 AI 怎么逆向闭源软件;第二个 rea-changelog-update 干的事乍看一点也不性感:把机器人生成的 changelog 草稿,重写成一份人类愿意读完的发布说明,并且每一位贡献者的致谢都查有实据。本篇拆这个技能——它其实是「AI 参与开源协作后,署名与信任怎么管理」的一个相当超前的样本。

技能文件位于 .agents/skills/rea-changelog-update/SKILL.md(7.6KB),定位一句话就能说清,原文是:这个技能准备说明(this skill prepares notes),它不授权合并、打标或发布。发布权限归 docs/releasing.md 管的既有流程,技能只负责把「这个版本里到底发生了什么、该谢谁」整理清楚。

为什么需要它:bot 草稿解决不了的两个问题

REA 用 Release Please 自动维护 changelog,机器人草稿能把每个 PR 列出来,但有两个先天缺陷。第一,它只看主线:旁支提交、GitHub 没关联上的合并、issue 报告人的贡献都会漏。第二,它不懂取舍:哪些是用户真正需要知道的变化、哪些是内部清理,机器分不出来。

技能的解法是把写作前置成一次盘点。第一节「Inventory before prose」的字面纪律就是:先盘点,后动笔(inventory before prose)。核心命令两条:

node scripts/release-notes.mjs inventory \
  --repository morluto/rea --base rea-agents-PREVIOUS \
  --target FULL_BASE_BRANCH_SHA --version VERSION \
  --manifest /tmp/rea-VERSION.contributions.json
node scripts/release-notes.mjs record \
  --manifest /tmp/rea-VERSION.contributions.json \
  --summary \
  --output /tmp/rea-VERSION.record.md

盘点从 .release-please-manifest.json 选基线 tag(REA 的 tag 形如 rea-agents-VERSION),把发布 PR base 分支的精确 SHA 钉为编辑目标。这有两个讲究:版本号用提议值、含预发布后缀,不为了模仿别的项目的日历版本号去改 always-bump-minor 策略;范围用 SHA 钉死,后面谁再往分支推提交都不影响本次编辑的口径。

四步流程全景

把三节技能与 docs/releasing.md 的流程合在一起看,整条链路是四步:

四步流程图

从 Git 历史到可发布 Release Notes 的四步,整理自技能与 releasing.md

盘点阶段有几条防翻车设计直接写在原文里:网络错误会停止生成,恢复后必须换新输出文件重跑,已有输出文件永不覆写(Existing output files are never overwritten);GitHub 关联是分页拉的,漏页就漏人。身份解析不出来怎么办?原文的表态非常克制——未解析的提交身份以 name/email 加 user: null 保留,报告保留未知项。它接着写了一句所有写发布说明的人都该抄走的话:

never guess a handle or thank the merger as a substitute

不猜 handle,也不拿「谢合并人」凑数。清单还明确了自己的性质:这是一份经过审阅的元数据快照(a reviewed metadata snapshot),不是「人类确实写了这个补丁」的独立证明。

真实清单长什么样

这套机制不是纸面设计。REA 仓库 docs/releases/ 下存着真实发布清单,6.5.0 版那份有 1,497,855 字节。结构如下:

contributions.json 真实结构

6.5.0.contributions.json 的顶层字段与实测内容(经 git blobs 接口读取)

893 条提交、529 个 PR,每条提交带 sha/subject/body/parents/authors/pullRequests 全量字段。两个真实样本值得细看:首条提交的 body 里就带着 Co-Authored-By: Claude Opus 5.5 的 trailer——AI 共同作者在这个仓库是日常;而提交 58e91e14 的作者数组里,第二个身份「Zayd <iam@zayd.wtf>」的 user 字段就是 null,同一个人两条身份,一条解析到了 GitHub 账号,一条没有。清单不猜、不合并、原样保留。

写作规范:为用户写,把致谢留住

第二节「Write for users and retain credit」规定重写只动 CHANGELOG.md 里最新的 ## [VERSION] 段,保留版本/日期/链接标题,条目单行。四个子栏目各有分工:Highlights 放定义本版的用户可感成果(小版本不设配额);Changes 放能力与行为变化;Fixes 放可靠性、正确性、兼容性与安全修复;BREAKING CHANGES 保留迁移说明与原始 PR/commit 引用。内部清理、测试、CI、例行文档只进溯源文件,不上公开 notes。

致谢规则是这一节的精华,单独成图:

致谢规则表

谁上墙、谁排除、怎么避免重复——整理自技能原文

最容易被忽视的是排除条款:GitHub bot 与已知 agent 账号不上墙。原文点名 Anthropic、Cursor、Codex 的 co-author trailer 会解析成 @claude、@cursoragent、@codex,GitHub type 都是 User——单看类型根本认不出是 AI,全靠这份清单拦。排除的同时保留它们的元数据,库存里如实记录,只是公开致谢不提。还有一条维护者特例:应 REA 维护者要求,公开 notes 省略 @morluto 的自我致谢,但清单里保留其作者身份。

写作纪律里最硬的一条:不许手工编辑生成的致谢来让校验通过(Do not hand-edit generated credits to make validation pass)。校验不过说明盘点和文字对不上,该修的是数据,不是改字。

收尾:先上锁,再动笔

第三节「Finalize with Release Please」防的是机器人覆盖:编辑线上发布 PR 之前,先给它加 rea:release-notes-finalized 标签,普通的主干推送提案会尊重这个标签,不再覆写编辑过的说明。注意原文的精确表述——这标签不是 Release Please 自带的 snooze 机制,是仓库自己的工作流守卫;它锁的是 bot 刷新,不锁 main 分支,目标之后主干有新提交就得重新盘点。

定稿的清单要存到发布分支的 docs/releases/VERSION.contributions.json——是持久公开的发布溯源,不是临时计划文件。然后跑两个命令:

node scripts/release-notes.mjs check \
  --manifest docs/releases/VERSION.contributions.json
node scripts/release-notes.mjs render \
  --manifest docs/releases/VERSION.contributions.json \
  --output /tmp/rea-VERSION.notes.md

校验器支持内联 PR 正文(含周边元数据),上限 GitHub 的 65,536 字符——超长直接失败,而不是截断致谢。渲染结果更新到 PR 正文时用 gh pr edit --body-file 传文件,且只改 CHANGELOG.md 不够,Release Please 的发布正文不会跟着变。最后重新拉取 PR 正文到文件,跑 check --pr-body FILE 复核,确认完整 diff、等 CI 通过。发布前的检查会再验一次正文。

这套流程对仓库外的人也有直接用处:任何用 Release Please、changesets 或同类 bot 管发布的项目,都可以照搬「盘点先于写作、身份未知就保留未知、编辑前先上锁」这三条。技能原文是写给 AI 的作业指导,但每一条都是人类维护者也该有的习惯。

边界与适用范围

技能自己的定权边界值得重申:它准备说明,不授权合并、打标或发布;本地准备和校验可以独立进行,动线上 PR 需要该 PR 更新的授权。清单是审阅过的快照,不是签名的证明——离线校验器验证的是本地范围覆盖和致谢一致性,不独立验证 GitHub 的作者归属。被 revert 的已盘点工作不得宣称仍在发布;模拟 provider 检查与真实 provider 验证必须区分表述。既有发布若没有贡献清单,走原有发布路径即可,官方明确说永远不要为修发布文案而重新打 tag 或重发包(Never retag or republish a package to correct release prose)。

来源与延伸

本文依据 morluto/rea 仓库 main 分支的 .agents/skills/rea-changelog-update/SKILL.md 全文、docs/releasing.md 及 docs/releases/6.5.0.contributions.json 真实文件整理,命令与引文出自原文。相关阅读可看本站对 reverse-engineer-anything 技能的姊妹篇。

评论 (0)