Skip to main content

管理合并队列

可以通过在存储库中为拉取请求启用合并队列来加快开发速度。

谁可以使用此功能?

People with admin permissions can manage merge queues for pull requests targeting selected branches of a repository.

拉取请求合并队列在组织拥有的任何公共存储库中均处于可用状态,或在使用 GitHub Enterprise Cloud 的组织拥有的专用存储库中处于可用状态。 有关详细信息,请参阅“GitHub 的计划”。

关于合并队列

合并队列通过将拉取请求自动合并到繁忙的分支中,并确保分支永远不会因不兼容的更改而中断,从而帮助提高速度。

合并队列提供与“要求分支在合并之前保持最新”分支保护相同的优势,但不需要拉取请求作者在尝试合并之前,更新其拉取请求分支并等待状态检查完成。

如果分支具有每天从许多不同用户合并的大量拉取请求,那么使用合并队列特别有用。

拉取请求通过所有必需的分支保护检查后,对存储库具有写入访问权限的用户可以将该拉取请求添加到该队列。 合并队列将确保拉取请求的更改在应用于最新版本的目标分支和队列中已有的任何拉取请求时通过所有必需的状态检查。

合并队列可以使用 GitHub Actions 或你自己的 CI 提供程序对合并队列中的拉取请求运行所需的检查。 有关详细信息,请参阅“GitHub Actions 文档”。

有关使用合并队列合并拉取请求的详细信息,请参阅“将拉取请求与合并队列合并”。

为合并队列配置持续集成 (CI) 工作流

注意:

  • 在分支名称模式中使用通配符 (*) 的分支保护规则无法启用合并队列。
  • 合并队列将等待报告所需的检查,然后才能继续合并。 必须更新 CI 配置,以在需要合并队列时触发和报告合并组事件。

通过 GitHub Actions 触发合并组检查

将拉取请求添加到合并队列时,必须使用 merge_group 事件触发 GitHub Actions 工作流。

注意: 如果存储库使用 GitHub Actions 对存储库中的拉取请求执行必要的检查,则需要更新工作流以将 merge_group 事件作为附加触发器包含在内。 否则在将拉取请求添加到合并队列时不会触发状态检查。 合并将失败,因为没有报告必要的状态检查。 事件 merge_group 独立于 pull_requestpush 事件。

报告目标分支保护所需的检查的工作流如下所示:

on:
  pull_request:
  merge_group:

有关 merge_group 事件的详细信息,请参阅“触发工作流的事件”。

通过第三方 CI 提供程序触发合并组检查

使用第三方 CI 提供程序时,可能需要更新 CI 配置,以在向其中推送以特殊前缀 gh-readonly-queue/{base_branch} 开头的分支时运行。 这些是合并队列代表你创建的临时分支,包含与拉取请求不同的 sha

管理合并队列

存储库管理员可以通过在基本分支的保护规则中启用分支保护设置“需要合并队列”来要求合并队列。 有关详细信息,请参阅“管理分支保护规则”。

启用“需要合并队列”设置后,还可以访问以下设置:

  • 合并方法:选择合并排队的拉取请求时要使用的方法:合并、变基或压缩。

  • 生成并发:要调度的最大数量的 merge_group Webhook(1100 之间),可限制并发 CI 生成的总量。 这会影响合并队列可以完成的合并速度。

  • 仅合并非失败的拉取请求:此设置决定合并队列如何形成要合并的拉取请求组。

    是否启用?说明
    所有拉取请求都必须满足要合并的所需检查。
    可以将未通过所需检查的拉取请求添加到组中,前提是该组中的最后一个拉取请求已通过所需检查。 如果组中的最后一个拉取请求已通过所需的检查,这意味着合并组中的更改组合集已通过检查。 如果发生间歇性测试失败,但不希望假阴性阻碍队列,则不选中此复选框可能很有用。
  • 状态检查超时:选择队列等待 CI 响应的时间,超过该时间则假定检查未通过。

  • 合并限制:选择要合并到单个组中的拉取请求的最小数量和最大数量(1100之间),并选择一个超时时间,在该时间之后队列应停止等待更多条目并与少于最小数量的拉取请求合并。 组中究竟有多少 PR 取决于合并队列的设置:

    合并限制用例
    要合并的最大拉取请求数可以指定最大组大小,如果合并到基础分支触发部署,并且你想要确保不会一次性部署太多更改,这非常有用。
    要合并的最小拉取请求数可以指定最小组大小,如果合并到基础分支触发冗长的 CI 生成或部署过程,并且不希望在队列中保留以下条目,这非常有用。
    等待时间可以指定达到最小组大小的超时值,如果指定的时间限制内没有更多的 PR 排队,则允许较小的组合并。

