Barrier 项目的 towncrier 发布说明工作流:用 newsfragments 管理变更并自动生成 Release Notes
2026/9/19 10:13:54 网站建设 项目流程

Barrier 项目的 towncrier 发布说明工作流:用 newsfragments 管理变更并自动生成 Release Notes

【免费下载链接】barrierOpen-source KVM software项目地址: https://gitcode.com/gh_mirrors/ba/barrier

开源 KVM 软件 Barrier 使用 towncrier 为核心,结合仓库中的 towncrier.toml、doc/release_notes/index.template.jinja、doc/release_notes/index.md 与 RELEASING.md,完整讲解 newsfragments 的目录约定、文件命名规范、支持的变更类型、配置原理以及它与 Barrier 发布流程的衔接,帮助你在提交用户可见变更时正确书写发布说明片段,并理解最终 Release Notes 是如何生成的。

newsfragments 目录在 Barrier 项目中的角色

在 Barrier 仓库根目录下有一个专门目录 doc/newsfragments/,它的定位是"发布说明片段(release note fragments)"的存放地。这些片段由 towncrier 工具统一收集处理:

  • 每当你做出一个**用户可见(user-visible)**的变更(例如新增功能、修复缺陷、加固安全、改进文档或移除功能),就在该目录中创建一个文件;
  • 该文件会在下一个版本发布时被 towncrier 自动并入发布说明文档;
  • 目录中现存的实际片段(如1260_macos-launchinfo.bugfixjapanese-translation.bugfixfix-wrong-encoding-for-text-copied-between-linux-and-windows.bugfix等)正是这种工作流的真实产物,是书写新片段时最直接的范例。

这种"变更即片段"的模式让贡献者无需在开发时就去手工维护一份长 changelog,而是由仓库在发布节点统一收口,避免合并冲突与遗漏。

文件扩展名决定变更类型

根据 doc/newsfragments/README.md,newsfragments 目录中每个文件的**扩展名(file extension)**直接指定了该变更的类型。当前支持以下五种:

扩展名含义发布说明中的归类名称(见 towncrier.toml)
.feature一项新功能Features
.bugfix一个缺陷修复Bug fixes
.security一个安全问题修复Security fixes
.doc文档改进Improved Documentation
.removal功能的弃用或移除Deprecations and Removals

扩展名的语义在 towncrier.toml 中被完整映射为发布说明中的章节。例如[[tool.towncrier.type]]中定义了directory = "feature"name = "Features"showcontent = true,而security类型则是name = "Security fixes"showcontent = false——这意味着安全类变更在生成时只列出 issue 编号,不渲染具体描述文本。目录中还实际存在未出现在 README 列表里的.doc.bugfix等类型片段,扩展名体系与配置文件一一对应。

五种变更类型与仓库中的真实范例

要理解每种类型的写法,直接查看 doc/newsfragments/ 目录中已有的文件最直观:

.feature:新功能

Feature 片段用于描述新增的用户能力。在 doc/release_notes/index.md 的 2.4.0 章节中可以看到这类片段的最终渲染形态,例如:

  • Added--drop-targetoption that improves drag and drop support on Windows when Barrier is being run as a portable app.
  • The--enable-cryptocommand line option has been made the default … A new--disable-cryptocommand line option has been added to explicitly disable encryption.
  • Added support for randomart images for easier comparison of SSL certificate fingerprints. The algorithm is identical to what OpenSSH uses.
  • Added--profile-diroption that allows to select custom profile directory.

这些内容在发布时以-列表项逐条呈现,表明 feature 片段的写作应以"新增了什么、为什么、如何使用"为要点。

.bugfix:缺陷修复

bugfix是仓库中现存最多的片段类型。例如 1260_macos-launchinfo.bugfix:

Corrected macOS packaging to provide a better error message when a user attempts to launch Barrier on an incompatible macOS version.

又如 fix-wrong-encoding-for-text-copied-between-linux-and-windows.bugfix:

Fix wrong encoding for text copied between Linux and Windows.

以及 restore-dpiawareness.bugfix:

