Merge requests
Goal
Learn how to...
- run pipelines in the context of a merge request using rules
- use template to avoid repetition when using rules
Task 1: Use rules to run in merge request context
In the last chapter about rules
, you learned how to use $CI_PIPELINE_SOURCE
to restrict execution to specific events. You will need this now.
On the branch main
, add rules to the jobs to specify when to run them:
- For the jobs
lint
, audit
, unit_tests
, build
and test
, add rules so that the jobs are executed when...
- pushing to the default branch
- running in merge request context
- Run the job
trigger
only when pushing to the default branch
- Run the job
deploy
only when on the branches dev
and live
- Do not modify the existing rules for the job
pages
Afterwards check the pipeline in the GitLab UI. You should see a successful pipeline run.
Hint (Click if you are stuck)
$CI_PIPELINE_SOURCE
can take the values push
and merge_request_event
in this context. $CI_COMMIT_REF_NAME
contains the name of the Git reference (e.g. branch) the pipeline is running on. $CI_DEFAULT_BRANCH
contains the name of the default branch of the repository in the current project. You can use the logical operator &&
to combine multiple conditions.
Solution (Click if you are stuck)
| workflow:
rules:
- if: $CI_DEPLOY_FREEZE
when: never
- if: $CI_PIPELINE_SOURCE == 'push'
- if: $CI_PIPELINE_SOURCE == 'web'
- if: $CI_PIPELINE_SOURCE == 'schedule'
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
- if: $CI_PIPELINE_SOURCE == 'pipeline'
- if: $CI_PIPELINE_SOURCE == 'api'
when: never
- if: $CI_PIPELINE_SOURCE == 'trigger'
when: never
include:
- local: go.yaml
stages:
- check
- build
- test
- deploy
- trigger
default:
image: golang:1.19.2
lint:
stage: check
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
script:
- go fmt .
audit:
stage: check
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
script:
- go vet .
unit_tests:
stage: check
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
script:
- go install gotest.tools/gotestsum@latest
- gotestsum --junitfile report.xml
artifacts:
when: always
reports:
junit: report.xml
build:
stage: build
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
extends:
- .build-go
artifacts:
paths:
- hello
test:
stage: test
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
image: alpine
script:
- ./hello
deploy:
stage: deploy
rules:
- if: $CI_COMMIT_REF_NAME == "dev"
- if: $CI_COMMIT_REF_NAME == "live"
environment:
name: ${CI_COMMIT_REF_NAME}
before_script:
- apt-get update
- apt-get -y install curl ca-certificates
script:
- |
curl https://seat${SEAT_INDEX}.${CI_COMMIT_REF_NAME}.webdav.inmylab.de/ \
--fail \
--verbose \
--upload-file hello \
--user seat${SEAT_INDEX}:${PASS}
pages:
stage: deploy
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
image: alpine
script:
- cp hello public/
artifacts:
paths:
- public
trigger:
stage: trigger
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
trigger:
include: child.yaml
|
If you want to jump to the solution, execute the following command:
git checkout upstream/160_gitlab_ci/140_merge_requests -- '*'
Task 2: Create a merge request
Now we want to check which jobs are executed in the context of a merge request:
- Create a new branch based on
main
- Create a merge request into
main
Afterwards check the pipeline in the GitLab UI. You should see a successful pipeline run.
Bonus: Explore additional predefined variables
On the branch of the merge request, add a job and run printenv
to get a list of variables available to the pipeline. Check out additional variables specific to merge request pipelines. See also the official documentation.
Task 3: Avoid repetition using rule templates
In the first task we have implemented the same set of rules for multiple jobs. By combining rules with templates, this repetition can be avoided.
- Create an inline template called
.run-on-push-to-default
with the corresponding rule(s)
- Create a second inline template called
.run-on-push-and-mr
with the corresponding rule(s)
- Modify the jobs to use the rule templates
Afterwards check the pipeline in the GitLab UI. You should see a successful pipeline run.
Hint (Click if you are stuck)
Use extends
to use the rule template in a job.
Remember that only variables
are kumulative. All other keywords overwrite each other in the order of appearance.
Solution (Click if you are stuck)
| workflow:
rules:
- if: $CI_DEPLOY_FREEZE
when: never
- if: $CI_PIPELINE_SOURCE == 'push'
- if: $CI_PIPELINE_SOURCE == 'web'
- if: $CI_PIPELINE_SOURCE == 'schedule'
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
- if: $CI_PIPELINE_SOURCE == 'pipeline'
- if: $CI_PIPELINE_SOURCE == 'api'
when: never
- if: $CI_PIPELINE_SOURCE == 'trigger'
when: never
include:
- local: go.yaml
.run-on-push-to-default-branch:
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
.run-on-push-and-in-mr:
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
stages:
- check
- build
- test
- deploy
- trigger
default:
image: golang:1.19.2
lint:
stage: check
extends:
- .run-on-push-and-in-mr
script:
- go fmt .
audit:
stage: check
extends:
- .run-on-push-and-in-mr
script:
- go vet .
unit_tests:
stage: check
extends:
- .run-on-push-and-in-mr
script:
- go install gotest.tools/gotestsum@latest
- gotestsum --junitfile report.xml
artifacts:
when: always
reports:
junit: report.xml
build:
stage: build
extends:
- .run-on-push-and-in-mr
- .build-go
artifacts:
paths:
- hello
test:
stage: test
extends:
- .run-on-push-and-in-mr
image: alpine
script:
- ./hello
deploy:
stage: deploy
extends:
- .run-on-push-to-default-branch
environment:
name: ${CI_COMMIT_REF_NAME}
before_script:
- apt-get update
- apt-get -y install curl ca-certificates
script:
- |
curl https://seat${SEAT_INDEX}.${CI_COMMIT_REF_NAME}.webdav.inmylab.de/ \
--fail \
--verbose \
--upload-file hello \
--user seat${SEAT_INDEX}:${PASS}
pages:
stage: deploy
extends:
- .run-on-push-to-default-branch
image: alpine
script:
- cp hello public/
artifacts:
paths:
- public
trigger:
stage: trigger
extends:
- .run-on-push-to-default-branch
trigger:
include: child.yaml
|
If you want to jump to the solution, execute the following command:
git checkout upstream/160_gitlab_ci/140_merge_requests_rule_templates -- '*'