Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to merge rules on a GitLab CI Job

Tags:

yaml

gitlab-ci

Let's suppose I have this hidden "base" job.

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

I'd like to add these rules to a new job and be able to extend them too, e.g.:

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"

Note that job_1 and job_2 have different rules, including the ones from .base_job.

If I were to use extends, the jobs would have only the custom rule because according to the docs:
You can use extends to merge hashes but not arrays.

My solution so far is to copy-paste the rules for both jobs but I'd like to keep it more DRY.

Any tips on how to do it?

like image 831
Ícaro Avatar asked Apr 08 '21 17:04

Ícaro


People also ask

Is it possible to merge rules in GitLab?

From the GitLab Documentation, You can use extends to merge hashes but not arrays. Since rules are listed as arrays, I suppose it can’t be merged. Would be nice to have such a feature though. As @xingrz1993 said extends does not merge arrays.

How to switch from branch to merge request pipelines in GitLab?

In GitLab 13.7 and later , you can add workflow:rules to switch from branch pipelines to merge request pipelines . After a merge request is open on the branch, the pipeline switches to a merge request pipeline. If you push an invalid CI/CD configuration to a merge request’s branch, two failed pipelines appear in the pipelines tab.

How to avoid duplicate pipelines in GitLab?

You can also avoid duplicate pipelines by changing the job rules to avoid either push (branch) pipelines or merge request pipelines. However, if you use a - when: always rule without workflow: rules, GitLab still displays a pipeline warning .

Can a single action trigger multiple GitLab pipelines?

Before GitLab 13.3 , rules that use both || and && may evaluate with an unexpected order of operations. If a job uses rules, a single action, like pushing a commit to a branch, can trigger multiple pipelines. You don’t have to explicitly configure rules for multiple types of pipeline to trigger them accidentally.


2 Answers

As pointed out in the question, the GitLab CI extends construct does not allow one to merge inner arrays (and more generally the expected underlying feature in YAML is not(yet) available), so basically:

.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"

would lead to:

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

Alternative solution

However, if you find that the first answer posted is too hacky and too verbose, it appears you could just use the native YAML anchors construct to do the same.

Namely, you might write a GitLab CI conf-file like this:

.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"
like image 121
ErikMD Avatar answered Oct 16 '22 10:10

ErikMD


So I've found a very hacky way of doing this. It is not ideal but at least I could get what I wanted working.

Warning: This is only available starting on GitLab 14.3, which as of Sep/21 is in a pre-release state.

I prepare a set of just the texts of the rules and inject them in a real rule if using !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]

This actually works and I can reuse the same rules on different jobs while also including new rules, if necessary.

like image 21
Ícaro Avatar answered Oct 16 '22 09:10

Ícaro