leobip
leobip

Reputation: 19

GitLab Pipeline: Needs Job to execute only when previous job fail in multi-env. pipeline

I need some help, with these:

I have these pipeline: (4) Stages:

Each one of these stages have two jobs, each Env, means diferent VM, I need the Rollback stage to be execute only when the respective previous fase (test) fails, ex: The Job-4-RollB have to execute only when the Job-3-Test Fails, not any other.

I hope I explained well.

Pipeline-Diagram

Upvotes: 1

Views: 4676

Answers (1)

sytech
sytech

Reputation: 41119

use when: on_failure to do this. Unfortunately, this triggers when any job in the previous stage fails. So, you'll need some method to make the distinction which environment(s) to rollback in the final stage.

If you must have only these 4 pipelines stages, one way to make that determination would be to pass artifacts to the rollback job in order for the rollback job to know whether to perform the rollback. For example, an artifact containing either a 0 or 1.

.env-test:
  stage: test
  script:
    - make test $ENV_NAME > results.txt
  artifacts:
    paths: # could also consider `artifacts:reports:dotenv`
    - results.txt
    when: always

Env-1-Test:
  extends: .env-test
  variables:
    ENV_NAME: "1"

Env-2-Test:
  extends: .env-test
  variables:
    ENV_NAME: "2"


.rollback:
  when: on_failure # runs when 1 or more jobs from previous stage fail
  stage: rollback
  script: |
    test_result="$(cat results.txt)"
    if [[ "${test_results}" == "1" ]]; then
        make rollback 1
    else
        echo "no rollback needed for env 1"
    fi

Env-1-Rollback:
  extends: .rollback
  needs: [Env-1-Test]  # only get the Env-1-Test artifact, start right away

Env-2-Rollback:
  extends: .rollback
  needs: [Env-2-Test] # same, but for Env 2

One advantage of this approach is that needs: will allow the rollback job to run immediately after the corresponding test job fails.

This is probably the best way to handle this scenario.

You can orchestrate a pipeline to get the behavior that each rollback job will strictly only run when the corresponding env fails, but it will require a far more verbose job configuration. Basically every job would need to declare needs: AND every environment needs its own stages for build/test/deploy.

OR

You could make use of parent-child pipelines for each environment, such that each child pipeline's rollback stage corresponds to just 1 job/environment.

Env-1-Child-Trigger:
  trigger:
    include: path/to/pipeline.yaml
  variables:
    ENV_NAME: "1"

Env-2-Child-Trigger:
  trigger:
    include: path/to/pipeline.yaml
  variables:
    ENV_NAME: "2"

Where your pipeline.yaml describes a singular build/deploy/test/rollback pipeline.

This is probably the most concise configuration.

Upvotes: 1

Related Questions