You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何防止GitLab同一分支多人同时提交时CI/CD流水线并行执行?

GitLab 阻止分支CI/CD流水线并行运行的实现方法

方法一:用官方Resource Group(最省心)

GitLab自带的resource_group特性可以直接实现流水线排队——给目标分支的流水线绑定同一个资源组,新触发的流水线会自动进入等待状态,直到前一个流水线跑完(不管成功还是失败)才会启动。

配置步骤:

  1. 打开项目根目录的.gitlab-ci.yml文件
  2. 按需求添加resource_group字段:
    • 如果要让整个流水线都排队,直接在文件顶部全局配置:
      resource_group: "main-branch-lock" # 随便起个唯一的组名,比如和分支名关联
      
      stages:
        - build
        - test
        - deploy
      
      build-job:
        stage: build
        script:
          - echo "开始构建"
      
      test-job:
        stage: test
        script:
          - echo "开始测试"
      
      deploy-job:
        stage: deploy
        script:
          - echo "开始部署"
      
    • 如果只需要关键阶段(比如部署)排队,就在对应job里加:
      stages:
        - build
        - test
        - deploy
      
      build-job:
        stage: build
        script:
          - echo "开始构建"
      
      test-job:
        stage: test
        script:
          - echo "开始测试"
      
      deploy-job:
        stage: deploy
        resource_group: "main-deploy-lock"
        script:
          - echo "开始部署"
      
  3. 把修改后的配置文件提交到目标分支就行。

额外说明:

  • 可以用变量动态生成资源组名,比如resource_group: "${CI_COMMIT_BRANCH}-lock",这样每个分支都有独立的排队队列
  • 等待中的流水线会显示pending状态,鼠标悬停能看到“Waiting for resource group”的提示

方法二:用GitLab API自定义排队逻辑(适合复杂场景)

如果需要更精细的控制(比如只允许特定状态的流水线排队),可以写个脚本通过GitLab API查当前分支的流水线状态,让新流水线等前面的跑完再继续。

实现步骤:

  1. 在项目「设置」→「CI/CD」→「变量」里添加一个GitLab个人访问令牌,命名为GITLAB_API_TOKEN,权限要勾上read_api
  2. 在.gitlab-ci.yml里加一个前置检查job:
    check-running-pipelines:
      stage: .pre # 这个阶段会在所有其他阶段之前执行
      script:
        - |
          # 循环检查当前分支是否有运行中的流水线
          while true; do
            # 调用API获取运行中流水线的数量
            RUNNING_COUNT=$(curl --silent --header "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/pipelines?ref=${CI_COMMIT_BRANCH}&status=running" | jq '. | length')
            
            if [ "$RUNNING_COUNT" -eq 0 ]; then
              echo "当前分支没有运行中的流水线,继续执行"
              break
            else
              echo "发现${RUNNING_COUNT}个运行中的流水线,等待30秒后再检查..."
              sleep 30
            fi
          done
    
  3. 提交配置文件即可。

注意:

  • 这种方法会占用runner资源,因为检查job会一直处于运行状态等待,所以优先用方法一。

内容的提问来源于stack exchange,提问作者ahmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 19:51:02