Fixed a regression in 2.4.0 that caused Barrier to not support scaling other than 100%.

从这些范例可以看出,bugfix 片段应写明"修复了什么、影响哪个平台/场景、对应哪个 issue 编号";涉及回归的还应点明引入问题的版本,方便用户判断是否需要升级。

.security:安全修复

安全片段默认不展示正文(showcontent = false),在 doc/release_notes/index.md 的 2.4.0 章节中,安全修复(如客户端身份校验 CVE-2021-42072/CVE-2021-42073、SHA256 指纹等)以较长的描述性文字与 CVE 编号列出。可见安全修复属于最高优先级变更,写作时应讲清漏洞影响面、修复方式与升级/兼容注意事项。

.doc:文档改进

1260_update-faqs.doc 是现存范例:

Updated FAQs in project README.md with more detail on OS support and links to issues for infrequent users.

而 linux-drag-drop-faq.doc 则更简短:

Fixed FAQ link to Linux drag and drop issue.

这说明.doc片段既可以描述一次实质性的文档增补,也可以仅仅记录一个链接修正,核心是让用户在 changelog 中感知到文档层面的变化。

.removal:弃用与移除

当前仓库中暂无.removal实例,但结合 towncrier 配置可知它会被归入 "Deprecations and Removals" 章节并展示正文。从 Barrier 的演进历史(如默认启用--enable-crypto、以--disable-crypto显式关闭加密)可以看出,涉及命令行行为默认值变更、旧能力下线时,正是该类型片段的应用场景。

towncrier.toml:仓库中的发布说明配置

Barrier 将 towncrier 的完整配置固化在仓库根目录的 towncrier.toml 中,它把 newsfragments 与发布说明文档"粘合"在一起:

[tool.towncrier] package = "" directory = "doc/newsfragments" filename = "doc/release_notes/index.md" template = "doc/release_notes/index.template.jinja" title_format = "\nBarrier `{version}` ( `{project_date}` )\n================================\n" start_string = "[comment]: <> (towncrier release notes start)" [[tool.towncrier.section]] path = "" [[tool.towncrier.type]] directory = "security" name = "Security fixes" showcontent = false [[tool.towncrier.type]] directory = "feature" name = "Features" showcontent = true [[tool.towncrier.type]] directory = "bugfix" name = "Bug fixes" showcontent = true [[tool.towncrier.type]] directory = "doc" name = "Improved Documentation" showcontent = true [[tool.towncrier.type]] directory = "removal" name = "Deprecations and Removals" showcontent = true [[tool.towncrier.type]] directory = "misc" name = "Miscellaneous" showcontent = false

关键配置项的语义如下:

  • directory:片段来源目录,即doc/newsfragments
  • filename:发布说明的写入目标,即 doc/release_notes/index.md;
  • template:生成发布说明所用的 Jinja2 模板 doc/release_notes/index.template.jinja;
  • title_format:每次发布生成的主标题格式,包含{version}{project_date}占位符;
  • start_string:发布说明文档中的锚点标记,towncrier 会将新内容插入到该标记之后([comment]: <> (towncrier release notes start)同时出现在 doc/release_notes/index.md 的第 4 行,是生成结果与配置互相印证的位置);
  • type 段:每一类扩展名对应的目录名、章节显示名,以及showcontent(是否展示片段正文)。

值得注意的是配置中还定义了misc类型(Miscellaneous,showcontent = false),但 newsfragments README 的五类列表中并未提及它——这暗示misc属于维护者可用的扩展类型,印证了配置与实际约定之间存在弹性空间。

Jinja 模板:Release Notes 是如何渲染的

towncrier 并非简单地把片段拼接进文档,而是通过 doc/release_notes/index.template.jinja 模板控制最终排版。模板核心逻辑是:

  1. sections遍历所有变更分组,为每个分组生成标题与下划线分隔线;
  2. 对每个分组,遍历配置中定义的definitions(即 towncrier.toml 里的 type 定义),只处理该分组实际存在的category
  3. showcontent = true的类型,逐条渲染为- <文本>列表项;对showcontent = false的类型(如 security、misc),只渲染通过逗号连接的条目集合;
  4. 当某个分组或分类没有任何条目时,输出占位文案 "No significant changes."。

