3

We have a gitlab-ci yaml file with duplicate parts.

test:client:
  before_script:
    - node -v
    - yarn install
  cache:
    untracked: true
    key: client
    paths:
      - node_modules/
  script:
    - npm test

build:client:
  before_script:
    - node -v
    - yarn install
  cache:
    untracked: true
    key: client
    paths:
      - node_modules/
    policy: pull
  script:
    - npm build

I would like to know, with the merge syntax, if I can extract the common part to reuse it efficiently in the context of these two parts.

.node_install_common: &node_install_common
  before_script:
    - node -v
    - yarn install
  cache:
    untracked: true
    key: client
    paths:
      - node_modules/

But the real question is: at which indent level do I have to merge the block to ensure policy: pull is applied to the cache section. I tried to so that:

test:client:
  <<: *node_install_common
  script:
    - npm test

test:build:
  <<: *node_install_common
    policy: pull
  script:
    - npm build

But I get an invalid yaml error. How to indent to get the correct merge behavior?

BlackHoleGalaxy
  • 9,160
  • 17
  • 59
  • 103

1 Answers1

8

Note that merge keys are not part of the YAML specification and therefore are not guaranteed to work. They are also specified for the obsolete YAML 1.1 version and have not been updated for the current YAML 1.2 version. We intend to explicitly remove merge keys in upcoming YAML 1.3 (and possibly provide a better alternative).

That being said: There is no merge syntax. the merge key << must be placed like a normal key in a mapping. This means that the key must have the same indentation as other keys. So this would be valid:

test:client:
  <<: *node_install_common
  script:
    - npm test

While this is not:

test:build:
  <<: *node_install_common
    policy: pull
  script:
    - npm build

Note that compared to your code, I added : to the test:client and test:build lines.

Now merge is specified to place all key-value pairs of the referenced mapping into the current mapping if they do not already exist in it. This means that you can not, as you want to, replace values deeper in the subtree – merge does not support partial replacement of subtrees. However, you can use merge multiple times:

.node_install_common: &node_install_common
  before_script:
    - node -v
    - yarn install
  cache: &cache_common
    untracked: true
    key: client
    paths:
      - node_modules/

test:client:
  <<: *node_install_common
  script:
    - npm test

test:build:
  <<: *node_install_common
  cache: # define an own cache mapping instead of letting merge place
         # its version here (which could not be modified)
    <<: *cache_common  # load the common cache content
    policy: pull       # ... and place your additional key-value pair
  script:
    - npm build
flyx
  • 35,506
  • 7
  • 89
  • 126