I need a way to run a job in the pipeline depending if another job’s result.
Right now I use this simplified CD definition, on gitlab.com:
# Staging branch: just deploy to staging
deploy staging (from staging branch):
rules:
- if: $CI_COMMIT_BRANCH == 'staging'
script:
- deploy staging
# Main branch: check if staging branch exists
staging branch presence:
rules:
- if: $CI_COMMIT_BRANCH == 'main'
variables:
GIT_STRATEGY: none
script:
- result=0
# Exit code 0 = staging branch present; 2 = staging branch absent
- git ls-remote --exit-code --heads $CI_REPOSITORY_URL staging || result=$?
# Can only continue if branch is absent
- test $result -eq 2
# Absent staging branch: deploy staging from main branch; then deploy production
deploy staging (from main branch):
rules:
- if: $CI_COMMIT_BRANCH == 'main'
needs:
- staging branch presence
script:
- deploy staging
deploy production (after deploy staging):
rules:
- if: $CI_COMMIT_BRANCH == 'main'
needs:
- deploy staging (from main branch)
script:
- deploy production
# Staging branch exists: just deploy to production directly
deploy production (⚠ without deploying staging):
rules:
- if: $CI_COMMIT_BRANCH == 'main'
needs:
- staging branch presence
when: on_failure
script:
- deploy production
The intention is:
- If there’s a branch called
staging
, and you run a pipeline:- If you run it from the
staging
branch, just deploy to staging. - If you run it from the
main
branch, just deploy to production.
- If you run it from the
- If there’s no
staging
branch and you run a pipeline from themain
branch:- Deploy to staging.
- If successful, deploy to production.
Since there’s no way for a rule to detect the presence of a branch regardless if it’s the one being checked out or not, then there’s the staging branch presence
job. This job goes or depending on that, and other jobs will use when:on_failure
to react.
However, since the job can actually fail (expectedly) on some circumstances, the whole pipeline is marked as failed. But it should be successful in any of the 2 cases.
I could set staging branch presence
with allow_failure:true
, but then the docs say:
on_success
(default): Run the job only when all jobs in earlier stages succeed or haveallow_failure: true
.
So the when:on_failure
wouldn’t trigger.
In my mind, the ideal solution would be:
- Gitlab fixes
allow_failure:exit_codes
, currently buggy. - Support for a new
when:on_exit_codes
option. - I configure
staging branch presence
withallow_failure:exit_codes = [2]
. - I configure
deploy production (⚠ without deploying staging)
withwhen:on_exit_codes = [2]
.
Do you think this feature makes sense? Or I should just formulate the pipeline differently?