Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to merge sequences in .gitlab-ci.yml?

Tags:

yaml

gitlab-ci

I am trying to remove some redundancy in setting up several tasks within GitLab CI. As a (greatly) simplified example, I have two jobs involving a call to apt-get update:

job1:
  before_script:
    - apt-get update
    - apt-get install foo

job2:
  before_script:
    - apt-get update
    - apt-get install bar

Not being a big fan of repetitions, I hoped that I would be able to "clean up" the yaml through the help of anchors as follows:

.update: &update
  before_script:
    - apt-get update

job1:
  <<: *update
  before_script:
    - apt-get install foo

job2:
  <<: *update
  before_script:
    - apt-get install bar

However, it appears that the before_script stanzas are not merged with *update. Instead, I find latter one being overwritten. This is in contrast to the GitLab CI docs as well as the example on Wikipedia, though.

Through some experimentation, I managed to get the following to run:

.update: &update apt-get update

job1:
  before_script: 
    - *update
    - apt-get install foo

job2:
  before_script: 
    - *update
    - apt-get install bar

Clearly a step forward. But given that I intend to go for more complex substitutions, this is hardly satisfactory. For reference: This is on GitLab v 8.12.

like image 607
DaSourcerer Avatar asked Jul 10 '17 11:07

DaSourcerer


2 Answers

I think you misunderstand what the <<: merge does. It pre-fills the mapping that it is part of, with the key-value pairs from the anchored mapping. And any keys that follow the merge are added to that mapping, with the value for a key that already existed in one of the merged mappings being overwritten with that value. Here is the documentation.

There is no such thing as appending of sequences in YAML, such as you describe in your expectations. The merge is at the level of the keys, not recursively (not for mapping, nor for sequences)

like image 164
Anthon Avatar answered Oct 19 '22 03:10

Anthon


Gitlab 13.9 added !reference keyword:

.setup:
  before_script: apt-get update

job1:
  before_script: 
    - !reference [.setup, before_script]
    - apt-get install foo

job2:
  before_script: 
    - !reference [.setup, before_script]
    - apt-get install bar

The union of reference and extend is really good and will help you battle redundancy.

like image 33
abranhe Avatar answered Oct 19 '22 05:10

abranhe