I have a GitLab repo with CI setup. My .gitlab-ci.yaml looks something like
stages:
- lint
- build
- test
Lint:
rules:
- if: $CI_COMMIT_TAG
when: never
- when: always
...
Build:
stage: build
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_PIPELINE_SOURCE == "web"
- if: $CI_COMMIT_BRANCH == "master"
- if: $CI_COMMIT_TAG
...
Test:
stage: test
# same rules as Build
...
I currently have a merge request open for my branch but, when I push changes, two pipelines get started. One of them includes the lint, build, and test stages while the other only includes the lint stage. Why is that second pipeline being created?
Once you open a merge request for a branch. If you then push to that branch again Gitlab will trigger two pipelines. The first is a push
pipeline. this is triggered because you pushed to the branch. The second pipeline is a merge request
pipeline and is triggered because there is an open merge request.
If you look in the pipelines page you will see both pipelines use the same commit ID, one will be against the branch (the push
pipeline). The other will be against the MR (the merge
pipeline)
So now we understand why there are two pipelines lets look at how gitlab evaluates if the job should be added to the pipeline. Gitlab documents the behaviour of rules: if
as
If we look at each job and its rules.
The lint job has 2 rules, if there is a CI_COMMIT_TAG then never run this job. CI_COMMIT_TAGs are only defined in tag
pipeline, since these pipelines are a push
and a merge
pipeline this rule is not true. So it moves to the next which always evaluates to true. So this job will be added to both pipelines.
In the build job there are 4 rules defined. The first rules checks if the pipelines type is a merge_request_event
I.E a merge pipeline then the job is added.
For the push
pipeline this first rule will not be true so it will move on to rule 2. This rule checks if its a web
pipeline. A web pipeline is a pipeline triggered from the UI. Since this is a push
pipeline, this is also false.
Rule 3 checks if its on the master branch, this will also be false since this is a feature branch.
Rule 4 checks if the CI_COMMIT_TAG is set, thats only set on a tag
pipeline so will not be set on a push
pipeline so this rule is also false.
Since no rules were matched for the build job in the push pipeline the job is not added. The same applies for the test job. So the result is the merge request will have all 3 jobs, and the push pipeline will only have the lint job.
If you dont want both pipelines to trigger you can look at https://docs.gitlab.com/ee/ci/jobs/job_rules.html#avoid-duplicate-pipelines