基于 Alexandre Okita 在 Medium 发布的 GitLab Merge Train: Easy and Efficient Merge Request Queueing 整理,原文发表于 2020-12-09。本文是中文摘要/译介,不是逐段全文翻译。
Merge Request Queueing
把“能不能合并”从单个 MR 改成组合验证
很多团队的问题不在于某个 MR 没跑 CI,而在于多个已经通过 CI 的 MR 同时进入主分支后,组合起来反而失败。Merge Train 处理的就是这个 “组合之后是否仍然安全”的问题。
为什么“每个 MR 都绿了”还不够
一个 MR 通过 CI,只能说明它和当时的主分支兼容。假设 B 修改了 lint 规则,A 的功能分支在旧规则下通过,但 A+B 一起进入主分支后,A 可能立刻违反新规则。此时问题不是 CI 不存在,而是验证对象选错了。
功能分支基于旧 main 跑绿。
规则或依赖更新也能独立通过。
主分支合并后才暴露组合冲突。
三种合并策略的取舍
直接合并
每个 MR 自己跑 CI,通过后就允许写入主分支。
- 等待时间短
- 没有验证多个 MR 的最终组合
- 高并发合并时容易把 main 弄红
串行队列
队首 MR 先基于最新 main 重新验证,通过后再处理下一个。
- 主分支保护更强
- 等待时间随队列长度线性增长
- 构建慢时反馈会明显变迟
Merge Train
为队列里的每个位置预先构造组合,并行跑合并结果流水线。
- 验证 A、A+B、A+B+C 这类实际组合
- 流水线可以并行启动
- 失败项被移出后,后续组合重新计算
Merge Train 怎么工作
点击合并,但不马上写入 main
MR 被放进列车队列,等待基于合并结果的验证。
每个位置生成一个组合
第一个位置验证 A,第二个位置验证 A+B,第三个位置验证 A+B+C。
并行跑流水线
GitLab 不必等 A 完全结束后才开始 A+B,因此反馈更快。
失败就重排
某个 MR 的组合失败后,它会被移出列车,后面的组合重新生成并验证。
配置时重点看什么
原文提到,启用 Merge Train 需要对应的 GitLab 能力、Maintainer 权限,以及项目里开启 merged results pipeline / merge trains 相关设置。除此之外,CI 配置必须真的覆盖合并结果,而不是只验证分支自身。
- 开启 merged results pipeline
- 开启 merge trains
- 确保 `.gitlab-ci.yml` 有用于合并结果验证的 job
- 把主分支保护规则和团队合并流程一起调整
读后总结
Merge Train 的价值不是让 CI 更炫,而是把验证对象从“单个分支” 升级成“即将进入主分支的真实组合”。对于多人协作的 monorepo、移动端主仓库和基础设施仓库, 这比依赖人工 rebase 和口头约定更可靠,也更容易规模化。
No comments yet