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

ica*_*ual 25 yaml gitlab-ci

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

.base_job:
  rules:
    - if: "$CI_COMMIT_TAG"
      when: never
    - if: '$CI_PIPELINE_SOURCE == "web"'
Run Code Online (Sandbox Code Playgroud)

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

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"
Run Code Online (Sandbox Code Playgroud)

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

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

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

有关如何做的任何提示?

Eri*_*kMD 29

正如问题中所指出的,GitLab CIextends构造不允许合并内部数组(更一般地说,YAML 中预期的底层功能尚不可用),所以基本上:

\n
.base_job:\n  rules:\n    - if: "$CI_COMMIT_TAG"\n      when: never\n    - if: \'$CI_PIPELINE_SOURCE == "web"\'\n\njob_1:\n  extends: .base_job\n  rules:\n    - if: "$CI_MERGE_REQUEST_IID"\n
Run Code Online (Sandbox Code Playgroud)\n

会导致:

\n
job_1:\n  rules:\n    - if: "$CI_MERGE_REQUEST_IID"\n  # \xe2\x86\x92 overwritten\n
Run Code Online (Sandbox Code Playgroud)\n

替代解决方案

\n

但是,如果您发现发布的第一个答案太老套且太冗长,那么您似乎可以使用本机 YAML 锚点构造来执行相同的操作。

\n

也就是说,您可以编写如下所示的 GitLab CI conf 文件:

\n
.base_job:\n  rules:\n    - if: "$CI_COMMIT_TAG"\n      when: never\n    - if: \'$CI_PIPELINE_SOURCE == "web"\'\n\njob_1:\n  extends: .base_job\n  rules:\n    - if: "$CI_MERGE_REQUEST_IID"\n
Run Code Online (Sandbox Code Playgroud)\n

  • 刚刚确认它确实有效,谢谢您的帮助! (6认同)

ica*_*ual 24

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

警告:此功能仅从 GitLab 14.3 开始可用,截至 9 月 21 日,该版本处于预发布状态。

我准备了一组规则文本,并if使用!reference.

.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]
Run Code Online (Sandbox Code Playgroud)

这实际上是有效的,我可以在不同的工作中重复使用相同的规则,同时如果需要的话还可以包括新的规则。

  • 值得注意的是,GitlabCI 从版本 14.3 开始支持规则中的“!reference”标签(https://docs.gitlab.com/ee/ci/yaml/index.html#reference-tags)(在版本历史记录下查看) (3认同)

小智 5

您实际上可以将一组规则声明为数组,并将它们合并到每个作业中:

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

.base_job:
  rules: !reference [.base_rules]

job_1:
  rules:
    - if: "$CI_MERGE_REQUEST_ID"
    - !reference [.base_rules]

job_2:
  rules:
    - if: "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH"
    - !reference [.base_rules]
Run Code Online (Sandbox Code Playgroud)

  • @Sigmatics 不,规则总是与 OR 组合。但根据德摩根定律 (https://en.wikipedia.org/wiki/De_Morgan's_laws),您可以从 OR &amp; NOT 中得出 AND。如果您可以反转条件,然后使用“when: never”为它们创建规则,则可以使用 OR 组合反向规则,其方式相当于使用 AND 组合非反向规则。 (2认同)