合并队列的工作原理

当拉取请求添加到合并队列时,合并队列可确保它们按照始终满足所需检查的先入先出的顺序进行合并。

合并队列创建具有特殊前缀的临时分支来验证拉取请求更改。 将拉取请求添加到合并队列时,使用最新版本的 base_branch 将拉取请求中的更改分组到 merge_group,与队列中位于其之前的拉取请求中的更改一样。 一旦 base_branch 的分支保护所需的检查通过,GitHub 会将所有这些更改合并到 base_branch 中。

有关合并方法的信息,请参阅“关于拉取请求合并”。

成功的 CI

将多个拉取请求添加到合并队列时,如果临时 merge_group 分支具有成功的 CI 结果,则它们都会被合并。 在以下方案中,两个拉取请求已成功添加到队列并合并到目标分支。

  1. 用户将拉取请求 #1 添加到合并队列。
  2. 合并队列创建一个前缀为 main/pr-1 的临时分支,其中包含目标分支的代码更改和拉取请求 #1。 调度 checks_requested 类型的 merge_group Webhook 事件,合并队列将等待来自 CI 提供程序的响应。
  3. 用户将拉取请求 #2 添加到合并队列。
  4. 合并队列创建一个前缀为 main/pr-2 的临时分支,其中包含目标分支的代码更改、拉取请求 #1、拉取请求 #2 和调度 Webhook。
  5. 当 GitHub API 收到 merge_group 分支 main/pr-1main/pr-2 的成功 CI 响应后,临时分支 main/pr-2 将合并到目标分支。 目标分支现在包含来自拉取请求 #1 和 #2 的更改。

失败的 CI

在将拉取请求与目标分支的最新版本分组并在队列中提前更改后,如果所需的状态检查失败或与基础分支冲突,将从队列中删除拉取请求。 拉取请求时间线将显示从队列中删除拉取请求的原因。

以下方案概述了当 CI 报告一个拉取请求的失败状态时会发生的情况。

  1. 用户将拉取请求 #1 添加到合并队列。
  2. 合并队列创建一个前缀为 main/pr-1 的临时分支,其中包含目标分支的代码更改和拉取请求 #1。 调度 checks_requested 类型的 merge_group Webhook 事件,合并队列将等待来自 CI 提供程序的响应。
  3. 用户将拉取请求 #2 添加到合并队列。
  4. 合并队列创建一个前缀为 main/pr-2 的临时分支,其中包含目标分支的代码更改、拉取请求 #1、拉取请求 #2 和调度 Webhook。
  5. 当 GitHub API 收到 main/pr-1 的失败状态时,合并队列会自动从合并队列中删除拉取请求 #1。
  6. 合并队列重新创建此前缀为 main/pr-2 的临时分支,以仅包含目标分支的更改和拉取请求 #2。
  7. 当 GitHub API 收到 merge_group 分支 main/pr-2 的成功 CI 响应后,临时分支 main/pr-2 将合并到目标分支,不含拉取请求 #1。

从合并队列中删除拉取请求的原因有很多:

  • 配置的 CI 服务报告合并组的测试失败
  • 根据配置的超时设置,等待成功 CI 结果超时
  • 用户通过 API 或合并队列接口请求删除
  • 无法自动解决的分支保护失败

跳转到队列顶部

将拉取请求添加到合并队列时,可以选择将拉取请求移动到队列顶部。

注意:请注意,跳转到合并队列的顶部将导致所有正在进行的拉取请求完全重新生成,因为对队列重新排序会在提交图中引入中断。 大量利用此功能可能会降低目标分支的合并速度。

以下方案概述了用户跳转队列时会发生的情况。

  1. 用户将拉取请求 #1 添加到合并队列。
  2. 合并队列创建一个前缀为 main/pr-1 的临时分支,其中包含目标分支的代码更改和拉取请求 #1。 调度 checks_requested 类型的 merge_group Webhook 事件,合并队列将等待来自 CI 提供程序的响应。
  3. 用户将拉取请求 #2 添加到合并队列。
  4. 合并队列创建一个前缀为 main/pr-2 的临时分支,其中包含目标分支的代码更改、拉取请求 #1、拉取请求 #2 和调度 Webhook。
  5. 用户使用跳转选项将拉取请求 #3 添加到合并队列,这会在提交图中引入中断。
  6. 合并队列创建一个前缀为 main/pr-3 的临时分支,其中包含目标分支的代码更改、拉取请求 #3 和调度 Webhook。
  7. 合并队列重新创建此前缀为 main/pr-1main/pr-2 的临时分支,其中包含拉取请求 #3 中的更改和调度 Webhook。

延伸阅读