使用 Mergify 像专业人士一样合并拉取请求

2025-06-04

使用 Mergify 像专业人士一样合并拉取请求

如果你已经使用 Git 一段时间了,我相信使用拉取请求对你来说已经习以为常了。而且,你也可能开始对合并冲突感到恼火。但是,如果我告诉你,即使合并了冲突,我们也无法确定拉取请求是否会中断我们的生产环境呢?你有没有想过,企业项目是如何维护的?这么多贡献者是如何同步协作而不中断生产的?

Shopify、Uber 以及几乎所有其他公司的工程团队都面临着同样的合并问题,并使用同样的方法解决了这个问题。许多工程团队和开源项目正在将合并队列作为其工作流程的一部分。

到底是什么问题?🤔

将庞大工程师团队的独立工作整合到一个代码库中并非易事。这其中的困难远比我们常见的合并冲突(版本控制技术在处理这类冲突方面相当出色)要深得多。当多个相互依赖的代码区域同时发生更改时,我们可能会遇到一种更加棘手的冲突。

让我们使用GitHub进一步理解这个问题。假设我们创建一个 Pull 请求,并将 CI 传递给主分支。

在我们的 PR 合并之前,还有另一个提交。提交的方式并不重要,无论是通过合并另一个 PR 还是直接提交到主分支。

即使提交之后,CI 检查仍然显示绿色。现在,作为业余维护人员,我们可能会觉得没问题,因为检查已经通过了。于是我们合并了 PR,你猜怎么着?很有可能我们破坏了生产环境。

常规 CI 检查或任何版本控制系统都会在此处发生故障。因此,需要使用合并队列。

但这怎么可能发生呢?🤯

你可能会想,即使所有检查都通过了,合并 PR 怎么会在生产环境中破坏代码呢?想象一下,我们在新代码中添加了一个函数调用,而我们的队友正忙着重构该函数,更改其签名或返回值。现在,由于我们修改的文件在朋友提交时没有任何新的更改,因此 CI 仍然会通过。版本控制,甚至 CI 中的测试和检查都无法解决这种冲突,但合并队列可以。

了解问题的规模

在 Shopify,开发人员每天要合并并部署超过 400 个拉取请求到 Shopify 主分支。超过一百万商家依赖 Shopify,合并过程中的一个错误就可能造成数十亿美元的损失。Uber 的工程团队报告称,两个变更之间发生实际冲突的可能性为 5%,而当并发且潜在冲突的修改数量仅为 16 个时,这个数字就会上升到 40%。因此,对于大型组织来说,这些冲突几乎每天都可能发生。

什么是合并队列?↣

合并队列顾名思义:就是将分支/拉取请求添加到一个队列中,等待其被合并。合并队列是一个先进先出的队列,用于管理我们 Github 仓库的合并工作流。

对于开发人员来说,直接提交到主分支总是更容易。但随着项目规模的扩大、代码复杂性的提升以及贡献者的增多,对分支的需求也随之而来。简单来说,合并队列可以理解为一种工具,它既能提供直接提交到主分支的优势,又能提供创建分支的可扩展性。除了无需等待构建通过即可合并这一显而易见的便利性之外,使用合并队列的一大原因是它可以帮助消除错误的合并,从而节省我们的时间和金钱。

使用合并队列可以解决这个问题,因为它会在合并之前更新任何未与其基分支同步的拉取请求。更新会强制持续集成系统使用基分支的新代码重新测试拉取请求,从而捕获任何潜在的回归问题。

合并队列的工作流程?🗒

合并队列的运作原理相当简单。假设我们有两个拉取请求,分别对应两个不同的功能。Git 和 CI 都认为这两个分支在某个时间点通过了所有检查,这本身并没有错。但这些检查意味着该 PR 只能在特定时刻与主分支合并,之后可能会发生变化。因此,每当主分支发生变更时,我们都必须重新评估该 PR 的兼容性和功能性。

合并队列确保每个 PR 都插入队列并按正确顺序合并。合并队列确保所有分支/PR 都使用特定流程合并。该流程如下:

  • 拉取请求已获得一个或多个审阅者的批准
  • 拉取请求已添加到合并队列
  • 当拉取请求到达顶部时,分支/PR 将更新为主分支,即所有 CI 检查将再次运行
  • 拉取请求从队列中移除并被合并或关闭。

各组织如何解决这个问题?🤝

Github 提供了一个原生的合并队列解决方案,但目前仅在有限的公开测试版中可用。由于它是在 GitHub Actions 框架下实现的,因此这可能是 GitHub 用户的最佳解决方案。目前,我们需要成为被选中参与测试版的幸运用户之一才能体验该功能。

如果您是 GitLab 的高级用户,则无需担心合并队列,因为在 GitLab 中它已经公开可用。

Mergify提供了一个易于设置和配置的合并队列功能,以满足我们的需求。它对开源项目永久免费,对私有项目提供 14 天免费试用。

Mergify 不仅有助于解决合并队列的问题,而且还具有许多在 GitHub 上找不到的迷人功能。

技术深度探究🚀

为了理解其中的技术细节,让我们亲身实践并见证 Mergify 的一些功能。

在大型组织中,解决合并冲突并非我们面临的唯一问题。我们必须将每个 PR 分配给合适的人员进行审核,确保在合并之前对其进行审核,设置标签,变基分支,将 PR 反向移植到不同的分支,等等,诸如此类的问题不胜枚举。您可以使用 Mergify 来解决所有这些问题。Mergify 提供的功能非常丰富,一篇博文难以全部讲完,所以让我们尝试一下其中的一些。在本篇实践中,我们将:

  • 合并前添加检查
  • 自动合并
  • 使用命令来指示 Mergify 机器人
  • 创建并使用合并队列

