• 新的代码合并方式 - Merge Queue
  • 发布于 2个月前
  • 217 热度
    0 评论
  • CEBBCt
  • 4 粉丝 44 篇博客
  •   

概括

这篇文章介绍了 Merge Queue 这一新的代码合并方式,它可以让开发者不用担心代码冲突和等待时间,而是把合并的任务交给一个自动化的队列来处理。文章还介绍了一个实现了 Merge Queue 的工具 Mergify,它可以与 GitHub 集成,让开发者更方便地使用 Merge Queue。


尽管几个月前“合并队列”还是一个不太为人所知的术语,现在却越来越受到业界的重视。无论是像 GitHub 这样的行业领袖的公告,还是实际的技术解决方案,合并队列正逐渐被软件开发团队所采纳。因此,你可以深入探讨这一主题,了解合并队列的定义,其适用场景,以及它们在实际操作中的工作原理。

准备好了吗?让我们开始吧。

“合并队列”是什么?
在探讨为何要使用合并队列之前,我们首先需要明确它的定义。顾名思义,合并队列是一系列等待合并的 Pull Request (简称 PR)的排列顺序。每位团队成员每天都可能创建许多 Pull Request,然后由仓库维护者将其加入队列。听起来很简单,不是吗?更准确地说,你不仅仅是将基础的 PR 加入队列。队列中的所有 PR 都已经得到了维护者的批准,这意味着它们已经通过了所有必要的检查。

因此,你得到了一个充满已验证 Pull Request 的队列。这听起来很有趣,但似乎并不实用。为什么不逐一合并它们呢?为了解答这个问题,我们先来看看如果你不使用合并队列,可能会遇到哪些常见问题。

为什么需要合并队列?
坦白说,有许多理由支持使用合并队列。在这一部分,你将了解一个真正棘手的问题,以及如何通过使用合并队列来解决它。

常见问题:合并过时的 Pull Request
要理解合并队列如何解决问题,你首先必须了解问题本身。

请想象以下场景:
1.主分支已经通过了持续集成测试。
2.创建了一个 Pull Request,并通过了 持续集成(CI),我们称之为 PR1。
此时,你可以通过以下图示来表示仓库的状态:

目前一切似乎都在正常运行,但这种情况并不会持续下去。让我们深入了解一下。当 PR1 仍处于打开状态时,主分支接收了另一个提交。无论这个新提交是直接推送到主分支还是从另一个 Pull Request 合并的,关键是主分支已经发生了变化。

随后,持续集成(CI)系统针对主分支运行了测试,并再次通过。此时,你可以通过以下图示来描述你的仓库及其持续集成系统的状态:

你会注意到 PR1 仍被持续集成系统视为有效,这是合理的,因为只有主分支发生了变化,而 PR1 并未发生改变。由于代码之间没有冲突,GitHub 认为 PR1 是可以合并的,合并按钮变成了绿色。你满怀信心地点击了那个绿色按钮。然而,正如你所预料,这可能会带来一个意外的“惊喜”——并不是好事。

现在,当你试图合并 PR1 并创建了一个新的合并提交时,持续集成测试却失败了。为什么会这样呢?

实际上,当 PR1 被标记为有效时,CI 并没有用主分支新添加的提交再次测试 PR1。然而,主分支中的最后一个提交引入了新的测试,而 PR1 并未包含正确的代码来通过这个新测试,这一情况虽让人沮丧,但却合情合理。

如何应对这一挑战?
这个问题的核心在于 Rebase 的操作以及每个 Pull Request 需要与主分支保持最新的必要性。如果你不采用合并队列,通常有两个选择:
1.仅在功能分支的顶部运行持续集成,不强制功能分支与主分支保持同步。主要缺点是功能分支可能与主分支兼容,但也可能不兼容。

2.要求所有功能分支与目标分支保持最新。主要缺点在于这会消耗大量的时间和资源。


对于采用持续集成/持续交付(CI/CD)流程的组织和团队来说,这是一种常见的挑战。如果你正面临这个问题,不必担心,因为真正的解决方案已经找到了!

真正的解决方案:合并队列
解决方案就是使用合并队列。它在合并之前会更新所有与主分支不同步的 Pull Request。实际上,合并队列会要求 CI 系统使用主分支的最新代码重新测试 PR。如果你在之前描述的情况下使用合并队列,系统会自动将主分支合并到功能分支中。

如下图所示,CI 将重新运行测试。如果 Pull Request 失败,则会被标记为失败并从队列中移除。当然,如果 PR 有效,并且所有检查都通过了,它将被合并。

另一个实际场景:多个 Pull Request 已验证,准备合并。合并队列会按照顺序安排这些 Pull Request 的合并,并确保它们与主分支保持同步。当然,只有当 Pull Request满足所有条件时,才会进行同步更新。

但是,如果你刚合并了一个已更新的 Pull Request,紧接着又发现另一个 Pull Request 仍然过时,那会发生什么情况呢?为了更清晰地解释这个过程,我们可以通过下图来理解:

合并队列的作用是确保在合并之前,第二个 Pull Request 与主分支的最新版本保持同步。通过这样的操作,可以避免将过时或有缺陷的 Pull Request 合并到主分支中。

你可以根据需要重复这个过程,逐一处理队列中的每个过时 Pull Request。虽然软件开发的过程并不总是简单,但合并队列的使用无疑可以让整个流程变得更加顺畅和高效。

合并队列的工作机制
了解合并队列能解决的问题后,我们来深入探讨其工作机制。合并队列在视觉上可能显得有些复杂,我们可以逐步分析其工作流程和组成部分。

1. 将有效的 PR 加入队列
合并队列引擎会在你的 Pull Request 上运行。所有满足条件的 Pull Request 将被添加到队列中。

2. 更新与 CI
合并队列会确保队列中的每个 PR 与主分支保持同步,以确保其最新状态。随后,CI 会重新运行,以确认 PR 是否可以合并。

3. 合并还是不合并:决策点
存在两种截然不同的情况:
.所有检查通过 → 合并 PR。

.测试失败 → 将 PR 从队列中移除。


Mergify 的合并队列特点是什么?
具体来说,Mergify 的合并队列实现了你刚刚了解的所有功能。作为市场上首批合并队列之一,Mergify 已经赢得了数千名用户的满意评价。虽然前述的常见功能足以解决许多棘手问题,但在更复杂和特定的情况下,你可能需要一些非常具体的功能。

幸运的是,Mergify 可以满足这些需求!

1. 推测性检查:并行测试不同的 PR
队列中的第一个 Pull Request 将被加入合并流程,并与其他请求一起并行测试,以便更快地合并。

2. 批次处理:一次检查和合并多个 PR
Mergify 通过 batch_size 选项允许一次性检查多个 Pull Request 的合并性。

3. 多队列管理:将 PR 分配到专用队列
通过使用多个队列,可以根据优先级将 Pull Request 分配到不同的队列中。

4. 队列冻结:暂停所有合并过程
Mergify 允许暂停一个或多个队列的合并过程,从而增强了对代码合并方式、时间的控制和灵活性。

5.优先级管理:优先处理特定 Pull Request
你可以根据标签、所有者等因素选择哪个 PR 应该首先合并。最终的决策权在你手中!

结论
现在,各位读者应该对合并队列的概念有了全面的了解,从工作原理到使用的理由,这一概念对你来说应该已经一目了然。如果你想使用 Mergify 的合并队列解决方案,可以去官网进一步详情。
用户评论