summaryrefslogtreecommitdiff
path: root/doc/ci/jobs/job_control.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/ci/jobs/job_control.md')
-rw-r--r--doc/ci/jobs/job_control.md317
1 files changed, 317 insertions, 0 deletions
diff --git a/doc/ci/jobs/job_control.md b/doc/ci/jobs/job_control.md
new file mode 100644
index 00000000000..6e9197c223b
--- /dev/null
+++ b/doc/ci/jobs/job_control.md
@@ -0,0 +1,317 @@
+---
+stage: Verify
+group: Continuous Integration
+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
+---
+
+# Choose when to run jobs **(FREE)**
+
+When a new pipeline starts, GitLab checks the pipeline configuration to determine
+which jobs should run in that pipeline. You can configure jobs to run depending on
+the status of variables, the pipeline type, and so on.
+
+To configure a job to be included or excluded from certain pipelines, you can use:
+
+- [`rules`](../yaml/README.md#rules)
+- [`only`](../yaml/README.md#only--except)
+- [`except`](../yaml/README.md#only--except)
+
+Use [`needs`](../yaml/README.md#needs) to configure a job to run as soon as the
+earlier jobs it depends on finish running.
+
+## Specify when jobs run with `only` and `except`
+
+You can use [`only`](../yaml/README.md#only--except) and [`except`](../yaml/README.md#only--except)
+to control when to add jobs to pipelines.
+
+- Use `only` to define when a job runs.
+- Use `except` to define when a job **does not** run.
+
+### `only:refs` / `except:refs` examples
+
+`only` or `except` used without `refs` is the same as
+[`only:refs` / `except/refs`](../yaml/README.md#onlyrefs--exceptrefs)
+
+In the following example, `job` runs only for:
+
+- Git tags
+- [Triggers](../triggers/README.md#trigger-token)
+- [Scheduled pipelines](../pipelines/schedules.md)
+
+```yaml
+job:
+ # use special keywords
+ only:
+ - tags
+ - triggers
+ - schedules
+```
+
+To execute jobs only for the parent repository and not forks:
+
+```yaml
+job:
+ only:
+ - branches@gitlab-org/gitlab
+ except:
+ - main@gitlab-org/gitlab
+ - /^release/.*$/@gitlab-org/gitlab
+```
+
+This example runs `job` for all branches on `gitlab-org/gitlab`,
+except `main` and branches that start with `release/`.
+
+### `only: variables` / `except: variables` examples
+
+You can use [`except:variables`](../yaml/README.md#onlyvariables--exceptvariables) to exclude jobs based on a commit message:
+
+```yaml
+end-to-end:
+ script: rake test:end-to-end
+ except:
+ variables:
+ - $CI_COMMIT_MESSAGE =~ /skip-end-to-end-tests/
+```
+
+You can use [parentheses](../variables/README.md#parentheses) with `&&` and `||`
+to build more complicated variable expressions:
+
+```yaml
+job1:
+ script:
+ - echo This rule uses parentheses.
+ only:
+ variables:
+ - ($CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "develop") && $MY_VARIABLE
+```
+
+### `only:changes` / `except:changes` examples
+
+You can skip a job if a change is detected in any file with a
+`.md` extension in the root directory of the repository:
+
+```yaml
+build:
+ script: npm run build
+ except:
+ changes:
+ - "*.md"
+```
+
+If you change multiple files, but only one file ends in `.md`,
+the `build` job is still skipped. The job does not run for any of the files.
+
+Read more about how to use `only:changes` and `except:changes`:
+
+- [New branches or tags *without* pipelines for merge requests](#use-onlychanges-without-pipelines-for-merge-requests).
+- [Scheduled pipelines](#use-onlychanges-with-scheduled-pipelines).
+
+#### Use `only:changes` with pipelines for merge requests
+
+With [pipelines for merge requests](../merge_request_pipelines/index.md),
+it's possible to define a job to be created based on files modified
+in a merge request.
+
+Use this keyword with `only: [merge_requests]` so GitLab can find the correct base
+SHA of the source branch. File differences are correctly calculated from any further
+commits, and all changes in the merge requests are properly tested in pipelines.
+
+For example:
+
+```yaml
+docker build service one:
+ script: docker build -t my-service-one-image:$CI_COMMIT_REF_SLUG .
+ only:
+ refs:
+ - merge_requests
+ changes:
+ - Dockerfile
+ - service-one/**/*
+```
+
+In this scenario, if a merge request changes
+files in the `service-one` directory or the `Dockerfile`, GitLab creates
+the `docker build service one` job.
+
+For example:
+
+```yaml
+docker build service one:
+ script: docker build -t my-service-one-image:$CI_COMMIT_REF_SLUG .
+ only:
+ changes:
+ - Dockerfile
+ - service-one/**/*
+```
+
+In this example, the pipeline might fail because of changes to a file in `service-one/**/*`.
+
+A later commit that doesn't have changes in `service-one/**/*`
+but does have changes to the `Dockerfile` can pass. The job
+only tests the changes to the `Dockerfile`.
+
+GitLab checks the **most recent pipeline** that **passed**. If the merge request is mergeable,
+it doesn't matter that an earlier pipeline failed because of a change that has not been corrected.
+
+When you use this configuration, ensure that the most recent pipeline
+properly corrects any failures from previous pipelines.
+
+#### Use `only:changes` without pipelines for merge requests
+
+Without [pipelines for merge requests](../merge_request_pipelines/index.md), pipelines
+run on branches or tags that don't have an explicit association with a merge request.
+In this case, a previous SHA is used to calculate the diff, which is equivalent to `git diff HEAD~`.
+This can result in some unexpected behavior, including:
+
+- When pushing a new branch or a new tag to GitLab, the policy always evaluates to true.
+- When pushing a new commit, the changed files are calculated by using the previous commit
+ as the base SHA.
+
+#### Use `only:changes` with scheduled pipelines
+
+`only:changes` always evaluates as true in [Scheduled pipelines](../pipelines/schedules.md).
+All files are considered to have changed when a scheduled pipeline runs.
+
+### Combine multiple keywords with `only` or `except`
+
+If you use multiple keywords with `only` or `except`, the keywords are evaluated
+as a single conjoined expression. That is:
+
+- `only:` includes the job if **all** of the keys have at least one condition that matches.
+- `except:` excludes the job if **any** of the keys have at least one condition that matches.
+
+With `only`, individual keys are logically joined by an `AND`. A job is added to
+the pipeline if the following is true:
+
+- `(any listed refs are true) AND (any listed variables are true) AND (any listed changes are true) AND (any chosen Kubernetes status matches)`
+
+In the following example, the `test` job is only created when **all** of the following are true:
+
+- The pipeline is [scheduled](../pipelines/schedules.md) **or** runs for `main`.
+- The `variables` keyword matches.
+- The `kubernetes` service is active on the project.
+
+```yaml
+test:
+ script: npm run test
+ only:
+ refs:
+ - main
+ - schedules
+ variables:
+ - $CI_COMMIT_MESSAGE =~ /run-end-to-end-tests/
+ kubernetes: active
+```
+
+With `except`, individual keys are logically joined by an `OR`. A job is **not**
+added if the following is true:
+
+- `(any listed refs are true) OR (any listed variables are true) OR (any listed changes are true) OR (a chosen Kubernetes status matches)`
+
+In the following example, the `test` job is **not** created when **any** of the following are true:
+
+- The pipeline runs for the `main` branch.
+- There are changes to the `README.md` file in the root directory of the repository.
+
+```yaml
+test:
+ script: npm run test
+ except:
+ refs:
+ - main
+ changes:
+ - "README.md"
+```
+
+## Use predefined CI/CD variables to run jobs only in specific pipeline types
+
+You can use [predefined CI/CD variables](../variables/predefined_variables.md) to choose
+which pipeline types jobs run in, with:
+
+- [`rules`](../yaml/README.md#rules)
+- [`only:variables`](../yaml/README.md#onlyvariables--exceptvariables)
+- [`except:variables`](../yaml/README.md#onlyvariables--exceptvariables)
+
+The following table lists some of the variables that you can use, and the pipeline
+types the variables can control for:
+
+- Branch pipelines that run for Git `push` events to a branch, like new commits or tags.
+- Tag pipelines that run only when a new Git tag is pushed to a branch.
+- [Merge request pipelines](../merge_request_pipelines/index.md) that run for changes
+ to a merge request, like new commits or selecting the **Run pipeline** button
+ in a merge request's pipelines tab.
+- [Scheduled pipelines](../pipelines/schedules.md).
+
+| Variables | Branch | Tag | Merge request | Scheduled |
+|--------------------------------------------|--------|-----|---------------|-----------|
+| `CI_COMMIT_BRANCH` | Yes | | | Yes |
+| `CI_COMMIT_TAG` | | Yes | | Yes, if the scheduled pipeline is configured to run on a tag. |
+| `CI_PIPELINE_SOURCE = push` | Yes | Yes | | |
+| `CI_PIPELINE_SOURCE = scheduled` | | | | Yes |
+| `CI_PIPELINE_SOURCE = merge_request_event` | | | Yes | |
+| `CI_MERGE_REQUEST_IID` | | | Yes | |
+
+For example, to configure a job to run for merge request pipelines and scheduled pipelines,
+but not branch or tag pipelines:
+
+```yaml
+job1:
+ script:
+ - echo
+ rules:
+ - if: $CI_PIPELINE_SOURCE == "merge_request_event"
+ - if: $CI_PIPELINE_SOURCE == "scheduled"
+ - if: $CI_PIPELINE_SOURCE == "push"
+ when: never
+```
+
+## Regular expressions
+
+The `@` symbol denotes the beginning of a ref's repository path.
+To match a ref name that contains the `@` character in a regular expression,
+you must use the hex character code match `\x40`.
+
+Only the tag or branch name can be matched by a regular expression.
+The repository path, if given, is always matched literally.
+
+To match the tag or branch name,
+the entire ref name part of the pattern must be a regular expression surrounded by `/`.
+For example, you can't use `issue-/.*/` to match all tag names or branch names
+that begin with `issue-`, but you can use `/issue-.*/`.
+
+Regular expression flags must be appended after the closing `/`. Pattern matching
+is case-sensitive by default. Use the `i` flag modifier, like `/pattern/i`, to make
+a pattern case-insensitive:
+
+```yaml
+job:
+ # use regexp
+ only:
+ - /^issue-.*$/i
+ # use special keyword
+ except:
+ - branches
+```
+
+Use anchors `^` and `$` to avoid the regular expression
+matching only a substring of the tag name or branch name.
+For example, `/^issue-.*$/` is equivalent to `/^issue-/`,
+while just `/issue/` would also match a branch called `severe-issues`.
+
+### `only` / `except` regex syntax
+
+In GitLab 11.9.4, GitLab began internally converting the regexp used
+in `only` and `except` keywords to [RE2](https://github.com/google/re2/wiki/Syntax).
+
+[RE2](https://github.com/google/re2/wiki/Syntax) limits the set of available features
+due to computational complexity, and some features, like negative lookaheads, became unavailable.
+Only a subset of features provided by [Ruby Regexp](https://ruby-doc.org/core/Regexp.html)
+are now supported.
+
+From GitLab 11.9.7 to GitLab 12.0, GitLab provided a feature flag to
+let you use unsafe regexp syntax. After migrating to safe syntax, you should disable
+this feature flag again:
+
+```ruby
+Feature.enable(:allow_unsafe_ruby_regexp)
+```