GitLab-CI如何限制同一分支并行运行流水线避免制品覆盖
解决方案
GitLab 14.10及以上版本已经提供了和Jenkins disableConcurrentBuilds()完全对等的流水线级并发限制能力,通过工作流级别资源组即可实现,完美解决你之前单Job加资源组导致的任务交替执行问题。
1. 推荐配置(GitLab 14.10+)
直接在.gitlab-ci.yml的workflow块中配置资源组即可,无需给单个Job重复添加:
workflow: # 用分支名作为资源组名称,同分支流水线共享资源组,不同分支互不影响 resource_group: name: $CI_COMMIT_REF_NAME # 15.7+版本支持配置排队规则,oldest_first表示先触发的流水线优先执行,默认值即符合要求 process_mode: oldest_first stages: - build - test1 - test2 - test3 - deploy # 后续所有Job无需额外配置resource_group,正常定义即可 build: stage: build script: echo "build" test1: stage: test1 script: echo "test1" # 其余test、deploy阶段配置保持不变
该配置生效后,同一时间只会有一条同分支的流水线处于运行状态,后续触发的流水线会整体排队,等前一条流水线所有阶段全部执行完成后才会启动,完全符合你预期的执行顺序。
你之前给单个Job添加同一资源组的方案不符合预期,是因为资源组默认是Job级别的锁,前一条流水线的某个Job执行完成后就会释放锁,下一条流水线的同资源组Job就能抢占锁执行,所以会出现两条流水线任务交替执行的情况。
2. 低版本兼容方案(GitLab <14.10)
如果你的GitLab版本不支持工作流级资源组,可以用如下变通方案实现:
- 仅给流水线第一个阶段(build阶段)的Job配置资源组
- 在build阶段的脚本中添加逻辑,调用GitLab开放接口查询当前分支是否存在ID小于当前流水线、且状态为运行中的流水线,如果存在则循环等待,直到所有更早的同分支流水线执行完成后再继续执行build逻辑。因为build是流水线的第一个阶段,只要build阶段等待旧流水线执行完成后启动,整条流水线的执行顺序就符合预期。
可选补充:自动取消冗余流水线
如果你的业务允许新流水线触发后直接取消同分支旧的运行中流水线,可以开启自动取消冗余流水线功能,能大幅节省CI资源:
workflow: auto_cancel: on_new_commit: interruptible
该方案不适用于需要旧流水线必须执行完成的场景。
内容的提问来源于stack exchange,提问作者Sathish
相关产品推荐
相关产品推荐

