使用 Bors 自动化合并拉取请求
我们如何开始使用 Bors 为 Meilisearch 的贡献者创造更好的环境。

Meilisearch 目前在 GitHub 上维护着超过 50 个开源项目。仅在过去六个月中,我们合并了 1000 多个拉取请求 (PRs),其中 160 个来自外部贡献者。
要确保代码库保持稳定且代码质量始终一流,我们必须在合并新的 PR 时非常谨慎。随着贡献数量的增长,自动化此过程变得必要,以便为贡献者保持简单,并确保 Meilisearch 代码库的安全。
在这篇文章中,我将描述我们为何决定使用 Bors,一个用于 GitHub 拉取请求的合并机器人,为维护者和贡献者创造更好的环境。
我们的合并流程
在开源贡献过程中,任何更改都必须在其单独的分支上完成。然后,当此分支的工作完成时,我们合并前的主要要求之一是新分支与主分支(在我们的多数仓库中称为 main
)保持最新。
如果 PR 未与 main
保持同步,可以说大部分工作已经完成,但仅仅 大部分工作 对我们来说是不够的。即使所有自动化测试在 PR 本身通过,如果 PR 分支和 main
没有对齐,合并后也无法保证通过。
在使用 Bors 之前,这意味着我们经常不得不要求 PR 作者 变基他们的分支,例如,如果在此期间合并了不同的 PR。这使得贡献比我们希望的要复杂,因为并非每个人都熟悉 Git 的 rebase
命令。
为什么要变基?
在 Meilisearch,我们认为保持清晰的 Git 历史记录非常重要,主要有两个原因: 1. 它允许每个人跟踪项目的所有更改 2. 在调试时,清晰的历史记录有助于识别是哪个提交引入了问题
变基的目标是将 PR 分支的提交移动到 main
上最新提交的后面。因此, 变基使您的 Git 历史记录清晰,并与您合并 PR 的顺序保持一致。
变基并不是使分支与 main
分支保持同步的唯一方法:例如,您也可以将 main
的更改拉取到 PR 分支。这种方法的问题在于,拉取操作会向 PR 分支添加一个合并提交,这会使仓库历史记录不清晰。
考虑到保持清晰的提交树的重要性, 变基是唯一能保证即将合并的工作与当前生产中的工作相符的方式。如果测试在一个最新分支上通过,那么一旦合并到 main
中,它们也会通过,从而确保您的生产分支不会中断。
寻找完美的工具
考虑到我们的变基要求,我开始寻找完美的工具。我想提高效率,所以我缩小了范围,只评估了符合以下条件的工具:
- 免费和开源: 该工具必须符合 Meilisearch 及其社区的价值观
- 高评价: 该工具必须稳定可靠,因为处理 PR 时出现的任何错误都可能产生重大影响
- 文档完善且易于设置: 良好的文档可以节省时间,我们可以将这些时间用于改进 Meilisearch
不幸的是,在这个范围内,我没有找到像我预期那么多的解决方案。
我尝试的第一个工具是 Shipits,这是我通过 Shopify 工程博客上的这篇文章发现的。尽管 Shipits 看起来非常坚实和有前景,但我感觉它更适合复杂的集成流程,而不是仅仅为了保持 Git 历史记录清晰的开源项目。
我测试的另一个工具是 Kodiak。它的设置非常简单,很大程度上得益于其出色的文档。它是一个很好的候选工具,适用于我们的用例,但其自动合并过程基于我们需要管理的标签,这与我们的工作流程不太匹配。例如,我们合并 PR 的最低要求是获得一位审阅者的批准;但有时,我希望有两个人审阅一个 PR,并且很容易忘记将此信息传达给 Kodiak。当它收到第一个批准时,Kodiak 会自动合并 PR,因为已满足一位审阅者的要求。
我们注意到的另一件事是 Kodiak 不会通过变基来更新源自 PR 的分支,而是通过将主分支拉取到 PR 分支中来创建 Git 提交,正如我们所见,这会混淆仓库的历史记录。最终,Kodiak 并不符合我们的需求,尽管它的设置和配置提供了无缝且无忧的体验!
与我研究过的所有其他工具相反, Bors 是根据原版 Bors 创建者在这篇文章中描述的一个独特而强大的原则构建的
软件工程的非火箭科学原则:自动维护一个始终通过所有测试的代码仓库。
这条“规则”完美地符合我们的要求,使 Bors 成为我们的最终选择。
Bors 如何工作?
Bors 是一个合并机器人——这意味着它是一个 自动化 PR 合并过程某些方面的应用程序。它的设置非常简单,而且和 Kodiak 一样,文档非常完善。实际上,配置可以是一个单独的 bors.toml
文件,其中包含我们希望在合并前执行的测试名称。
所有 Bors 命令都必须通过 PR 中的注释给出。要合并 PR,我们只需使用 bors merge
。Bors 首先应用变基,然后运行测试,如果测试成功,则将它们合并回 main
。更准确地说,Bors 实际上并没有变基 PR 的分支:它将 PR 的提交合并到另一个名为 staging
的分支中,该分支已经与 main
保持同步。如果测试在 staging
上失败,Bors 将返回失败并且不合并 PR。
锦上添花的是: Bors 还能够同时管理多个 PR 的合并,这意味着我们不需要逐个合并它们。每个 PR 都被添加到一个队列中,并会定期与 main
上的最新版本进行检查。
如果 Bors 发现 PR 和主分支之间存在冲突,它无法决定要应用哪些最终更改。在这种情况下,贡献者必须手动变基分支——如果发生这种情况,我写了这篇快速教程,说明如何从分叉仓库进行变基。
结论:我们解决了哪些问题?
Meilisearch 团队使用 Bors 已经有几个月了,我们非常满意。我们知道在提供稳定代码库的同时保持 Git 历史记录清晰可能非常复杂,但到目前为止,Bors 极大地帮助我们优化了工作流程。将 Bors 集成到我们的工作流程中,就实现了:
- 无需请求并等待 PR 作者变基
- 无需逐个测试和合并 PR
- 减少了贡献者的挫败感:他们都做得非常出色,但有些人对 Git 的变基功能不太熟悉,而这确实并非总是易于使用——尤其是在从分叉仓库工作时!
Bors 让维护者和贡献者都更快乐;因此,我们将其推荐给与我们有相同用例的项目。