在中使用 rpmautospec Fedora Linux

使用 %autorelease 和 %autochangelog 标签可以简化包的维护,并使将包贡献给 Fedora 项目。 从最终用户的角度来看,这些 rpmautospec 标签不会在包中造成明显的差异。 截至 Fedora Linux 38 版本,包维护者应该使用这些新标签。

有关包历史的信息

发行版中的每个包都带有识别信息。 为了 example最新版本 Firefox 可以作为 firefox-110.0-3.fc38.x86_64。 这可以解压为:

  • 一个名字 (firefox),
  • 一个版本(110.0),
  • “发布标签”,由打包发布版本 + 分发标记 + 架构标签 (3.fc38.x86_64) 组成。

在现代实践中,名称和版本由上游项目直接提供,并明确标识构建的内容。 release 标签描述了下游发行版构建(where, which distro, build count)。 这听起来很自然,但过去打包者会根据一些相当复杂的规则将上游版本的一部分拆分到发布标签中。

软件包还在其变更日志中包含有用的信息。

继续 Firefox example:

$ rpm -q --changelog firefox-110.0-3.fc38.x86_64 | head -n5
* Tue Feb 14 2023 Martin Stránský <[email protected]>- 110.0-3
- Updated to 110.0 build 3

* Mon Feb 13 2023 Martin Stránský <[email protected]>- 110.0-2
- Added fix for orca

变更日志由包维护者创建。 它描述了与用户相关的包更改。 新的软件版本、修改的文件路径和重要的错误修复都是变更日志中会提到的例子。 打包脚本和其他清理中的空白更改是更改日志中不会提及的示例。 当一切顺利时,用户通常不会查看变更日志。 但是,当发现错误并且人们需要跟踪更改的内容、时间和原因时,更改日志很有用。

所有这些变更日志信息必须由维护者提供。 当维护者构建一个 rpm 包时,他们必须在包的规范文件的适当字段中提供此信息。

为了 example, 这 firefox.spec 可能看起来像这样:

Name: firefox
Version: 110.0
Release: 3%{dist}
...
%changelog
* Tue Feb 14 2023 Martin Stránský <[email protected]>- 110.0-3
- Updated to 110.0 build 3

* Mon Feb 13 2023 Martin Stránský <[email protected]>- 110.0-2
- Added fix for orca
...

这是传统的方式。 每次维护者进行新构建时,他们都会更新 Release 字段中的数字,并在 %changelog 部分添加相应的条目。 为了 example,对于 110.0-3.fc38 版本,Martin 会更改 Release: 2%{dist} → Release: 3%{dist} 并在 %changelog 下添加第一段。

包裹在 Fedora 使用 git 维护。 这意味着在对包进行更改并向更改日志添加一些文本后,维护者还会在 git 提交消息中写下更改的描述。 通常这与更改日志的文本完全相同。 为了 example,对于 110.0-3.fc38 构建,Martin 在 git 提交消息中写了“更新到最新的 110.0 上游构建”。 应该注意的是,git 中的每个提交还包含一个名称、作者的电子邮件地址和更改的时间戳。 如果这听起来有点重复,那是因为它确实如此。 值得庆幸的是,其中一些现在可以自动化。

rpm自动规格

rpmautospec 方法利用了 spec 文件保存在 git 存储库中这一事实:

Name: firefox
Version: 110.0
Release: %autorelease
...
%changelog
%autochangelog

Release 字段的目的是识别特定上游版本的发行版本号。 Release 字段应该设置为 %autorelease 并且永远不会再更改。 %autorelease 宏提供自上次更改 Version 字段的提交以来的提交计数。 这很漂亮。 每次打包者更改规范文件时,他们都必须提交以“保存”更改并进行构建,并且 %autorelease 中的数字将增加。 当 Version 改变时,autorelease number 重置为 1。

git commit 消息的目的是总结对存储库内容的更改。 %changelog 部分的目的是总结对包的更改。 %autochangelog 宏获取 git 提交消息、作者姓名和提交时间戳,并以适合 %changelog 部分的方式格式化它们。

如果 Martin 要进行另一个构建,假设添加了一个补丁,他将调整规范文件添加一个补丁行,并创建一个提交:

$ git commit -a -m 'Add patch to fix rhbz#1000002'

%autorelease 字段将自动增加一个,%autochangelog 文本现在将以:

* Thu Mar 23 2023 Martin Stránský <[email protected]>- 110.0-4
- Add patch to fix rhbz#1000002

新的工作流程有什么影响?

最容易考虑效果 对于用户: 不用找了. %autorelease 和 %autochangelog 在构建包之前被“真实”内容替换,用户下载的二进制包看起来完全一样。

对于打包者来说,忙活少了。 Release 字段是不变的,git commit 文本被重新用于变更日志。 我在这里忽略了细节,但是 git commit 文本可以包含未包含在 changelog 文本中的部分。 它甚至可以有完全从变更日志中删除的提交。

这种自动化也减少了一些错误的可能性。 为了 example:

  • 维护者进行了更改,但忘记修改 Release,并且构建失败,因为具有相同版本发布的先前构建已经存在。
  • 维护者进行了更改,但忘记在 %changelog 中描述它们,用户不知道更改了什么。
  • 维护者创建了一个变更日志条目,但写的是星期二而不是星期四,并且 rpm 抱怨日期无效。

另一方面,包装商必须更加自律。 git 提交消息中的文本最终对用户可见。 所以它必须相应地格式化。 git 中的每个提交都会增加发布标签中的数字。 变更日志现在在所有包中以相同的特定样式格式化。 可以说,这些并不是很大的限制,但需要对打包程序的习惯进行一些调整。

使用 rpmautospec 对外部贡献者有积极的影响。 在 Fedora,鼓励任何想要对包进行更改的人打开拉取请求。

不幸的是,对于触及规范文件的更改,使用传统的 Release 和 %changelog,我们遇到了一个难题。 如果贡献者不更新他们的提交,维护者必须在构建之前这样做,实际上贡献是不完整的。 如果贡献者确实更新了他们的提交,并且拉取请求没有立即合并,很可能在合并时
版本号将过时,%changelog 中的日期将是过去的,规范文件甚至可能已经包含具有较晚日期的条目,并且 git 将始终在 %changelog 部分显示合并冲突。

使用 rpmautospec,所有这些问题都会消失。 发布号是自动计算的。 变更日志中的日期源自补丁合并时的时间戳。 变更日志是从提交流中生成的,因此不会有冲突。

当维护者想要将提交复制(用 git 的说法是 cherry-pick)到另一个分支时,会出现此贡献者工作流程的特定变体。 为了 example,因为 F38 中必需的重要错误修复也需要在 F37 中应用,使用 rpmautospec 很可能可以应用提交,而无需对不同的打包分支进行任何更改。

总结

%autorelease 和 %autochangelog 已经有一段时间了,但现在已经达到了可以很好地用于常见维护模式和绝大多数包的水平; 即使还不支持一些复杂的极端情况。 和 Fedora 38、rpmautospec 现在是推荐的方法。 希望我们会有更快乐的维护者和贡献者,用户不会注意到任何负面变化。

有关详细信息,请参阅: 更改/Rpmautospec_by_DefaultRpmautospec 文档. 为 example 使用 rpmautospec 的软件包,请参阅 python-sphinxcontrib-程序输出.