这条模板链路意味着:newsfragments 中的正文文本(去除文件名)就是最终渲染进 Release Notes 的列表项文本,因此片段正文必须自含完整语义、可独立阅读。对照 doc/release_notes/index.md 中 Barrier 2.4.0 的实际排版("Security fixes" / "Bug fixes" / "Features" 三节,各节内以-列表呈现),可以直观看到模板输出与配置定义的对应关系。

与发布流程的集成:RELEASING.md 中的使用方式

newsfragments 只是发布流程的前半段,真正触发收集动作的是维护者的发布脚本。在 RELEASING.md 的 "Step 2: Release notes PR" 中给出了唯一一条核心命令:

export VERSION=X.Y.Z towncrier --version ${VERSION} --date `date -u +%F`

该命令会读取 towncrier.toml 的配置,把 doc/newsfragments/ 中的全部片段按类型归类,渲染进 doc/release_notes/index.md,随后维护者提交这批收集后的发布说明,并在后续步骤中同步更新 Build.properties(当前版本号为BARRIER_VERSION_MAJOR = 2MINOR = 4PATCH = 0STAGE = release)等版本文件。

RELEASING.md 还特别提醒了一个实践要点:

Certain file names are not properly supported by thetowncriertool and it ignores them. Checknewsfragmentsdirectory for any forgotten release notes.

也就是说,towncrier 对某些文件名(如以.md、特殊字符开头或不遵循编号.类型命名习惯的文件)会静默忽略。发布前需要人工复查 newsfragments 目录,确认没有遗漏未被收集的片段——这正是目录内保留README.md文档文件也不会被误收的原因(README.md 扩展名为.md,不在五类类型之列)。

实操指南:如何为一次用户可见变更添加 newsfragment

结合上述约定,在 Barrier 中为一次变更书写发布说明的完整步骤如下:

  1. 判断是否需要片段:只有影响用户(新增功能、修 bug、修安全、改文档、移除/弃用功能)的变更需要;纯内部重构、CI 调整等可不必添加。
  2. 命名文件:建议按"变更主题或 issue 编号 + 类型扩展名"命名,仓库现有范例包括:
    • 1260_macos-launchinfo.bugfix(macOS 打包错误提示修复)
    • 1260_update-faqs.doc(FAQ 文档更新)
    • fix-wrong-encoding-for-text-copied-between-linux-and-windows.bugfix(Linux/Windows 间剪贴板文本编码修复)
    • japanese-translation.bugfix(日文翻译更新)
    • linux-drag-drop-faq.doc(FAQ 链接修正)
    • restore-dpiawareness.bugfix(2.4.0 回归修复)
  3. 书写正文:正文即最终 Release Notes 中的列表项文本,应自含语义。可参照 fix-wrong-encoding-for-text-copied-between-linux-and-windows.bugfix 的写法——一句话说明问题与影响;涉及已知 issue 时可在正文中标注对应编号。
  4. 提交并等待收集:片段随 PR 合入仓库,无需手动修改 doc/release_notes/index.md;它会在维护者执行towncrier --version ${VERSION} --date ...时被自动并入下一版发布说明。
  5. 发布前复查:确认文件名符合命名习惯,避免因 towncrier 不支持的文件名而被静默忽略。

小结

Barrier 的 newsfragments 工作流是一套轻量、可自动化的发布说明管理体系:贡献者以"扩展名即类型"的方式在 doc/newsfragments/ 中沉淀每一次用户可见变更,towncrier.toml 定义类型与章节的映射,doc/release_notes/index.template.jinja 负责渲染,最终由 RELEASING.md 中的towncrier命令在发布节点统一写入 doc/release_notes/index.md。理解这套约定后,无论是提交贡献还是参与 Barrier 的发布维护,你都能准确书写、定位并生成高质量的 Release Notes。

【免费下载链接】barrierOpen-source KVM software项目地址: https://gitcode.com/gh_mirrors/ba/barrier

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

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

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

立即咨询