关于合并队列
合并队列通过自动将拉取请求合并到繁忙的分支并确保该分支不因不兼容的更改而被破坏,从而提升开发速度。
合并队列提供与 Require branches to be up to date before merging 分支保护相同的优势,但不需要拉取请求作者更新其分支并等待状态检查完成后再尝试合并。
在每日有相对大量来自不同用户的拉取请求合并到同一分支的情况下,使用合并队列尤为有用。
当拉取请求通过所有必需的分支保护检查后,拥有仓库写入权限的用户即可将该拉取请求加入队列。合并队列会确保在将拉取请求的更改应用到目标分支的最新版本以及队列中已有的拉取请求时,所有必需的状态检查均通过。
合并队列可以使用 GitHub Actions 或您自己的 CI 提供商来对合并队列中的拉取请求运行必需的检查。更多信息,请参阅 GitHub Actions 文档。
有关使用合并队列合并拉取请求的更多信息,请参阅 使用合并队列合并拉取请求。
为合并队列配置持续集成(CI)工作流
注意
- 合并队列无法在分支保护规则使用通配符 (
*) 的分支名称模式时启用。 - 合并队列将在继续合并之前等待必需的检查报告。要求使用合并队列时,您必须更新 CI 配置以触发并报告
merge_group事件。 - 合并队列和拉取请求的检查是耦合的,并在分支保护规则或规则集下进行配置。更多信息,请参阅 管理合并队列。
使用 GitHub Actions 触发 merge_group 检查
You must use the merge_group event to trigger your GitHub Actions workflow when a pull request is added to a merge queue.
注意
如果您的仓库使用 GitHub Actions 对拉取请求执行必需检查,则需要更新工作流以将 merge_group 事件作为额外触发器。否则,在将拉取请求加入合并队列时不会触发状态检查,导致合并失败,因为必需的状态检查未被报告。merge_group 事件独立于 pull_request 和 push 事件。
A workflow that reports a check which is required by the target branch's protections would look like this
on:
pull_request:
merge_group:
For more information on the merge_group event, see Events that trigger workflows.
使用第三方 CI 提供商触发 merge_group 检查
使用第三方 CI 提供商时,您需要更新 CI 配置,使其在以特殊前缀 gh-readonly-queue/{base_branch} 开头的分支被推送时运行。这些是合并队列代表您创建的临时分支,包含与拉取请求不同的 sha。
管理合并队列
仓库管理员可以通过在基分支的保护规则中启用 “Require merge queue” 分支保护设置来要求使用合并队列。更多信息,请参阅 管理分支保护规则。
启用 “Require merge queue” 设置后,您还可以访问以下设置
-
合并方式: 选择在合并排队的拉取请求时使用的方法:merge、rebase 或 squash。
-
构建并发数: 要分发的
merge_groupwebhook 的最大数量(介于1和100之间),限制并发 CI 构建的总量。这会影响合并队列能够完成的合并速度。 -
仅合并未失败的拉取请求: 此设置决定合并队列如何形成待合并的拉取请求组。
已启用? 描述 是 所有拉取请求必须满足必需的检查才能合并。 否 即使拉取请求的必需检查失败,只要该组中最后一个拉取请求已通过必需检查,也可以将其加入组中。如果组中最后一个拉取请求已通过必需检查,这意味着合并组中所有更改的检查均已通过。若不选中此复选框,则在出现间歇性测试失败但不希望误报阻塞队列的情况下会很有用。 -
状态检查超时: 选择队列在假设检查失败之前等待 CI 响应的时长。
-
合并限制: 选择一次性合并到基分支的最小和最大拉取请求数量(介于
1和100之间),以及在超时后队列应停止等待更多条目并以少于最小数量的方式合并的时间。注意
合并限制不会合并
merge_group构建。合并限制仅在一个或多个merge_group已满足构建检查后,影响对基分支的合并。合并限制 使用场景 最大合并的拉取请求数 您可以指定最大组大小,这在基分支的合并会触发部署且您希望确保一次不部署过多更改时非常有用。 最小合并的拉取请求数 您可以指定最小组大小,这在基分支的合并会触发较长的 CI 构建或部署过程且不希望阻塞队列后续条目时非常有用。 等待时间 您可以为达到最小组大小设置超时,如果在指定的时间限制内没有更多 PR 排队,则允许较小的组进行合并。
合并队列的工作原理
当拉取请求被添加到合并队列时,合并队列确保它们按照先进先出的顺序合并,并始终满足必需的检查。
合并队列会创建带有特殊前缀的临时分支来验证拉取请求的更改。当拉取请求被添加到合并队列时,其更改会与最新的 base_branch 版本以及队列中排在前面的拉取请求的更改一起分组成一个 merge_group。GitHub 会在 base_branch 的分支保护所要求的检查通过后,将所有这些更改合并到 base_branch。
有关合并方式的详细信息,请参阅 关于拉取请求合并。
CI 成功
当多个拉取请求被添加到合并队列且临时的 merge_group 分支的 CI 结果成功时,它们都会被合并。在下面的场景中,两个拉取请求成功添加到队列并合并到目标分支。
- 用户将拉取请求 #1 添加到合并队列。
- 合并队列创建一个前缀为
main/pr-1的临时分支,包含目标分支和拉取请求 #1 的代码更改。会触发类型为checks_requested的merge_groupwebhook 事件,合并队列将等待您的 CI 提供商的响应。 - 用户将拉取请求 #2 添加到合并队列。
- 合并队列创建一个前缀为
main/pr-2的临时分支,包含目标分支、拉取请求 #1 和拉取请求 #2 的代码更改,并触发 webhook。 - 当 GitHub API 收到
merge_group分支main/pr-1和main/pr-2的成功 CI 响应后,临时分支main/pr-2将合并到目标分支。目标分支现在同时包含拉取请求 #1 和 #2 的更改。
CI 失败
在将拉取请求与目标分支的最新版本以及队列中其前面的更改进行分组后,如果出现必需的状态检查失败或与基础分支冲突,拉取请求将被从队列中移除。拉取请求的时间线会显示被移除的原因。
以下场景说明了当 CI 对某个拉取请求报告失败状态时会发生什么。
- 用户将拉取请求 #1 添加到合并队列。
- 合并队列创建一个前缀为
main/pr-1的临时分支,包含目标分支和拉取请求 #1 的代码更改。会触发类型为checks_requested的merge_groupwebhook 事件,合并队列将等待您的 CI 提供商的响应。 - 用户将拉取请求 #2 添加到合并队列。
- 合并队列创建一个前缀为
main/pr-2的临时分支,包含目标分支、拉取请求 #1 和拉取请求 #2 的代码更改,并触发 webhook。 - 当 GitHub API 收到
main/pr-1的失败状态时,合并队列会自动将拉取请求 #1 从合并队列中移除。 - 合并队列重新创建前缀为
main/pr-2的临时分支,使其仅包含目标分支和拉取请求 #2 的更改。 - 当 GitHub API 收到
merge_group分支main/pr-2的成功 CI 响应后,临时分支main/pr-2将合并到目标分支中,且不包含拉取请求 #1 的更改。
导致拉取请求从合并队列中被移除的原因有多种
- 已配置的 CI 服务报告合并组的测试失败
- 基于配置的超时时间设置,等待成功的 CI 结果超时
- 用户通过 API 或合并队列界面请求移除
- 分支保护失败且无法自动解决
跳到队列顶部
在向合并队列添加拉取请求时,可以选择将您的拉取请求移动到队列顶部。
注意
请注意,跳到合并队列的顶部会导致所有进行中的拉取请求重新构建,因为队列的重新排序会在提交图中产生断点。频繁使用此功能可能会降低目标分支的合并速度。
以下场景说明了用户将队列跳到顶部时会发生什么。
- 用户将拉取请求 #1 添加到合并队列。
- 合并队列创建一个前缀为
main/pr-1的临时分支,包含目标分支和拉取请求 #1 的代码更改。会触发类型为checks_requested的merge_groupwebhook 事件,合并队列将等待您的 CI 提供商的响应。 - 用户将拉取请求 #2 添加到合并队列。
- 合并队列创建一个前缀为
main/pr-2的临时分支,包含目标分支、拉取请求 #1 和拉取请求 #2 的代码更改,并触发 webhook。 - 用户使用跳转选项将拉取请求 #3 添加到合并队列,这会在提交图中产生断点。
- 合并队列创建一个前缀为
main/pr-3的临时分支,包含目标分支和拉取请求 #3 的代码更改,并触发 webhook。 - 合并队列重新创建前缀为
main/pr-1和main/pr-2的临时分支,使其包含拉取请求 #3 的更改,并触发 webhook。