I use the following configuration (on GitLab Enterprise Edition 14.7.2-ee):
.gitlab-ci.yml
image: ...
include:
- local: '/.gitlab/variables.yml'
- local: '/.gitlab/rules.yml'
- local: '/.gitlab/workflows.yml'
- local: '/.gitlab/stages/test.yml'
- local: '/.gitlab/stages/build.yml'
- local: '/.gitlab/stages/deploy.yml'
stages:
- test
- build
- deploy
.gitlab/variables.yml
variables:
STAGING_BRANCH_NAME: $STAGING_BRANCH_NAME
PRODUCTION_BRANCH_NAME: $PRODUCTION_BRANCH_NAME
.gitlab/rules.yml
.rule_references:
pipeline__skip:
if: '$CI_PIPELINE_SOURCE == "pipeline"'
when: never
mr:
if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
mr_staging:
if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_COMMIT_REF_NAME == $STAGING_BRANCH_NAME'
mr_production:
if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_COMMIT_REF_NAME == $PRODUCTION_BRANCH_NAME'
mr_staging_or_production:
if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_COMMIT_REF_NAME == $STAGING_BRANCH_NAME || $CI_COMMIT_REF_NAME == $PRODUCTION_BRANCH_NAME)'
mr_not_staging_not_production:
if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_COMMIT_REF_NAME != $STAGING_BRANCH_NAME && $CI_COMMIT_REF_NAME != $PRODUCTION_BRANCH_NAME)'
mr_not_staging_not_production__manual:
if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_COMMIT_REF_NAME != $STAGING_BRANCH_NAME && $CI_COMMIT_REF_NAME != $PRODUCTION_BRANCH_NAME)'
when: manual
allow_failure: true
commit_staging:
if: '$CI_COMMIT_BRANCH == $STAGING_BRANCH_NAME'
commit_production:
if: '$CI_COMMIT_BRANCH == $PRODUCTION_BRANCH_NAME'
commit_staging_or_production:
if: '$CI_COMMIT_REF_NAME == $STAGING_BRANCH_NAME || $CI_COMMIT_REF_NAME == $PRODUCTION_BRANCH_NAME'
commit_branch_with_open_mr__skip:
if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
when: never
.gitlab/workflows
workflow:
rules:
- !reference [.rule_references, mr]
- !reference [.rule_references, commit_branch_with_open_mr__skip]
- !reference [.rule_references, commit_staging_or_production]
.gitlab/stages/test.yml
test-unit:
stage: test
needs: []
tags:
- test
script:
- |
echo "using SUB_DOMAIN_TEST SUB_DOMAIN_TEST"
- yarn install --frozen-lockfile && yarn test:unit --silent
coverage: /All\sfiles.*?\s+(\d+.\d+)/
artifacts:
when: always
paths:
- coverage/
reports:
cobertura: coverage/cobertura-coverage.xml
junit: reports/junit.xml
rules:
- !reference [.rule_references, pipeline__skip]
- !reference [.rule_references, mr]
- !reference [.rule_references, commit_staging_or_production]
.gitlab/stages/build.yml
.build_default:
stage: build
needs: ['test-unit']
tags:
- docker
script:
...
build-test:
extends:
- .build_default
environment:
name: test
rules:
- !reference [.rule_references, mr_not_staging_not_production]
build-staging:
extends:
- .build_default
environment:
name: staging
rules:
- !reference [.rule_references, pipeline__skip]
- !reference [.rule_references, mr_staging]
- !reference [.rule_references, commit_staging]
build-production:
extends:
- .build_default
environment:
name: production
rules:
- !reference [.rule_references, pipeline__skip]
- !reference [.rule_references, mr_production]
- !reference [.rule_references, commit_production]
.gitlab/stages/deploy.yml
.deploy-default:
stage: deploy
tags:
- docker
interruptible: true
script:
...
deploy-test:
needs: ['build-test']
extends:
- .deploy-default
environment:
name: test
rules:
- !reference [.rule_references, mr_not_staging_not_production__manual]
deploy-staging:
needs: ['build-staging']
extends:
- .deploy-default
environment:
name: staging
rules:
- !reference [.rule_references, pipeline__skip]
- !reference [.rule_references, mr_staging]
- !reference [.rule_references, commit_staging]
deploy-production:
needs: ['build-production']
extends:
- .deploy-default
environment:
name: production
interruptible: false
rules:
- !reference [.rule_references, pipeline__skip]
- !reference [.rule_references, mr_production]
- !reference [.rule_references, commit_production]
Observation/Problem:
I have an open merge request (from a feature branch into the master branch) and at the same time another open merge request (from the master branch into the release branch). When the feature branch is now merged into the master branch a pipeline is created and run only for the still open MR (master branch into release branch) and not for the master branch since my rules define “don’t create a pipeline for branches with open MR”. Actually, this behavior is correct because I don’t want duplicate pipelines (as explained in Worfklow - Switch between branch pipelines and merge request pipelines).
The problem is, however, that my project’s badge (based on master branch) is showing “pipeline unknown” status now, since the pipeline is a merge request pipeline assigned to the open merge request (master branch into release branch) and not a commit pipeline assigned to the merge commit on master.
If I created duplicate pipelines (a merge request pipeline and a branch pipeline), this problem would not occur. However, it remains unclear to me if it is intended by GitLab that I need duplicate pipelines just to get the pipeline badge showing the correct status (passed or failed instead of unknown). Furthermore, I thought it would be great if GitLab would also display an info text that due to the other open MR only a pipeline in the open MR was created, because otherwise if users don’t switch to CI/CD - Pipelines or to the open merge request (master into release), they might be confused and assume that no pipeline runs on merge, as it happened to me.
What is shown when merging (feature branch into master):
What I would expect to be shown not only when having duplicate but also shared pipelines (for better user experience):
Questions:
Do you know of any solutions to get the correct status for the badge? Does it seem like an intended behavior or more like a GitLab bug to you? Do you also think that displaying an info text regarding the rules in MRs would be helpful?