1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
---
stage: Verify
group: Pipeline Authoring
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# GitLab CI/CD `workflow` keyword **(FREE)**
Use the [`workflow`](index.md#workflow) keyword to control when pipelines are created.
The `workflow` keyword is evaluated before jobs. For example, if a job is configured to run
for tags, but the workflow prevents tag pipelines, the job never runs.
## Common `if` clauses for `workflow:rules`
Some example `if` clauses for `workflow: rules`:
| Example rules | Details |
|------------------------------------------------------|-----------------------------------------------------------|
| `if: '$CI_PIPELINE_SOURCE == "merge_request_event"'` | Control when merge request pipelines run. |
| `if: '$CI_PIPELINE_SOURCE == "push"'` | Control when both branch pipelines and tag pipelines run. |
| `if: $CI_COMMIT_TAG` | Control when tag pipelines run. |
| `if: $CI_COMMIT_BRANCH` | Control when branch pipelines run. |
See the [common `if` clauses for `rules`](../jobs/job_control.md#common-if-clauses-for-rules) for more examples.
## `workflow: rules` examples
In the following example:
- Pipelines run for all `push` events (changes to branches and new tags).
- Pipelines for push events with `-draft` in the commit message don't run, because
they are set to `when: never`.
- Pipelines for schedules or merge requests don't run either, because no rules evaluate to true for them.
```yaml
workflow:
rules:
- if: $CI_COMMIT_MESSAGE =~ /-draft$/
when: never
- if: $CI_PIPELINE_SOURCE == "push"
```
This example has strict rules, and pipelines do **not** run in any other case.
Alternatively, all of the rules can be `when: never`, with a final
`when: always` rule. Pipelines that match the `when: never` rules do not run.
All other pipeline types run. For example:
```yaml
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- if: $CI_PIPELINE_SOURCE == "push"
when: never
- when: always
```
This example prevents pipelines for schedules or `push` (branches and tags) pipelines.
The final `when: always` rule runs all other pipeline types, **including** merge
request pipelines.
### Switch between branch pipelines and merge request pipelines
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/201845) in GitLab 13.8.
To make the pipeline switch from branch pipelines to merge request pipelines after
a merge request is created, add a `workflow: rules` section to your `.gitlab-ci.yml` file.
If you use both pipeline types at the same time, [duplicate pipelines](../jobs/job_control.md#avoid-duplicate-pipelines)
might run at the same time. To prevent duplicate pipelines, use the
[`CI_OPEN_MERGE_REQUESTS` variable](../variables/predefined_variables.md).
The following example is for a project that runs branch and merge request pipelines only,
but does not run pipelines for any other case. It runs:
- Branch pipelines when a merge request is not open for the branch.
- Merge request pipelines when a merge request is open for the branch.
```yaml
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
- if: $CI_COMMIT_BRANCH
```
If GitLab attempts to trigger:
- A merge request pipeline, start the pipeline. For example, a merge request pipeline
can be triggered by a push to a branch with an associated open merge request.
- A branch pipeline, but a merge request is open for that branch, do not run the branch pipeline.
For example, a branch pipeline can be triggered by a change to a branch, an API call,
a scheduled pipeline, and so on.
- A branch pipeline, but there is no merge request open for the branch, run the branch pipeline.
You can also add a rule to an existing `workflow` section to switch from branch pipelines
to merge request pipelines when a merge request is created.
Add this rule to the top of the `workflow` section, followed by the other rules that
were already present:
```yaml
workflow:
rules:
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
when: never
- ... # Previously defined workflow rules here
```
[Triggered pipelines](../triggers/index.md) that run on a branch have a `$CI_COMMIT_BRANCH`
set and could be blocked by a similar rule. Triggered pipelines have a pipeline source
of `trigger` or `pipeline`, so `&& $CI_PIPELINE_SOURCE == "push"` ensures the rule
does not block triggered pipelines.
### Git Flow with merge request pipelines
You can use `workflow: rules` as part of [Git Flow or similar strategies](../../topics/gitlab_flow.md)
with merge request pipelines. With these rules, you can use [merge request pipeline features](../pipelines/merge_request_pipelines.md)
with feature branches, while keeping long-lived branches to support multiple versions
of your software.
For example, to only run pipelines for your merge requests, tags, and protected branches:
```yaml
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_TAG
- if: $CI_COMMIT_REF_PROTECTED
```
This example assumes that your long-lived branches are [protected](../../user/project/protected_branches.md).
## `workflow:rules` templates
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217732) in GitLab 13.0.
GitLab provides templates that set up `workflow: rules`
for common scenarios. These templates help prevent duplicate pipelines.
The [`Branch-Pipelines` template](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates/Workflows/Branch-Pipelines.gitlab-ci.yml)
makes your pipelines run for branches and tags.
Branch pipeline status is displayed in merge requests that use the branch
as a source. However, this pipeline type does not support any features offered by
[merge request pipelines](../pipelines/merge_request_pipelines.md), like
[merged results pipelines](../pipelines/merged_results_pipelines.md)
or [merge trains](../pipelines/merge_trains.md).
This template intentionally avoids those features.
To [include](index.md#include) it:
```yaml
include:
- template: 'Workflows/Branch-Pipelines.gitlab-ci.yml'
```
The [`MergeRequest-Pipelines` template](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates/Workflows/MergeRequest-Pipelines.gitlab-ci.yml)
makes your pipelines run for the default branch, tags, and
all types of merge request pipelines. Use this template if you use any of the
the [merge request pipelines features](../pipelines/merge_request_pipelines.md).
To [include](index.md#include) it:
```yaml
include:
- template: 'Workflows/MergeRequest-Pipelines.gitlab-ci.yml'
```
## Troubleshooting
### Merge request stuck with `Checking pipeline status.` message
If a merge request displays `Checking pipeline status.`, but the message never goes
away (the "spinner" never stops spinning), it might be due to `workflow:rules`.
This issue can happen if a project has [**Pipelines must succeed**](../../user/project/merge_requests/merge_when_pipeline_succeeds.md#require-a-successful-pipeline-for-merge)
enabled, but the `workflow:rules` prevent a pipeline from running for the merge request.
For example, with this workflow, merge requests cannot be merged, because no
pipeline can run:
```yaml
workflow:
rules:
- changes:
- .gitlab/**/**.md
when: never
```
|