How to eliminate code repitition in a ".gitlab-ci.yml"-script that uses stages that are almost identical?

Viewed 159

I have a gitlab-ci/cd.yaml-file that executes 2 test scripts. As you can see there is a lot of repetition going on. As a matter of fact, both stages are identical, except for their "script" value.

For the smoke-suite the value is

  • npm run docker_smoke --single-run --progress false

For the regression-suite the value is

  • npm run docker_regression --single-run --progress false
image: node-karma-protractor

stages:
  - suiteSmoke
  - suiteRegression

before_script:
  - npm install

# Smoke suite =================================
smoke_suite:
  stage: suiteSmoke
  tags:
    - docker-in-docker
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - node_modules/
  script:
    - npm run docker_smoke --single-run --progress false
  retry: 1
  #saving the HTML-Report
  artifacts:
    when: on_failure
    paths:
      - reporting/
    expire_in: 1 week
  allow_failure: true

# Regression suite ============================
regression_suite:
  stage: suiteRegression
  tags:
    - docker-in-docker
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - node_modules/
  script:
    - npm run docker_regression --single-run --progress false
  retry: 1
  #saving the HTML-Report
  artifacts:
    when: on_failure
    paths:
      - reporting/
    expire_in: 1 week
  allow_failure: true

The script needs to adhere to the following rules:

  • The tests need to run consecutively (as problems may occur if they're executed in a simultaneous fashion). The order of execution doesn't matter, though.
  • If either of the test fails, it gets a second chance and will be executed one more time.
  • If one of the tests fails on both attempts and is marked as a 'failed', the other one will still be executed regardless.

Is there a way to eliminate all this repetition via abstraction? How can this be achieved?

2 Answers

You can define templates and then extend your jobs with them.

Documentation: https://docs.gitlab.com/ee/ci/yaml/#extends

Example:

.job-template:
  tags:
    - tag
  allow_failure: true

job1:
  extends:
    - .job-template
  script:
    - do something

job2:
  extends:
    - .job-template
  script:
    - do something

Gitlab provides a couple of mechanisms to prevent duplications in your pipelines namely YAML anchors and the extends keyword while the extends keyword is recommended for readability.

Applied to your example your pipeline can look like this:

image: node-karma-protractor

stages:
  - suiteSmoke
  - suiteRegression

.test:suite:
  stage: suiteSmoke
  tags:
    - docker-in-docker
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - node_modules/
  before_script:
    - npm install
  retry: 1
  #saving the HTML-Report
  artifacts:
    when: on_failure
    paths:
      - reporting/
    expire_in: 1 week
  allow_failure: true

# Smoke suite =================================
smoke_suite:
  extends: .test:suite
  script:
    - npm run docker_smoke --single-run --progress false

# Regression suite ============================
regression_suite:
  extends: .test:suite
  script:
    - npm run docker_regression --single-run --progress false
Related