如何合并 GitLab CI 作业上的规则

时间:2021-04-08 17:26:57

标签: yaml gitlab-ci

假设我有这个隐藏的“基础”工作。

.base_job:
  rules:
    - if: "$CI_COMMIT_TAG"
      when: never
    - if: '$CI_PIPELINE_SOURCE == "web"'

我想将这些规则添加到新作业中并能够扩展它们,例如:

job_1:
  rules:
    - <add .base_job here>
    - if: "$CI_MERGE_REQUEST_IID"


job_2:
  rules:
    - <add .base_job here>
    - if: "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH"

请注意,job_1job_2 具有不同的规则,包括来自 .base_job 的规则。

如果我使用 extends,作业将只有自定义规则,因为根据 docs:
You can use extends to merge hashes but not arrays.

到目前为止,我的解决方案是复制粘贴两个作业的规则,但我想让它更加干燥。

关于如何做到这一点的任何提示?

2 个答案:

答案 0 :(得分:4)

正如问题中所指出的,GitLab CI extends 构造不允许合并内部数组(更一般地,YAML 中预期的底层功能是 not(yet) available),所以基本上:

.base_job:
  rules:
    - if: "$CI_COMMIT_TAG"
      when: never
    - if: '$CI_PIPELINE_SOURCE == "web"'

job_1:
  extends: .base_job
  rules:
    - if: "$CI_MERGE_REQUEST_IID"

会导致:

job_1:
  rules:
    - if: "$CI_MERGE_REQUEST_IID"
  # → overwritten

替代解决方案

但是,如果您发现发布的第一个答案过于笨拙且过于冗长,您似乎可以使用 native YAML anchors construct 来做同样的事情。

也就是说,您可以像这样编写 GitLab CI conf 文件:

.base_job:
  rules:
    - &rule_a
      if: "$CI_COMMIT_TAG"
      when: never
    - &rule_b
      if: '$CI_PIPELINE_SOURCE == "web"'
job_a:
  rules:
    - *rule_a
    - if: "$CI_MERGE_REQUEST_IID"
job_b:
  rules:
    - *rule_b
    - if: "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH"

答案 1 :(得分:2)

所以我找到了一种非常难的方法来做到这一点。这并不理想,但至少我可以得到我想要的工作。

我准备了一组规则文本,并使用 !reference 将它们注入到真正的规则 if 中。

.rules_base:
  rules:
    RULE_A: "$CI_COMMIT_TAG"
    RULE_B: "$CI_MERGE_REQUEST_IID"

job_a:
  rules:
    - if: !reference [.rules_base, rules, RULE_A]
    - if: '$CI_PIPELINE_SOURCE == "web"'

job_b:
  rules:
    - if: !reference [.rules_base, rules, RULE_B]

这确实有效,我可以在不同的工作中重复使用相同的规则,同时在必要时还包括新规则。