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

如何使用YAML锚点避免CI脚本代码段重复?

解决GitLab CI重复作业的YAML锚点正确用法

问题场景

你有多个结构相似的CI作业,仅tags和脚本中的部分变量值不同,示例代码如下:

test a:
  stage: test
  tags:
    - a
  interruptible: true
  rules: 
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
  script:
    - echo "env is $(env)"
    - echo etcetera
    - echo and so on
    - docker build -t a -f Dockerfile.a .
test b:
  stage: test
  tags:
    - b
  interruptible: true
  rules: 
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
  script:
    - echo "env is $(env)"
    - echo etcetera
    - echo and so on
    - docker build -t b -f Dockerfile.b .

尝试用锚点统一脚本时遇到两种问题:

  1. 直接定义脚本列表锚点,在作业中用<<: *which_ref会触发YAMLException: cannot merge mappings; the provided source object is unacceptable错误
  2. 定义包含script节点的锚点,作业中声明新的script会覆盖锚点内容

正确解决方案

方案1:复用完整作业模板(推荐)

定义包含所有重复字段的作业模板锚点,每个作业通过继承模板并覆盖差异字段(如tags)、设置专属变量来实现复用:

# 定义通用作业模板锚点
.job_template: &job_template
  stage: test
  interruptible: true
  rules: 
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
  script:
    - echo "env is $(env)"
    - echo etcetera
    - echo and so on
    - docker build -t $WHICH -f Dockerfile.$WHICH .

# 作业a:继承模板+覆盖差异
test a:
  <<: *job_template
  tags:
    - a
  variables:
    WHICH: a

# 作业b:继承模板+覆盖差异
test b:
  <<: *job_template
  tags:
    - b
  variables:
    WHICH: b

这种方式直接复用整个作业的重复配置,仅需修改每个作业独有的tags和WHICH变量,完全避免重复代码。

方案2:仅复用脚本列表

如果只需要复用script部分的代码,可单独定义脚本列表锚点,在作业的script列表中直接引用锚点即可(注意不要用映射合并语法<<:):

# 定义通用脚本列表锚点
.script_template: &script_template
  - echo "env is $(env)"
  - echo etcetera
  - echo and so on
  - docker build -t $WHICH -f Dockerfile.$WHICH .

test a:
  stage: test
  tags:
    - a
  interruptible: true
  rules: 
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
  variables:
    WHICH: a
  script:
    # 可添加作业专属前置步骤
    - echo "Starting job a"
    # 引用通用脚本列表
    - *script_template

test b:
  stage: test
  tags:
    - b
  interruptible: true
  rules: 
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
  variables:
    WHICH: b
  script:
    - *script_template

错误原因说明

  • 第一种错误:<<:是YAML中**合并映射(键值对结构)**的语法,不能用于列表(数组)结构中,因此直接在script列表里用<<: *which_ref会触发语法错误。
  • 第二种错误:当锚点包含script键时,作业中重新声明script会覆盖锚点里的同名键,YAML中后定义的键会优先覆盖之前的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 17:05:46