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

如何基于$jobs变量按组控制GitLab CI/CD作业执行顺序?

问题描述

我有3组作业,当前配置下同一stage的所有作业会并发执行。希望基于$jobs变量按以下顺序执行:

  • prep(始终最先执行)
  • 若$jobs字符串变量中包含build1,则执行build1
  • build1执行完成后执行deploy1
  • 若$jobs中包含build2,则执行build2
  • build2执行完成后执行deploy2
  • 若$jobs中包含build3,则执行build3
  • build3执行完成后执行deploy3

补充规则:若build1不存在则跳过build1直接执行build2;若build2不存在则跳过build2,先执行build1再执行build3。

现有CI配置如下:

stages:
  - prep
  - build
  - deploy

getjobs  
  stage: prep  
  script: <script assigns string value with jobs to be ran to $jobs global variable>  
  rules:    
    - if: $CI_COMMIT_MESSAGE =~ /See merge request/
      when: on_success

build1 
  stage: build 
  needs: [getjobs] 
  script: ... 
  rules:   
    - if: $CI_COMMIT_MESSAGE =~ /See merge request/
      when: on_success

deploy1 
  stage: deploy 
  needs: [build1] 
  script: ...
  rules:   
    - if: $CI_COMMIT_MESSAGE =~ /See merge request/
      when: on_success

build2 
  stage: build 
  needs: [getjobs] 
  script: ... 
  rules:   
    - if: $CI_COMMIT_MESSAGE =~ /See merge request/
      when: on_success

deploy2 
  stage: deploy 
  needs: [build2] 
  script: ... 
  rules:   
    - if: $CI_COMMIT_MESSAGE =~ /See merge request/
      when: on_success

build3 
  stage: build 
  needs: [getjobs] 
  script: ... 
  rules:   
    - if: $CI_COMMIT_MESSAGE =~ /See merge request/
      when: on_success

deploy3 
  stage: deploy 
  needs: [build3] 
  script: ... 
  rules:   
    - if: $CI_COMMIT_MESSAGE =~ /See merge request/
      when: on_success

想了解在保留当前stage结构的前提下,是否能实现这种作业顺序依赖。


解决方案

可以实现,核心是通过**needs控制作业执行顺序**,结合**rules基于$jobs变量判断作业是否触发**,同时利用GitLab CI中needs对未触发作业的自动忽略特性(需GitLab 13.10+版本支持)。以下是修改后的完整配置:

stages:
  - prep
  - build
  - deploy

getjobs  
  stage: prep  
  script: <script assigns string value with jobs to be ran to $jobs global variable>  
  rules:    
    - if: $CI_COMMIT_MESSAGE =~ /See merge request/
      when: on_success
  # 将$jobs变量传递给后续作业
  artifacts:
    reports:
      dotenv: jobs.env

build1 
  stage: build 
  needs: [getjobs] 
  script: ... 
  rules:   
    - if: $CI_COMMIT_MESSAGE =~ /See merge request/ && $jobs =~ /build1/
      when: on_success

deploy1 
  stage: deploy 
  needs: [build1] 
  script: ...
  rules:   
    - if: $CI_COMMIT_MESSAGE =~ /See merge request/ && $jobs =~ /build1/
      when: on_success

build2 
  stage: build 
  # 依赖getjobs和build1(若build1触发则等待其完成,未触发则直接执行)
  needs: 
    - getjobs
    - job: build1
      optional: true
  script: ... 
  rules:   
    - if: $CI_COMMIT_MESSAGE =~ /See merge request/ && $jobs =~ /build2/
      when: on_success

deploy2 
  stage: deploy 
  needs: [build2] 
  script: ... 
  rules:   
    - if: $CI_COMMIT_MESSAGE =~ /See merge request/ && $jobs =~ /build2/
      when: on_success

build3 
  stage: build 
  # 依赖getjobs、build1和build2(已触发的作业需等待完成,未触发则跳过)
  needs: 
    - getjobs
    - job: build1
      optional: true
    - job: build2
      optional: true
  script: ... 
  rules:   
    - if: $CI_COMMIT_MESSAGE =~ /See merge request/ && $jobs =~ /build3/
      when: on_success

deploy3 
  stage: deploy 
  needs: [build3] 
  script: ... 
  rules:   
    - if: $CI_COMMIT_MESSAGE =~ /See merge request/ && $jobs =~ /build3/
      when: on_success

关键修改说明:

  1. 传递$jobs变量:在getjobs作业中添加artifacts:reports:dotenv,确保$jobs变量能被后续作业读取使用(GitLab 12.0+支持)。
  2. 基于$jobs触发作业:所有build/deploy作业的rules中添加$jobs =~ /buildX/判断,只有当变量包含对应作业标识时才触发。
  3. 控制作业执行顺序:
    • build2的needs中添加可选依赖build1:若build1被触发,则build2会等待build1完成后再执行;若build1未触发,build2直接执行。
    • build3的needs中添加可选依赖build1和build2:确保build3在build1、build2(如果触发)完成后才执行,符合要求的顺序逻辑。
  4. deploy作业依赖对应build:保持原有needs: [buildX],确保只有对应build完成后才执行deploy,且仅当$jobs包含对应build时触发。

这样既保留了原有的prep/build/deploy stage结构,又完全实现了要求的作业执行顺序规则。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 22:35:16