Search code examples
gitlabcontinuous-integrationyamlgitlab-cipipeline

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


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?


Solution

  • 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