让我们先创建一个 Github 仓库。我将其命名为Mergify,但您可以随意命名。让我们点击特定的 URL 来初始化我们的项目。

https://github.com/new
Enter fullscreen mode Exit fullscreen mode

填写详细信息,然后单击“创建存储库”按钮。

Mergify Repo 初始化

现在,既然我们已经初始化了仓库,那就让我们在Mergify上注册一个账户吧。我们可以轻松地直接使用 Github 账户登录。如果您是第一次使用该工具,点击“注册”按钮后,它会将您重定向到授权页面。

Mergify 认证页面

一旦通过身份验证,我们就可以访问仪表板。在身份验证过程中,我们可以选择将工具安装到所有存储库或选定的存储库。

Mergify 仪表板

正如我们在仪表板中看到的,“合并队列”按钮可以帮助我们以队列的形式检查拉取请求。“编辑器配置”选项提供了一个配置的入门模板,我们可以根据需要进行自定义。“使用情况”选项卡显示了与哪些用户关联的选项。侧边栏包含“应用程序密钥”等选项,您还可以在其中存储私钥和公​​钥。

让我们点击按钮添加更多存储库来添加我们创建的存储库。

将 Mergify Repo 添加到 Mergify

现在,我们可以处理 Mergify 存储库并根据我们的需要实现功能。

为了本次实践,我们先构建一个基本的React项目来展示其功能。克隆代码库后,将工作目录切换到 Mergify 目录,然后运行以下命令创建一个新的 React 应用程序。

npx create-react-app .
Enter fullscreen mode Exit fullscreen mode

在本地主机上启动应用程序

npm start
Enter fullscreen mode Exit fullscreen mode

如果您发现以下屏幕,那么就可以开始了。
React 入门模板

现在一切都已设置完毕,让我们开始使用 Mergify。

第一步是为我们的仓库创建一个 Mergify 配置。一个简单的配置文件可能像这样

pull_request_rules:
  - name: Automatic merge on approval
    conditions:
      - or:
        - "#files=1"
        - files=README.md
    actions:
      merge:
        method: merge
Enter fullscreen mode Exit fullscreen mode

让我们来理解一下这一点。我们添加了一条拉取请求规则,规定 Mergify 应该自动合并所有对某个文件或 README.md 文件有更改的拉取请求。这有助于将小的更改快速合并到主分支。

我们可以使用andor条件来使我们的规则更加具体。现在,要检查我们的配置是否正确,请点击蓝色按钮check my configuration。我们还可以添加 PR 进行检查,这将为我们提供有关所创建规则的更多详细信息。

我们创建了一个名为的分支header,并向主分支发送了一个 PR,该分支向网站添加了一个标题文本。

标题 PR

让我们尝试根据这个 PR 检查我们的 Mergify 配置。
检查配置

右侧清晰地显示,由于此 PR 仅更改了一个文件,因此规则已匹配。测试规则后,我们可以轻松地通过单击此按钮将此配置添加到我们的代码库中。
创建配置 PR

如果你检查你的 GitHub 仓库,你会发现一个来自 Mergify 的新 PR。只需合并该 PR,你的规则就会被添加。
Mergify PR

如果你仔细观察,你会发现,一旦你合并了 PR,header PR 也会自动合并。如果你打开已经关闭的header PR,你会发现 Mergify 已经帮你合并了。
Mergify 已合并

这是一个非常简单的配置,但使用 Mergify,您可以添加更多复杂的规则。一切皆有可能!

您还可以指示 Mergifyio 机器人为您执行某些任务,例如更新配置文件。点击此处获取完整的命令列表
Mergifyio 命令

最后,我们来看一下合并队列。
一个简单的用法是串行合并拉取请求,确保所有请求都能逐一通过 CI。

queue_rules:
  - name: default
    conditions: [] 

pull_request_rules:
  - name: merge using the merge queue
    conditions:
      - "#approved-reviews-by>=2"
      - check-success=Travis CI - Pull Request
    actions:
      queue:
        name: default

Enter fullscreen mode Exit fullscreen mode

在上面的规则中,我们定义了一个名为 default 的队列,允许任何拉取请求在进入该队列后进行合并。要进入该队列,拉取请求必须获得 2 个批准评审并通过 CI。一旦拉取请求位于队列的第一位,它将被更新为其基础分支的最新提交。

同样,我们可以设置多个队列,例如“紧急”和“默认”。此功能目前仅适用于高级用户。您可以为 PR 添加标签,以便将其分配到不同的队列,如下所示。
多个队列

结尾💚

Mergify 的功能数不胜数。这篇博客的目的是激发您对这款神奇工具的兴趣,它可以帮您节省大量时间和精力。请查看文档中的所有功能。不要犹豫,立即创建您的帐户并开始使用Mergify 。如果您对本文有任何疑问,或者想讨论一些其他话题,请随时在LinkedIn上与我联系💕

如果您经营一家组织并希望我为您撰写文章,请联系我🙈

文章来源:https://dev.to/aniket762/merging-pull-requests-like-a-pro-with-mergify-30fa
PREV
高阶数组函数 forEach、map 和 filter
NEXT
React Hooks 详解:useImperativeHandle