- 开发工具
- 桌面应用
【免费下载链接】desktop
Fork of GitHub Desktop to support various Linux distributions
本篇技术指南基于 GitHub Desktop 仓库的docs/process/writing-release-notes.md,系统讲解该项目的发布说明(Release Notes)写作规范,包括条目结构、五种标签的语义与排序、面向用户影响的写作原则,以及yarn draft-release草稿生成工具背后完整的自动化解析链路。读完本文,你将掌握一套可复用的发布说明写作与校验工作流:既能写出符合社区规范的条目,也能理解草稿是如何从 PR 合并记录与changelog.json中自动生成的。
发布说明的构成:Anatomy of a Release Note
每一条发布说明由三到四个部分组成,其标准格式如下:
[Tag] Description of work or change - #{issue_number}- Tag(标签):用于归类的标记,取值来自固定的五类,详见下文「标签体系」一节。
- Description(描述):对本次改动的一句话说明,必须遵循「面向用户」的写作原则。
- Issue/PR 编号:以
- #编号形式附在描述之后,用于追溯对应的 issue 或 PR。 - 贡献者致谢(可选,第四部分):当改动由外部贡献者完成时,追加一段致谢:
[Tag] Description of work or change - #{issue_number}. Thanks @{contributor_username}!这一「感谢外部贡献者」的约定不仅在写作规范中存在,也被工具链实际解析:在 script/changelog/parser.ts 的getChangelogEntry中,会检查 PR 所属仓库所有者是否等于官方账号desktop,若不是则自动追加. Thanks @{owner}!后缀;script/draft-release/run.ts 的辅助脚本 script/generate-release-notes.ts 也使用正则\[(.*)\](https://link.gitcode.com/i/d9679a7f8bd70fcd071f3f59f7697654)- (.*)\. Thanks (.*)!来识别并提取带贡献者的条目。
写作风格指南
规范文档用较大的篇幅约束描述文案本身,这些约束大致可归纳为四条原则。
只写面向用户的变化
不收录不影响用户使用体验的改动。例如,修复 CI 配置(如 Appveyor)、升级 Electron 这类纯内部工程改动,通常不会出现在发布说明中。
安全漏洞修复属于例外:即使是内部层面的修复,只要是安全漏洞(尤其是高关注度漏洞)就会收录,且措辞通常比较宽泛、不附带具体 CVE 编号。原文档给出的例子:
[Fixed] Update embedded Git to address security vulnerability - #4791描述用户影响而非技术过程
条目应说明「这项改动如何改变用户的工作流或体验、帮用户做到了什么」,而不是堆砌技术实现细节。原文档中的对比示例:
[Fixed] Keep PR badge on top of progress bar - #8622 ✅ 推荐 [Fixed] Increase z-index of the progress bar PR badge - #8622 ❌ 不推荐前者描述的是用户可感知的结果(PR 徽标保持在进度条上方),后者则是在复述 CSS 实现(提升 z-index),用户并不关心也不理解。
使用现在时态
除非会显著损害清晰度,否则统一使用现在时。对比:
[Added] Add external editor integration for Xcode - #8255 ✅ 推荐 [Added] Adding external editor integration for Xcode - #8255 ❌ 不推荐描述以动词原形开头(Add / Fix / Improve / Remove),保持简洁直接。
措辞:描述独立于标签可读
虽然把标签当作描述的第一个词很诱人,但规范要求描述本身脱离标签后依然通顺、自成一句。对比:
[Improved] Always fast forward recent branches after fetch - #7761 ✅ 推荐 [Improved] Branch fast-forwarding after fetch - #7761 ❌ 不推荐去掉[Improved]后,Always fast forward recent branches after fetch依然是一句完整的话,而Branch fast-forwarding after fetch只是短语,可读性较差。
标签体系与排序
项目使用五个标签来组织发布说明,且在最终展示时严格按以下顺序排序:
[New][Added][Fixed][Improved][Removed]
(同一标签组内各条目的顺序则相对随意。)这一排序同样反映在自动化脚本中:script/generate-release-notes.ts 的generateDraftReleaseNotes按 New → Added → Fixed → Improved → Removed 的顺序渲染各个分组标题。
[New]
通常保留给「最闪亮的新功能」,条目本身可能很短、层级很高,却浓缩了大量开发工作。写作时一个自查技巧是:检查[New]条目是否与该版本对外宣传的「亮点 / 最重要的新特性」一一对应。
[Added]
本质上是「小一号的 [New]」:功能更小,或者不是本版本重点宣传的内容。编辑器与终端集成类的新功能经常使用[Added]——例如 changelog 中可见的[Added] Add Cursor support on macOS - #17462、[Added] Add JetBrains RustRover support - #18802等条目(见 changelog.json)。
[Fixed]
发布说明的中流砥柱,表示「之前坏了,现在不坏了」。注意措辞应描述做了什么、行为如何改善,而不是描述之前错在哪里。原文档示例:
[Fixed] Keep conflicting untracked files when bringing changes to another branch - #8084 ✅ [Fixed] Conflicting untracked files are lost when bringing changes to another branch - #8084 ❌[Improved]
介于 [Added] 与 [Fixed] 之间,表示「把已有功能做得更好」,但功能此前并非损坏。与 [Added] 的区分规则是:新增一段端到端的小功能用 [Added];对已有功能某个部分的修改用 [Improved]。例如 changelog.json 中的[Improved] Allow resizing Branch and Push/Pull toolbar buttons - #4569 #17388即为典型的「增强既有功能」条目。
[Removed]
描述应用中不再可用的功能,使用频率较低。示例:
[Removed] Remove "Discard all changes" context menu item from Changes list - #7394关于标签的灵活性
文档明确提醒:这些标签并不是硬性、绝对的规则,需要结合具体情境运用判断力与细微差别(原文即注明「These aren't hard and fast rules or categories」)。
发布渠道与严谨程度
规范指出:生产版本(production)的发布说明比 beta 版本的更严谨。这一点在工具链中有直接对应:yarn draft-release支持production、beta、test三种渠道(见 script/draft-release/channel.ts),其中:
production:只会收集自上一个生产版本以来的条目,且拒绝基于 beta/test 版本起草生产发布(见 script/draft-release/version.ts);beta:从 git 历史中提取自上一个版本 tag 以来的合并 PR,再调用 GitHub API 解析成 changelog 格式;test:不为测试发布猜测发布说明,直接跳过收集阶段(见 script/draft-release/run.ts)。
从草稿到定稿:yarn draft-release自动化链路
规范文档指出,yarn draft-release是一个很好的起点,但不是最终版本。理解这条命令背后的自动化流程,有助于更准确地理解为什么草稿需要人工修订。
第一步:环境校验与渠道解析
入口脚本 script/draft-release/index.ts 首先通过gh auth status校验 GitHub CLI 是否已认证,未认证则提示先执行gh auth login并退出。随后 script/draft-release/run.ts 解析渠道参数(production/beta/test),并根据渠道从git tag中选取上一个版本(production/test 渠道排除 beta 版本,production/beta 渠道排除 test 版本),再调用getNextVersionNumber计算出下一个版本号并创建releases/<版本>分支。
第二步:按渠道收集条目
- production 渠道:调用
getChangelogEntriesSince(previousVersion)(见 script/changelog/parser.ts),从仓库根目录的 changelog.json 中收集所有版本号大于上一版本、且非-beta0的条目(beta0 是生产更新同步到 beta 渠道的约定占位,予以跳过)。 - beta 渠道:通过
git log ...<上一版本> --merges --grep="Merge pull request" --format=format:%s拉取合并提交标题(见 script/changelog/git.ts),随后逐条解析并调用 GitHub PR API 获取详情,最终转换成 changelog 条目格式。 - 另外,若传入
--pretext参数,还会读取 app/static/common/pretext-draft.md,将其包装成[Pretext] ...条目置于最前(见 script/draft-release/run.ts)。
第三步:PR 到条目的转换规则
script/changelog/parser.ts 定义了从 PR 信息生成 changelog 条目的核心逻辑,这正好印证了规范中「格式是[Tag] 描述 - #编号」的写法:
- PR 正文的
Notes:段优先:解析 PR body 中最后一行以Notes:开头的内容作为发布说明;若内容为no-notes,则明确表示该 PR 不需要发布说明;若完全没有Notes:段,则回退到自动生成; - 自动生成规则:类型占位为
???,描述取 PR 标题并首字母大写;若 PR body 中出现fixes/closes/resolves #编号之类的引用,则类型自动置为Fixed且编号取被修复的 issue 编号,否则编号取 PR 自身编号; - 外部贡献者:PR 来源仓库所有者不是
desktop时,自动追加. Thanks @{owner}!致谢。
上述规则都有对应的单元测试验证,见 script/changelog/test/parser-test.ts,例如「多个 Notes 取最后一个」「Notes: no-notes返回 null」「Fixes #2314被识别为 issue 引用」等场景。
第四步:写入 changelog.json 并给出后续步骤
草稿条目会被写入 changelog.json 的releases对象(新版本号对应的数组),随后脚本打印后续操作清单,其中明确包含一条指向本规范文档的提示——「根据写作发布说明的规范修订草稿」,随后用yarn draft-release:format进行格式检查(lint)、提交到 release 分支并推送。可见:自动化工具负责「收集素材」,而是否符合 docs/process/writing-release-notes.md 的写作规范,仍需人工把关。
changelog.json 的数据结构与校验
草稿与最终定稿都沉淀在仓库根目录的 changelog.json 中,其结构为:
{ "releases": { "3.4.9": [ "[Fixed] App no longer crash for first time users going through the welcome flow and attempting to sign in more than once - #19442", "[Improved] Allow resizing Branch and Push/Pull toolbar buttons - #4569 #17388. Thanks @jpedroso!", "[Removed] Remove ruleset bypass confirmation modal - #19281. Thanks @lofcz!" ] } }注意几个值得借鉴的细节:
- 一个条目可引用多个编号:如
#4569 #17388,对应 PR 同时关闭/关联多个 issue 的情况; - 版本号格式:
主.次.补丁,可选-betaN或-testN后缀; - beta 与生产版本的条目存在重叠:beta 阶段的条目会逐步合并进后续生产版本,这是「beta 严谨度低于 production」的又一体现。
该文件由 script/validate-changelog.ts 负责校验:要求 JSON 可解析、只有releases一个顶层键、至少包含一个发布版本、版本号符合x.y.z(-betaN|-testN)?正则、且每个版本的改动均为字符串数组,校验通过后输出The changelog is totally fine。而 script/generate-release-notes.ts 则是在正式发布时,把 changelog 条目连同构建产物(3 种架构 × 3 种包格式 × 2 个文件 = 18个)一起渲染成最终的发布说明文件release_notes.txt。
写作自查清单
综合规范文档与工具链实现,撰写一条合格的发布说明可以按以下清单自查:
- 结构完整:
[Tag] 描述 - #编号,外部贡献者追加. Thanks @用户名!; - 面向用户:描述用户能感知的结果,不写内部实现(z-index、CI 配置等);
- 现在时:以 Add/Fix/Improve/Remove 原形动词开头;
- 脱离标签可读:去掉
[Tag]后描述仍是完整通顺的句子; - 标签准确:亮点大功能用
[New],小功能用[Added],修复用[Fixed],既有功能增强用[Improved],移除功能用[Removed]; - 排序正确:New → Added → Fixed → Improved → Removed;
- 无编号缺失:编号可追溯(issue 或 PR),并可被 script/changelog/parser.ts 的正则正确解析;
- 符合渠道要求:production 发布说明必须比 beta 更严谨,纯内部改动不收录(安全修复除外)。
遵循这套规范,既能保证发布说明对最终用户友好、可读、可追溯,也能确保yarn draft-release、changelog 校验与正式发布脚本整条自动化链路顺畅运转——这正是规范文档与工具链设计相辅相成的完整闭环。
- 开发工具
- 桌面应用
【免费下载链接】desktop
Fork of GitHub Desktop to support various Linux distributions
相关推荐
GitHub Desktop 发布说明编写指南:格式规范、写作原则与 changelog 自动化流程
GitHub Desktop 发布说明编写指南:格式规范、写作原则与 changelog 自动化流程 本文以 GitHub Desktop(仓库 gh_mirr
桌面应用版本控制开发工具Bazel 贡献者发布说明撰写指南:RELNOTES 标签规范与自动化生成流程
Bazel 贡献者发布说明撰写指南:RELNOTES 标签规范与自动化生成流程 Bazel 仓库要求每个可能影响用户的提交在 commit message 中携
构建工具LobeHub 版本发布工作流:Minor/Patch 双轨自动化与 GitHub Release 编写规范
LobeHub 版本发布工作流:Minor/Patch 双轨自动化与 GitHub Release 编写规范 本文以 LobeHub 仓库内的 version
人工智能AI 应用大模型AI Agent多智能体工具调用前端后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考