DEV Community

Michal Bryxí
Michal Bryxí

Posted on

How to dry your .gitlab-ci.yml

Playing around with .gitlab-ci.yml I found few nice things I'd like to share. Let's start with an example:

.frontend_template: &frontend_template
  stage: deploy
  script:
  - npm install netlify-cli -g
  - ember deploy $ENVIRONMENT --verbose
  - netlify deploy -e $ENVIRONMENT -p ./dist -s $NETLIFY_SITE_ID -t $NETLIFY_KEY

.frontend_variables: &frontend_variables
  API_SERVER: "http://${ENVIRONMENT}-api.example.com"
  NETLIFY_SITE_ID: "${ENVIRONMENT}-example-com"

development_frontend:
  <<: *frontend_template
  variables:
    ENVIRONMENT: "development"
    <<: *frontend_variables
  only:
  - master

production_frontend:
  <<: *frontend_template
  variables:
    ENVIRONMENT: "production"
    <<: *frontend_variables
  only:
  - production
Enter fullscreen mode Exit fullscreen mode

There's quite a lot going on, so let's try to decompose it piece by piece:

  • Each job definition that starts with a dot is ignored. So .frontend_template and .frontend_variables do not define active, runnable jobs. This feature is called hidden keys.
  • YAML allows for referencing other parts of itself to prevent copy&pasting. The feature is called anchors. Simply speaking:
    • &frontend_template is copy
    • <<: *frontend_template is paste
  • It might seem weird to have separate frontend_template and frontend_variables, but YAML does not allow complicated merging when using anchors, so that variables key cannot be simply put into frontend_template, because it would be overwritten with the key of the same name at development_frontend / production_frontend level.
  • It is important to import frontend_variables after the definition of ENVIRONMENT, because then we can use that variable in API_SERVER / NETLIFY_SITE_ID.

Bonus: If you ever wonder how does your YAML look like when expanded, you can simply convert your source to something that does not support anchors. Like JSON for example. Try it with the example above.

Top comments (3)

Collapse
 
ridaehamdani profile image
Ridae HAMDANI

There is an other gitlab-ci keywords that can help us such:

  • include that allows the inclusion of an other YAML file to the current gitlab-ci.
  • extends: it allows the job that uses it to inherit from other job .
Collapse
 
michalbryxi profile image
Michal Bryxí

Good point. I should've mention that. IIRC I did not chose that one because at the time of writting the article include and/or extends were restricted only to paid versions of GitLab.

Collapse
 
smichaelsen profile image
Sebastian Michaelsen • Edited

I already knew about the anchors, but here's a ❤️ for the hint with viewing the expanded yaml as JSON.