summaryrefslogtreecommitdiff
path: root/doc/ci/yaml
diff options
context:
space:
mode:
Diffstat (limited to 'doc/ci/yaml')
-rw-r--r--doc/ci/yaml/README.md4874
-rw-r--r--doc/ci/yaml/gitlab_ci_yaml.md8
-rw-r--r--doc/ci/yaml/includes.md6
-rw-r--r--doc/ci/yaml/index.md4935
-rw-r--r--doc/ci/yaml/script.md6
5 files changed, 4949 insertions, 4880 deletions
diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md
index 8e9cf00b160..5ab8653dc35 100644
--- a/doc/ci/yaml/README.md
+++ b/doc/ci/yaml/README.md
@@ -1,4874 +1,8 @@
---
-stage: Verify
-group: Pipeline Execution
-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
-type: reference
+redirect_to: 'index.md'
---
-<!-- markdownlint-disable MD044 -->
-<!-- vale gitlab.Spelling = NO -->
-# Keyword reference for the .gitlab-ci.yml file **(FREE)**
-<!-- vale gitlab.Spelling = YES -->
-<!-- markdownlint-enable MD044 -->
+This document was moved to [another location](index.md).
-This document lists the configuration options for your GitLab `.gitlab-ci.yml` file.
-
-- For a quick introduction to GitLab CI/CD, follow the [quick start guide](../quick_start/index.md).
-- For a collection of examples, see [GitLab CI/CD Examples](../examples/README.md).
-- To view a large `.gitlab-ci.yml` file used in an enterprise, see the [`.gitlab-ci.yml` file for `gitlab`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab-ci.yml).
-
-When you are editing your `.gitlab-ci.yml` file, you can validate it with the
-[CI Lint](../lint.md) tool.
-
-## Job keywords
-
-A job is defined as a list of keywords that define the job's behavior.
-
-The keywords available for jobs are:
-
-| Keyword | Description |
-| :-----------------------------------|:------------|
-| [`after_script`](#after_script) | Override a set of commands that are executed after job. |
-| [`allow_failure`](#allow_failure) | Allow job to fail. A failed job does not cause the pipeline to fail. |
-| [`artifacts`](#artifacts) | List of files and directories to attach to a job on success. |
-| [`before_script`](#before_script) | Override a set of commands that are executed before job. |
-| [`cache`](#cache) | List of files that should be cached between subsequent runs. |
-| [`coverage`](#coverage) | Code coverage settings for a given job. |
-| [`dependencies`](#dependencies) | Restrict which artifacts are passed to a specific job by providing a list of jobs to fetch artifacts from. |
-| [`environment`](#environment) | Name of an environment to which the job deploys. |
-| [`except`](#only--except) | Control when jobs are not created. |
-| [`extends`](#extends) | Configuration entries that this job inherits from. |
-| [`image`](#image) | Use Docker images. |
-| [`include`](#include) | Include external YAML files. |
-| [`inherit`](#inherit) | Select which global defaults all jobs inherit. |
-| [`interruptible`](#interruptible) | Defines if a job can be canceled when made redundant by a newer run. |
-| [`needs`](#needs) | Execute jobs earlier than the stage ordering. |
-| [`only`](#only--except) | Control when jobs are created. |
-| [`pages`](#pages) | Upload the result of a job to use with GitLab Pages. |
-| [`parallel`](#parallel) | How many instances of a job should be run in parallel. |
-| [`release`](#release) | Instructs the runner to generate a [release](../../user/project/releases/index.md) object. |
-| [`resource_group`](#resource_group) | Limit job concurrency. |
-| [`retry`](#retry) | When and how many times a job can be auto-retried in case of a failure. |
-| [`rules`](#rules) | List of conditions to evaluate and determine selected attributes of a job, and whether or not it's created. |
-| [`script`](#script) | Shell script that is executed by a runner. |
-| [`secrets`](#secrets) | The CI/CD secrets the job needs. |
-| [`services`](#services) | Use Docker services images. |
-| [`stage`](#stage) | Defines a job stage. |
-| [`tags`](#tags) | List of tags that are used to select a runner. |
-| [`timeout`](#timeout) | Define a custom job-level timeout that takes precedence over the project-wide setting. |
-| [`trigger`](#trigger) | Defines a downstream pipeline trigger. |
-| [`variables`](#variables) | Define job variables on a job level. |
-| [`when`](#when) | When to run job. |
-
-### Unavailable names for jobs
-
-You can't use these keywords as job names:
-
-- `image`
-- `services`
-- `stages`
-- `types`
-- `before_script`
-- `after_script`
-- `variables`
-- `cache`
-- `include`
-
-### Custom default keyword values
-
-You can set global defaults for some keywords. Jobs that do not define one or more
-of the listed keywords use the value defined in the `default:` section.
-
-These job keywords can be defined inside a `default:` section:
-
-- [`after_script`](#after_script)
-- [`artifacts`](#artifacts)
-- [`before_script`](#before_script)
-- [`cache`](#cache)
-- [`image`](#image)
-- [`interruptible`](#interruptible)
-- [`retry`](#retry)
-- [`services`](#services)
-- [`tags`](#tags)
-- [`timeout`](#timeout)
-
-The following example sets the `ruby:3.0` image as the default for all jobs in the pipeline.
-The `rspec 2.7` job does not use the default, because it overrides the default with
-a job-specific `image:` section:
-
-```yaml
-default:
- image: ruby:3.0
-
-rspec:
- script: bundle exec rspec
-
-rspec 2.7:
- image: ruby:2.7
- script: bundle exec rspec
-```
-
-## Global keywords
-
-Some keywords are not defined in a job. These keywords control pipeline behavior
-or import additional pipeline configuration:
-
-| Keyword | Description |
-|-------------------------|:------------|
-| [`stages`](#stages) | The names and order of the pipeline stages. |
-| [`workflow`](#workflow) | Control what types of pipeline run. |
-| [`include`](#include) | Import configuration from other YAML files. |
-
-### `stages`
-
-Use `stages` to define stages that contain groups of jobs. `stages` is defined globally
-for the pipeline. Use [`stage`](#stage) in a job to define which stage the job is
-part of.
-
-The order of the `stages` items defines the execution order for jobs:
-
-- Jobs in the same stage run in parallel.
-- Jobs in the next stage run after the jobs from the previous stage complete successfully.
-
-For example:
-
-```yaml
-stages:
- - build
- - test
- - deploy
-```
-
-1. All jobs in `build` execute in parallel.
-1. If all jobs in `build` succeed, the `test` jobs execute in parallel.
-1. If all jobs in `test` succeed, the `deploy` jobs execute in parallel.
-1. If all jobs in `deploy` succeed, the pipeline is marked as `passed`.
-
-If any job fails, the pipeline is marked as `failed` and jobs in later stages do not
-start. Jobs in the current stage are not stopped and continue to run.
-
-If no `stages` are defined in the `.gitlab-ci.yml` file, then `build`, `test` and `deploy`
-are the default pipeline stages.
-
-If a job does not specify a [`stage`](#stage), the job is assigned the `test` stage.
-
-If a stage is defined, but no jobs use it, the stage is not visible in the pipeline. This is
-useful for [compliance pipeline configuration](../../user/project/settings/index.md#compliance-pipeline-configuration)
-because:
-
-- Stages can be defined in the compliance configuration but remain hidden if not used.
-- The defined stages become visible when developers use them in job definitions.
-
-To make a job start earlier and ignore the stage order, use
-the [`needs`](#needs) keyword.
-
-### `workflow`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/29654) in GitLab 12.5
-
-Use `workflow:` to determine whether or not a pipeline is created.
-Define this keyword at the top level, with a single `rules:` keyword that
-is similar to [`rules:` defined in jobs](#rules).
-
-You can use the [`workflow:rules` templates](#workflowrules-templates) to import
-a preconfigured `workflow: rules` entry.
-
-`workflow: rules` accepts these keywords:
-
-- [`if`](#rulesif): Check this rule to determine when to run a pipeline.
-- [`when`](#when): Specify what to do when the `if` rule evaluates to true.
- - To run a pipeline, set to `always`.
- - To prevent pipelines from running, set to `never`.
-- [`variables`](#workflowrulesvariables): If not defined, uses the [variables defined elsewhere](#variables).
-
-When no rules evaluate to true, the pipeline does not run.
-
-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.
-
-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:
-
-```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.
-
-If your rules match both branch pipelines and merge request pipelines,
-[duplicate pipelines](../jobs/job_control.md#avoid-duplicate-pipelines) can occur.
-
-#### `workflow:rules:variables`
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/294232) in GitLab 13.11.
-> - [Deployed behind a feature flag](../../user/feature_flags.md), disabled by default.
-> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/300997) in GitLab 13.12.
-> - Enabled on GitLab.com.
-> - Recommended for production use.
-> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#enable-or-disable-workflowrulesvariables). **(FREE SELF)**
-
-There can be
-[risks when disabling released features](../../user/feature_flags.md#risks-when-disabling-released-features).
-Refer to this feature's version history for more details.
-
-You can use [`variables`](#variables) in `workflow:rules:` to define variables for specific pipeline conditions.
-
-For example:
-
-```yaml
-variables:
- DEPLOY_VARIABLE: "default-deploy"
-
-workflow:
- rules:
- - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
- variables:
- DEPLOY_VARIABLE: "deploy-production" # Override globally-defined DEPLOY_VARIABLE
- - if: $CI_COMMIT_REF_NAME =~ /feature/
- variables:
- IS_A_FEATURE: "true" # Define a new variable.
- - when: always # Run the pipeline in other cases
-
-job1:
- variables:
- DEPLOY_VARIABLE: "job1-default-deploy"
- rules:
- - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
- variables: # Override DEPLOY_VARIABLE defined
- DEPLOY_VARIABLE: "job1-deploy-production" # at the job level.
- - when: on_success # Run the job in other cases
- script:
- - echo "Run script with $DEPLOY_VARIABLE as an argument"
- - echo "Run another script if $IS_A_FEATURE exists"
-
-job2:
- script:
- - echo "Run script with $DEPLOY_VARIABLE as an argument"
- - echo "Run another script if $IS_A_FEATURE exists"
-```
-
-When the branch is the default branch:
-
-- job1's `DEPLOY_VARIABLE` is `job1-deploy-production`.
-- job2's `DEPLOY_VARIABLE` is `deploy-production`.
-
-When the branch is `feature`:
-
-- job1's `DEPLOY_VARIABLE` is `job1-default-deploy`, and `IS_A_FEATURE` is `true`.
-- job2's `DEPLOY_VARIABLE` is `default-deploy`, and `IS_A_FEATURE` is `true`.
-
-When the branch is something else:
-
-- job1's `DEPLOY_VARIABLE` is `job1-default-deploy`.
-- job2's `DEPLOY_VARIABLE` is `default-deploy`.
-
-##### Enable or disable workflow:rules:variables **(FREE SELF)**
-
-workflow:rules:variables is under development but ready for production use.
-It is deployed behind a feature flag that is **enabled by default**.
-[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md)
-can opt to disable it.
-
-To enable it:
-
-```ruby
-Feature.enable(:ci_workflow_rules_variables)
-```
-
-To disable it:
-
-```ruby
-Feature.disable(:ci_workflow_rules_variables)
-```
-
-#### `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](../merge_request_pipelines/), like
-[pipelines for merge results](../merge_request_pipelines/#pipelines-for-merged-results)
-or [merge trains](../merge_request_pipelines/pipelines_for_merged_results/merge_trains/).
-This template intentionally avoids those features.
-
-To [include](#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 [pipelines for merge requests features](../merge_request_pipelines/).
-
-To [include](#include) it:
-
-```yaml
-include:
- - template: 'Workflows/MergeRequest-Pipelines.gitlab-ci.yml'
-```
-
-#### Switch between branch pipelines and merge request pipelines
-
-> [Introduced in](https://gitlab.com/gitlab-org/gitlab/-/issues/201845) 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 the pipeline is triggered by:
-
-- A merge request, run a merge request pipeline. For example, a merge request pipeline
- can be triggered by a push to a branch with an associated open merge request.
-- A change to a branch, but a merge request is open for that branch, do not run a branch pipeline.
-- A change to a branch, but without any open merge requests, run a 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/README.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.
-
-### `include`
-
-> [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/42861) to GitLab Free in 11.4.
-
-Use `include` to include external YAML files in your CI/CD configuration.
-You can break down one long `gitlab-ci.yml` file into multiple files to increase readability,
-or reduce duplication of the same configuration in multiple places.
-
-You can also store template files in a central repository and `include` them in projects.
-
-`include` requires the external YAML file to have the extensions `.yml` or `.yaml`,
-otherwise the external file is not included.
-
-You can't use [YAML anchors](#anchors) across different YAML files sourced by `include`.
-You can only refer to anchors in the same file. To reuse configuration from different
-YAML files, use [`!reference` tags](#reference-tags) or the [`extends` keyword](#extends).
-
-`include` supports the following inclusion methods:
-
-| Keyword | Method |
-|:--------------------------------|:------------------------------------------------------------------|
-| [`local`](#includelocal) | Include a file from the local project repository. |
-| [`file`](#includefile) | Include a file from a different project repository. |
-| [`remote`](#includeremote) | Include a file from a remote URL. Must be publicly accessible. |
-| [`template`](#includetemplate) | Include templates that are provided by GitLab. |
-
-When the pipeline starts, the `.gitlab-ci.yml` file configuration included by all methods is evaluated.
-The configuration is a snapshot in time and persists in the database. GitLab does not reflect any changes to
-the referenced `.gitlab-ci.yml` file configuration until the next pipeline starts.
-
-The `include` files are:
-
-- Deep merged with those in the `.gitlab-ci.yml` file.
-- Always evaluated first and merged with the content of the `.gitlab-ci.yml` file,
- regardless of the position of the `include` keyword.
-
-NOTE:
-Use merging to customize and override included CI/CD configurations with local
-configurations. Local configurations in the `.gitlab-ci.yml` file override included configurations.
-
-#### Variables with `include` **(FREE SELF)**
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/284883) in GitLab 13.8.
-> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/294294) in GitLab 13.9.
-
-You can [use some predefined variables in `include` sections](../variables/where_variables_can_be_used.md#gitlab-ciyml-file)
-in your `.gitlab-ci.yml` file:
-
-```yaml
-include:
- project: '$CI_PROJECT_PATH'
- file: '.compliance-gitlab-ci.yml'
-```
-
-For an example of how you can include these predefined variables, and the variables' impact on CI/CD jobs,
-see this [CI/CD variable demo](https://youtu.be/4XR8gw3Pkos).
-
-#### `include:local`
-
-Use `include:local` to include a file that is in the same repository as the `.gitlab-ci.yml` file.
-Use a full path relative to the root directory (`/`).
-
-If you use `include:local`, make sure that both the `.gitlab-ci.yml` file and the local file
-are on the same branch.
-
-You can't include local files through Git submodules paths.
-
-All [nested includes](#nested-includes) are executed in the scope of the same project,
-so it's possible to use local, project, remote, or template includes.
-
-Example:
-
-```yaml
-include:
- - local: '/templates/.gitlab-ci-template.yml'
-```
-
-You can also use shorter syntax to define the path:
-
-```yaml
-include: '.gitlab-ci-production.yml'
-```
-
-Use local includes instead of symbolic links.
-
-##### `include:local` with wildcard file paths
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/25921) in GitLab 13.11.
-> - [Deployed behind a feature flag](../../user/feature_flags.md), disabled by default.
-> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/327315) in GitLab 13.12.
-> - Enabled on GitLab.com.
-> - Recommended for production use.
-> - For GitLab self-managed instances, GitLab administrators can opt to disable it. **(CORE ONLY)**
-
-There can be
-[risks when disabling released features](../../user/feature_flags.md#risks-when-disabling-released-features).
-Refer to this feature's version history for more details.
-
-You can use wildcard paths (`*` and `**`) with `include:local`.
-
-Example:
-
-```yaml
-include: 'configs/*.yml'
-```
-
-When the pipeline runs, GitLab:
-
-- Adds all `.yml` files in the `configs` directory into the pipeline configuration.
-- Does not add `.yml` files in subfolders of the `configs` directory. To allow this,
- add the following configuration:
-
- ```yaml
- # This matches all `.yml` files in `configs` and any subfolder in it.
- include: 'configs/**.yml'
-
- # This matches all `.yml` files only in subfolders of `configs`.
- include: 'configs/**/*.yml'
- ```
-
-The wildcard file paths feature is under development but ready for production use.
-It is deployed behind a feature flag that is **enabled by default**.
-[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md)
-can opt to disable it.
-
-To enable it:
-
-```ruby
-Feature.enable(:ci_wildcard_file_paths)
-```
-
-To disable it:
-
-```ruby
-Feature.disable(:ci_wildcard_file_paths)
-```
-
-#### `include:file`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53903) in GitLab 11.7.
-
-To include files from another private project on the same GitLab instance,
-use `include:file`. You can use `include:file` in combination with `include:project` only.
-Use a full path, relative to the root directory (`/`).
-
-For example:
-
-```yaml
-include:
- - project: 'my-group/my-project'
- file: '/templates/.gitlab-ci-template.yml'
-```
-
-You can also specify a `ref`. If you do not specify a value, the ref defaults to the `HEAD` of the project:
-
-```yaml
-include:
- - project: 'my-group/my-project'
- ref: main
- file: '/templates/.gitlab-ci-template.yml'
-
- - project: 'my-group/my-project'
- ref: v1.0.0
- file: '/templates/.gitlab-ci-template.yml'
-
- - project: 'my-group/my-project'
- ref: 787123b47f14b552955ca2786bc9542ae66fee5b # Git SHA
- file: '/templates/.gitlab-ci-template.yml'
-```
-
-All [nested includes](#nested-includes) are executed in the scope of the target project.
-You can use local (relative to target project), project, remote, or template includes.
-
-##### Multiple files from a project
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/26793) in GitLab 13.6.
-> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/271560) in GitLab 13.8.
-
-You can include multiple files from the same project:
-
-```yaml
-include:
- - project: 'my-group/my-project'
- ref: main
- file:
- - '/templates/.builds.yml'
- - '/templates/.tests.yml'
-```
-
-#### `include:remote`
-
-Use `include:remote` with a full URL to include a file from a different location.
-The remote file must be publicly accessible by an HTTP/HTTPS `GET` request, because
-authentication in the remote URL is not supported. For example:
-
-```yaml
-include:
- - remote: 'https://gitlab.com/example-project/-/raw/main/.gitlab-ci.yml'
-```
-
-All [nested includes](#nested-includes) execute without context as a public user,
-so you can only `include` public projects or templates.
-
-#### `include:template`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53445) in GitLab 11.7.
-
-Use `include:template` to include `.gitlab-ci.yml` templates that are
-[shipped with GitLab](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates).
-
-For example:
-
-```yaml
-# File sourced from the GitLab template collection
-include:
- - template: Auto-DevOps.gitlab-ci.yml
-```
-
-Multiple `include:template` files:
-
-```yaml
-include:
- - template: Android-Fastlane.gitlab-ci.yml
- - template: Auto-DevOps.gitlab-ci.yml
-```
-
-All [nested includes](#nested-includes) are executed only with the permission of the user,
-so it's possible to use project, remote or template includes.
-
-#### Nested includes
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/56836) in GitLab 11.9.
-
-Use nested includes to compose a set of includes.
-
-You can have up to 100 includes, but you can't have duplicate includes.
-
-In [GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/issues/28212) and later, the time limit
-to resolve all files is 30 seconds.
-
-#### Additional `includes` examples
-
-View [additional `includes` examples](includes.md).
-
-## Keyword details
-
-The following topics explain how to use keywords to configure CI/CD pipelines.
-
-### `image`
-
-Use `image` to specify [a Docker image](../docker/using_docker_images.md#what-is-an-image) to use for the job.
-
-For:
-
-- Usage examples, see [Define `image` in the `.gitlab-ci.yml` file](../docker/using_docker_images.md#define-image-in-the-gitlab-ciyml-file).
-- Detailed usage information, refer to [Docker integration](../docker/index.md) documentation.
-
-#### `image:name`
-
-An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
-
-For more information, see [Available settings for `image`](../docker/using_docker_images.md#available-settings-for-image).
-
-#### `image:entrypoint`
-
-An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
-
-For more information, see [Available settings for `image`](../docker/using_docker_images.md#available-settings-for-image).
-
-#### `services`
-
-Use `services` to specify a [service Docker image](../services/index.md), linked to a base image specified in [`image`](#image).
-
-For:
-
-- Usage examples, see [Define `services` in the `.gitlab-ci.yml` file](../services/index.md#define-services-in-the-gitlab-ciyml-file).
-- Detailed usage information, refer to [Docker integration](../docker/index.md) documentation.
-- Example services, see [GitLab CI/CD Services](../services/index.md).
-
-##### `services:name`
-
-An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
-
-For more information, see [Available settings for `services`](../services/index.md#available-settings-for-services).
-
-##### `services:alias`
-
-An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
-
-For more information, see [Available settings for `services`](../services/index.md#available-settings-for-services).
-
-##### `services:entrypoint`
-
-An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
-
-For more information, see [Available settings for `services`](../services/index.md#available-settings-for-services).
-
-##### `services:command`
-
-An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
-
-For more information, see [Available settings for `services`](../services/index.md#available-settings-for-services).
-
-### `script`
-
-Use `script` to specify a shell script for the runner to execute.
-
-All jobs except [trigger jobs](#trigger) require a `script` keyword.
-
-For example:
-
-```yaml
-job:
- script: "bundle exec rspec"
-```
-
-You can use [YAML anchors with `script`](#yaml-anchors-for-scripts).
-
-The `script` keyword can also contain several commands in an array:
-
-```yaml
-job:
- script:
- - uname -a
- - bundle exec rspec
-```
-
-Sometimes, `script` commands must be wrapped in single or double quotes.
-For example, commands that contain a colon (`:`) must be wrapped in single quotes (`'`).
-The YAML parser needs to interpret the text as a string rather than
-a "key: value" pair.
-
-For example, this script uses a colon:
-
-```yaml
-job:
- script:
- - curl --request POST --header 'Content-Type: application/json' "https://gitlab/api/v4/projects"
-```
-
-To be considered valid YAML, you must wrap the entire command in single quotes. If
-the command already uses single quotes, you should change them to double quotes (`"`)
-if possible:
-
-```yaml
-job:
- script:
- - 'curl --request POST --header "Content-Type: application/json" "https://gitlab/api/v4/projects"'
-```
-
-You can verify the syntax is valid with the [CI Lint](../lint.md) tool.
-
-Be careful when using these characters as well:
-
-- `{`, `}`, `[`, `]`, `,`, `&`, `*`, `#`, `?`, `|`, `-`, `<`, `>`, `=`, `!`, `%`, `@`, `` ` ``.
-
-If any of the script commands return an exit code other than zero, the job
-fails and further commands are not executed. Store the exit code in a variable to
-avoid this behavior:
-
-```yaml
-job:
- script:
- - false || exit_code=$?
- - if [ $exit_code -ne 0 ]; then echo "Previous command failed"; fi;
-```
-
-#### `before_script`
-
-Use `before_script` to define an array of commands that should run before each job,
-but after [artifacts](#artifacts) are restored.
-
-Scripts you specify in `before_script` are concatenated with any scripts you specify
-in the main [`script`](#script). The combine scripts execute together in a single shell.
-
-You can overwrite a globally-defined `before_script` if you define it in a job:
-
-```yaml
-default:
- before_script:
- - echo "Execute this script in all jobs that don't already have a before_script section."
-
-job1:
- script:
- - echo "This script executes after the global before_script."
-
-job:
- before_script:
- - echo "Execute this script instead of the global before_script."
- script:
- - echo "This script executes after the job's `before_script`"
-```
-
-You can use [YAML anchors with `before_script`](#yaml-anchors-for-scripts).
-
-#### `after_script`
-
-Use `after_script` to define an array of commands that run after each job,
-including failed jobs.
-
-If a job times out or is cancelled, the `after_script` commands do not execute.
-An [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/15603) exists to support
-executing `after_script` commands for timed-out or cancelled jobs.
-
-Scripts you specify in `after_script` execute in a new shell, separate from any
-`before_script` or `script` scripts. As a result, they:
-
-- Have a current working directory set back to the default.
-- Have no access to changes done by scripts defined in `before_script` or `script`, including:
- - Command aliases and variables exported in `script` scripts.
- - Changes outside of the working tree (depending on the runner executor), like
- software installed by a `before_script` or `script` script.
-- Have a separate timeout, which is hard coded to 5 minutes. See the
- [related issue](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2716) for details.
-- Don't affect the job's exit code. If the `script` section succeeds and the
- `after_script` times out or fails, the job exits with code `0` (`Job Succeeded`).
-
-```yaml
-default:
- after_script:
- - echo "Execute this script in all jobs that don't already have an after_script section."
-
-job1:
- script:
- - echo "This script executes first. When it completes, the global after_script executes."
-
-job:
- script:
- - echo "This script executes first. When it completes, the job's `after_script` executes."
- after_script:
- - echo "Execute this script instead of the global after_script."
-```
-
-You can use [YAML anchors with `after_script`](#yaml-anchors-for-scripts).
-
-#### Script syntax
-
-You can use syntax in [`script`](README.md#script) sections to:
-
-- [Split long commands](script.md#split-long-commands) into multiline commands.
-- [Use color codes](script.md#add-color-codes-to-script-output) to make job logs easier to review.
-- [Create custom collapsible sections](../jobs/index.md#custom-collapsible-sections)
- to simplify job log output.
-
-### `stage`
-
-Use `stage` to define which stage a job runs in. Jobs in the same
-`stage` can execute in parallel (subject to [certain conditions](#use-your-own-runners)).
-
-Jobs without a `stage` entry use the `test` stage by default. If you do not define
-[`stages`](#stages) in the pipeline, you can use the 5 default stages, which execute in
-this order:
-
-- [`.pre`](#pre-and-post)
-- `build`
-- `test`
-- `deploy`
-- [`.post`](#pre-and-post)
-For example:
-
-```yaml
-stages:
- - build
- - test
- - deploy
-
-job 0:
- stage: .pre
- script: make something useful before build stage
-
-job 1:
- stage: build
- script: make build dependencies
-
-job 2:
- stage: build
- script: make build artifacts
-
-job 3:
- stage: test
- script: make test
-
-job 4:
- stage: deploy
- script: make deploy
-
-job 5:
- stage: .post
- script: make something useful at the end of pipeline
-```
-
-#### Use your own runners
-
-When you use your own runners, each runner runs only one job at a time by default.
-Jobs can run in parallel if they run on different runners.
-
-If you have only one runner, jobs can run in parallel if the runner's
-[`concurrent` setting](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-global-section)
-is greater than `1`.
-
-#### `.pre` and `.post`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31441) in GitLab 12.4.
-
-Use `pre` and `post` for jobs that need to run first or last in a pipeline.
-
-- `.pre` is guaranteed to always be the first stage in a pipeline.
-- `.post` is guaranteed to always be the last stage in a pipeline.
-
-User-defined stages are executed after `.pre` and before `.post`.
-
-You must have a job in at least one stage other than `.pre` or `.post`.
-
-You can't change the order of `.pre` and `.post`, even if you define them out of order in the `.gitlab-ci.yml` file.
-For example, the following configurations are equivalent:
-
-```yaml
-stages:
- - .pre
- - a
- - b
- - .post
-```
-
-```yaml
-stages:
- - a
- - .pre
- - b
- - .post
-```
-
-```yaml
-stages:
- - a
- - b
-```
-
-### `extends`
-
-> Introduced in GitLab 11.3.
-
-Use `extends` to reuse configuration sections. It's an alternative to [YAML anchors](#anchors)
-and is a little more flexible and readable. You can use `extends` to reuse configuration
-from [included configuration files](#use-extends-and-include-together).
-
-In the following example, the `rspec` job uses the configuration from the `.tests` template job.
-GitLab:
-
-- Performs a reverse deep merge based on the keys.
-- Merges the `.tests` content with the `rspec` job.
-- Doesn't merge the values of the keys.
-
-```yaml
-.tests:
- script: rake test
- stage: test
- only:
- refs:
- - branches
-
-rspec:
- extends: .tests
- script: rake rspec
- only:
- variables:
- - $RSPEC
-```
-
-The result is this `rspec` job:
-
-```yaml
-rspec:
- script: rake rspec
- stage: test
- only:
- refs:
- - branches
- variables:
- - $RSPEC
-```
-
-`.tests` in this example is a [hidden job](#hide-jobs), but it's
-possible to extend configuration from regular jobs as well.
-
-`extends` supports multi-level inheritance. You should avoid using more than three levels,
-but you can use as many as eleven. The following example has two levels of inheritance:
-
-```yaml
-.tests:
- rules:
- - if: $CI_PIPELINE_SOURCE == "push"
-
-.rspec:
- extends: .tests
- script: rake rspec
-
-rspec 1:
- variables:
- RSPEC_SUITE: '1'
- extends: .rspec
-
-rspec 2:
- variables:
- RSPEC_SUITE: '2'
- extends: .rspec
-
-spinach:
- extends: .tests
- script: rake spinach
-```
-
-In GitLab 12.0 and later, it's also possible to use multiple parents for
-`extends`.
-
-#### Merge details
-
-You can use `extends` to merge hashes but not arrays.
-The algorithm used for merge is "closest scope wins," so
-keys from the last member always override anything defined on other
-levels. For example:
-
-```yaml
-.only-important:
- variables:
- URL: "http://my-url.internal"
- IMPORTANT_VAR: "the details"
- rules:
- - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- - if: $CI_COMMIT_BRANCH == "stable"
- tags:
- - production
- script:
- - echo "Hello world!"
-
-.in-docker:
- variables:
- URL: "http://docker-url.internal"
- tags:
- - docker
- image: alpine
-
-rspec:
- variables:
- GITLAB: "is-awesome"
- extends:
- - .only-important
- - .in-docker
- script:
- - rake rspec
-```
-
-The result is this `rspec` job:
-
-```yaml
-rspec:
- variables:
- URL: "http://docker-url.internal"
- IMPORTANT_VAR: "the details"
- GITLAB: "is-awesome"
- rules:
- - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- - if: $CI_COMMIT_BRANCH == "stable"
- tags:
- - docker
- image: alpine
- script:
- - rake rspec
-```
-
-In this example:
-
-- The `variables` sections merge, but `URL: "http://docker-url.internal"` overwrites `URL: "http://my-url.internal"`.
-- `tags: ['docker']` overwrites `tags: ['production']`.
-- `script` does not merge, but `script: ['rake rspec']` overwrites
- `script: ['echo "Hello world!"']`. You can use [YAML anchors](#anchors) to merge arrays.
-
-#### Use `extends` and `include` together
-
-To reuse configuration from different configuration files,
-combine `extends` and [`include`](#include).
-
-In the following example, a `script` is defined in the `included.yml` file.
-Then, in the `.gitlab-ci.yml` file, `extends` refers
-to the contents of the `script`:
-
-- `included.yml`:
-
- ```yaml
- .template:
- script:
- - echo Hello!
- ```
-
-- `.gitlab-ci.yml`:
-
- ```yaml
- include: included.yml
-
- useTemplate:
- image: alpine
- extends: .template
- ```
-
-### `rules`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27863) in GitLab 12.3.
-
-Use `rules` to include or exclude jobs in pipelines.
-
-Rules are evaluated *in order* until the first match. When a match is found, the job
-is either included or excluded from the pipeline, depending on the configuration.
-
-`rules` replaces [`only/except`](#only--except) and they can't be used together
-in the same job. If you configure one job to use both keywords, the GitLab returns
-a `key may not be used with rules` error.
-
-`rules` accepts an array of rules defined with:
-
-- `if`
-- `changes`
-- `exists`
-- `allow_failure`
-- `variables`
-- `when`
-
-You can combine multiple keywords together for [complex rules](../jobs/job_control.md#complex-rules).
-
-The job is added to the pipeline:
-
-- If an `if`, `changes`, or `exists` rule matches and also has `when: on_success` (default),
- `when: delayed`, or `when: always`.
-- If a rule is reached that is only `when: on_success`, `when: delayed`, or `when: always`.
-
-The job is not added to the pipeline:
-
-- If no rules match.
-- If a rule matches and has `when: never`.
-
-#### `rules:if`
-
-Use `rules:if` clauses to specify when to add a job to a pipeline:
-
-- If an `if` statement is true, add the job to the pipeline.
-- If an `if` statement is true, but it's combined with `when: never`, do not add the job to the pipeline.
-- If no `if` statements are true, do not add the job to the pipeline.
-
-`if:` clauses are evaluated based on the values of [predefined CI/CD variables](../variables/predefined_variables.md)
-or [custom CI/CD variables](../variables/README.md#custom-cicd-variables).
-
-**Keyword type**: Job-specific and pipeline-specific. You can use it as part of a job
-to configure the job behavior, or with [`workflow`](#workflow) to configure the pipeline behavior.
-
-**Possible inputs**: A [CI/CD variable expression](../jobs/job_control.md#cicd-variable-expressions).
-
-**Example of `rules:if`**:
-
-```yaml
-job:
- script: echo "Hello, Rules!"
- rules:
- - if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature/ && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != $CI_DEFAULT_BRANCH'
- when: never
- - if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature/'
- when: manual
- allow_failure: true
- - if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME'
-```
-
-**Additional details**:
-
-- If a rule matches and has no `when` defined, the rule uses the `when`
- defined for the job, which defaults to `on_success` if not defined.
-- You can define `when` once per rule, or once at the job-level, which applies to
- all rules. You can't mix `when` at the job-level with `when` in rules.
-- Unlike variables in [`script`](../variables/README.md#use-cicd-variables-in-job-scripts)
- sections, variables in rules expressions are always formatted as `$VARIABLE`.
-
-**Related topics**:
-
-- [Common `if` expressions for `rules`](../jobs/job_control.md#common-if-clauses-for-rules).
-- [Avoid duplicate pipelines](../jobs/job_control.md#avoid-duplicate-pipelines).
-
-#### `rules:changes`
-
-Use `rules:changes` to specify when to add a job to a pipeline by checking for changes
-to specific files.
-
-WARNING:
-You should use `rules: changes` only with **branch pipelines** or **merge request pipelines**.
-You can use `rules: changes` with other pipeline types, but `rules: changes` always
-evaluates to true when there is no Git `push` event. Tag pipelines, scheduled pipelines,
-and so on do **not** have a Git `push` event associated with them. A `rules: changes` job
-is **always** added to those pipelines if there is no `if:` that limits the job to
-branch or merge request pipelines.
-
-**Keyword type**: Job keyword. You can use it only as part of a job.
-
-**Possible inputs**: An array of file paths. In GitLab 13.6 and later,
-[file paths can include variables](../jobs/job_control.md#variables-in-ruleschanges).
-
-**Example of `rules:changes`**:
-
-```yaml
-docker build:
- script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
- rules:
- - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- changes:
- - Dockerfile
- when: manual
- allow_failure: true
-```
-
-- If the pipeline is a merge request pipeline, check `Dockerfile` for changes.
-- If `Dockerfile` has changed, add the job to the pipeline as a manual job, and the pipeline
- continues running even if the job is not triggered (`allow_failure: true`).
-- If `Dockerfile` has not changed, do not add job to any pipeline (same as `when: never`).
-
-**Additional details**:
-
-- `rules: changes` works the same way as [`only: changes` and `except: changes`](#onlychanges--exceptchanges).
-- You can use `when: never` to implement a rule similar to [`except:changes`](#onlychanges--exceptchanges).
-
-#### `rules:exists`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/24021) in GitLab 12.4.
-
-Use `exists` to run a job when certain files exist in the repository.
-
-**Keyword type**: Job keyword. You can use it only as part of a job.
-
-**Possible inputs**: An array of file paths. Paths are relative to the project directory (`$CI_PROJECT_DIR`)
-and can't directly link outside it. File paths can use glob patterns.
-
-**Example of `rules:exists`**:
-
-```yaml
-job:
- script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
- rules:
- - exists:
- - Dockerfile
-```
-
-`job` runs if a `Dockerfile` exists anywhere in the repository.
-
-**Additional details**:
-
-- Glob patterns are interpreted with Ruby [`File.fnmatch`](https://docs.ruby-lang.org/en/2.7.0/File.html#method-c-fnmatch)
- with the flags `File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB`.
-- For performance reasons, GitLab matches a maximum of 10,000 `exists` patterns or
- file paths. After the 10,000th check, rules with patterned globs always match.
- In other words, the `exists` rule always assumes a match in projects with more
- than 10,000 files.
-
-#### `rules:allow_failure`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30235) in GitLab 12.8.
-
-Use [`allow_failure: true`](#allow_failure) in `rules:` to allow a job to fail
-without stopping the pipeline.
-
-You can also use `allow_failure: true` with a manual job. The pipeline continues
-running without waiting for the result of the manual job. `allow_failure: false`
-combined with `when: manual` in rules causes the pipeline to wait for the manual
-job to run before continuing.
-
-**Keyword type**: Job keyword. You can use it only as part of a job.
-
-**Possible inputs**: `true` or `false`. Defaults to `false` if not defined.
-
-**Example of `rules:allow_failure`**:
-
-```yaml
-job:
- script: echo "Hello, Rules!"
- rules:
- - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH'
- when: manual
- allow_failure: true
-```
-
-If the rule matches, then the job is a manual job with `allow_failure: true`.
-
-**Additional details**:
-
-- The rule-level `rules:allow_failure` overrides the job-level [`allow_failure`](#allow_failure),
- and only applies when the specific rule triggers the job.
-
-#### `rules:variables`
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/209864) in GitLab 13.7.
-> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/289803) in GitLab 13.10.
-
-Use [`variables`](#variables) in `rules:` to define variables for specific conditions.
-
-**Keyword type**: Job-specific. You can use it only as part of a job.
-
-**Possible inputs**: A hash of variables in the format `VARIABLE-NAME: value`.
-
-**Example of `rules:variables`**:
-
-```yaml
-job:
- variables:
- DEPLOY_VARIABLE: "default-deploy"
- rules:
- - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
- variables: # Override DEPLOY_VARIABLE defined
- DEPLOY_VARIABLE: "deploy-production" # at the job level.
- - if: $CI_COMMIT_REF_NAME =~ /feature/
- variables:
- IS_A_FEATURE: "true" # Define a new variable.
- script:
- - echo "Run script with $DEPLOY_VARIABLE as an argument"
- - echo "Run another script if $IS_A_FEATURE exists"
-```
-
-### `only` / `except`
-
-NOTE:
-`only` and `except` are not being actively developed. [`rules`](#rules) is the preferred
-keyword to control when to add jobs to pipelines.
-
-You can use `only` and `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.
-
-Four keywords can be used with `only` and `except`:
-
-- [`refs`](#onlyrefs--exceptrefs)
-- [`variables`](#onlyvariables--exceptvariables)
-- [`changes`](#onlychanges--exceptchanges)
-- [`kubernetes`](#onlykubernetes--exceptkubernetes)
-
-See [specify when jobs run with `only` and `except`](../jobs/job_control.md#specify-when-jobs-run-with-only-and-except)
-for more details and examples.
-
-#### `only:refs` / `except:refs`
-
-Use the `only:refs` and `except:refs` keywords to control when to add jobs to a
-pipeline based on branch names or pipeline types.
-
-**Keyword type**: Job keyword. You can use it only as part of a job.
-
-**Possible inputs**: An array including any number of:
-
-- Branch names, for example `main` or `my-feature-branch`.
-- [Regular expressions](../jobs/job_control.md#only--except-regex-syntax)
- that match against branch names, for example `/^feature-.*/`.
-- The following keywords:
-
- | **Value** | **Description** |
- | -------------------------|-----------------|
- | `api` | For pipelines triggered by the [pipelines API](../../api/pipelines.md#create-a-new-pipeline). |
- | `branches` | When the Git reference for a pipeline is a branch. |
- | `chat` | For pipelines created by using a [GitLab ChatOps](../chatops/index.md) command. |
- | `external` | When you use CI services other than GitLab. |
- | `external_pull_requests` | When an external pull request on GitHub is created or updated (See [Pipelines for external pull requests](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests)). |
- | `merge_requests` | For pipelines created when a merge request is created or updated. Enables [merge request pipelines](../merge_request_pipelines/index.md), [merged results pipelines](../merge_request_pipelines/pipelines_for_merged_results/index.md), and [merge trains](../merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md). |
- | `pipelines` | For [multi-project pipelines](../multi_project_pipelines.md) created by [using the API with `CI_JOB_TOKEN`](../multi_project_pipelines.md#triggering-multi-project-pipelines-through-api), or the [`trigger`](#trigger) keyword. |
- | `pushes` | For pipelines triggered by a `git push` event, including for branches and tags. |
- | `schedules` | For [scheduled pipelines](../pipelines/schedules.md). |
- | `tags` | When the Git reference for a pipeline is a tag. |
- | `triggers` | For pipelines created by using a [trigger token](../triggers/README.md#trigger-token). |
- | `web` | For pipelines created by using **Run pipeline** button in the GitLab UI, from the project's **CI/CD > Pipelines** section. |
-
-**Example of `only:refs` and `except:refs`**:
-
-```yaml
-job1:
- script: echo
- only:
- - main
- - /^issue-.*$/
- - merge_requests
-
-job2:
- script: echo
- except:
- - main
- - /^stable-branch.*$/
- - schedules
-```
-
-**Additional details:**
-
-- Scheduled pipelines run on specific branches, so jobs configured with `only: branches`
- run on scheduled pipelines too. Add `except: schedules` to prevent jobs with `only: branches`
- from running on scheduled pipelines.
-- `only` or `except` used without any other keywords are equivalent to `only: refs`
- or `except: refs`. For example, the following two jobs configurations have the same
- behavior:
-
- ```yaml
- job1:
- script: echo
- only:
- - branches
-
- job2:
- script: echo
- only:
- refs:
- - branches
- ```
-
-- If a job does not use `only`, `except`, or [`rules`](#rules), then `only` is set to `branches`
- and `tags` by default.
-
- For example, `job1` and `job2` are equivalent:
-
- ```yaml
- job1:
- script: echo 'test'
-
- job2:
- script: echo 'test'
- only:
- - branches
- - tags
- ```
-
-#### `only:variables` / `except:variables`
-
-Use the `only:variables` or `except:variables` keywords to control when to add jobs
-to a pipeline, based on the status of [CI/CD variables](../variables/README.md).
-
-**Keyword type**: Job keyword. You can use it only as part of a job.
-
-**Possible inputs**: An array of [CI/CD variable expressions](../jobs/job_control.md#cicd-variable-expressions).
-
-**Example of `only:variables`**:
-
-```yaml
-deploy:
- script: cap staging deploy
- only:
- variables:
- - $RELEASE == "staging"
- - $STAGING
-```
-
-**Related topics**:
-
-- [`only:variables` and `except:variables` examples](../jobs/job_control.md#only-variables--except-variables-examples).
-
-#### `only:changes` / `except:changes`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/19232) in GitLab 11.4.
-
-Use the `changes` keyword with `only` to run a job, or with `except` to skip a job,
-when a Git push event modifies a file.
-
-Use `changes` in pipelines with the following refs:
-
-- `branches`
-- `external_pull_requests`
-- `merge_requests` (see additional details about [using `only:changes` with pipelines for merge requests](../jobs/job_control.md#use-onlychanges-with-pipelines-for-merge-requests))
-
-**Keyword type**: Job keyword. You can use it only as part of a job.
-
-**Possible inputs**: An array including any number of:
-
-- Paths to files.
-- Wildcard paths for single directories, for example `path/to/directory/*`, or a directory
- and all its subdirectories, for example `path/to/directory/**/*`.
-- Wildcard ([glob](https://en.wikipedia.org/wiki/Glob_(programming))) paths for all
- files with the same extension or multiple extensions, for example `*.md` or `path/to/directory/*.{rb,py,sh}`.
-- Wildcard paths to files in the root directory, or all directories, wrapped in double quotes.
- For example `"*.json"` or `"**/*.json"`.
-
-**Example of `only:changes`**:
-
-```yaml
-docker build:
- script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
- only:
- refs:
- - branches
- changes:
- - Dockerfile
- - docker/scripts/*
- - dockerfiles/**/*
- - more_scripts/*.{rb,py,sh}
-```
-
-**Additional details**:
-
-- If you use refs other than `branches`, `external_pull_requests`, or `merge_requests`,
- `changes` can't determine if a given file is new or old and always returns `true`.
-- If you use `only: changes` with other refs, jobs ignore the changes and always run.
-- If you use `except: changes` with other refs, jobs ignore the changes and never run.
-
-**Related topics**:
-
-- [`only: changes` and `except: changes` examples](../jobs/job_control.md#onlychanges--exceptchanges-examples).
-- If you use `changes` with [only allow merge requests to be merged if the pipeline succeeds](../../user/project/merge_requests/merge_when_pipeline_succeeds.md#only-allow-merge-requests-to-be-merged-if-the-pipeline-succeeds),
- you should [also use `only:merge_requests`](../jobs/job_control.md#use-onlychanges-with-pipelines-for-merge-requests).
-- Use `changes` with [new branches or tags *without* pipelines for merge requests](../jobs/job_control.md#use-onlychanges-without-pipelines-for-merge-requests).
-- Use `changes` with [scheduled pipelines](../jobs/job_control.md#use-onlychanges-with-scheduled-pipelines).
-
-#### `only:kubernetes` / `except:kubernetes`
-
-Use `only:kubernetes` or `except:kubernetes` to control if jobs are added to the pipeline
-when the Kubernetes service is active in the project.
-
-**Keyword type**: Job-specific. You can use it only as part of a job.
-
-**Possible inputs**: The `kubernetes` strategy accepts only the `active` keyword.
-
-**Example of `only:kubernetes`**:
-
-```yaml
-deploy:
- only:
- kubernetes: active
-```
-
-In this example, the `deploy` job runs only when the Kubernetes service is active
-in the project.
-
-### `needs`
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/47063) in GitLab 12.2.
-> - In GitLab 12.3, maximum number of jobs in `needs` array raised from five to 50.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30631) in GitLab 12.8, `needs: []` lets jobs start immediately.
-
-Use `needs:` to execute jobs out-of-order. Relationships between jobs
-that use `needs` can be visualized as a [directed acyclic graph](../directed_acyclic_graph/index.md).
-
-You can ignore stage ordering and run some jobs without waiting for others to complete.
-Jobs in multiple stages can run concurrently.
-
-The following example creates four paths of execution:
-
-- Linter: the `lint` job runs immediately without waiting for the `build` stage
- to complete because it has no needs (`needs: []`).
-- Linux path: the `linux:rspec` and `linux:rubocop` jobs runs as soon as the `linux:build`
- job finishes without waiting for `mac:build` to finish.
-- macOS path: the `mac:rspec` and `mac:rubocop` jobs runs as soon as the `mac:build`
- job finishes, without waiting for `linux:build` to finish.
-- The `production` job runs as soon as all previous jobs finish; in this case:
- `linux:build`, `linux:rspec`, `linux:rubocop`, `mac:build`, `mac:rspec`, `mac:rubocop`.
-
-```yaml
-linux:build:
- stage: build
-
-mac:build:
- stage: build
-
-lint:
- stage: test
- needs: []
-
-linux:rspec:
- stage: test
- needs: ["linux:build"]
-
-linux:rubocop:
- stage: test
- needs: ["linux:build"]
-
-mac:rspec:
- stage: test
- needs: ["mac:build"]
-
-mac:rubocop:
- stage: test
- needs: ["mac:build"]
-
-production:
- stage: deploy
-```
-
-#### Requirements and limitations
-
-- In GitLab 13.9 and older, if `needs:` refers to a job that might not be added to
- a pipeline because of `only`, `except`, or `rules`, the pipeline might fail to create.
-- The maximum number of jobs that a single job can need in the `needs:` array is limited:
- - For GitLab.com, the limit is 50. For more information, see our
- [infrastructure issue](https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/7541).
- - For self-managed instances, the limit is: 50. This limit [can be changed](#changing-the-needs-job-limit).
-- If `needs:` refers to a job that uses the [`parallel`](#parallel) keyword,
- it depends on all jobs created in parallel, not just one job. It also downloads
- artifacts from all the parallel jobs by default. If the artifacts have the same
- name, they overwrite each other and only the last one downloaded is saved.
-- `needs:` is similar to `dependencies:` in that it must use jobs from prior stages,
- meaning it's impossible to create circular dependencies. Depending on jobs in the
- current stage is not possible either, but support [is planned](https://gitlab.com/gitlab-org/gitlab/-/issues/30632).
-- Stages must be explicitly defined for all jobs
- that have the keyword `needs:` or are referred to by one.
-
-##### Changing the `needs:` job limit **(FREE SELF)**
-
-The maximum number of jobs that can be defined in `needs:` defaults to 50.
-
-A GitLab administrator with [access to the GitLab Rails console](../../administration/feature_flags.md)
-can choose a custom limit. For example, to set the limit to 100:
-
-```ruby
-Plan.default.actual_limits.update!(ci_needs_size_limit: 100)
-```
-
-To disable directed acyclic graphs (DAG), set the limit to `0`.
-
-#### Artifact downloads with `needs`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14311) in GitLab v12.6.
-
-When a job uses `needs`, it no longer downloads all artifacts from previous stages
-by default, because jobs with `needs` can start before earlier stages complete. With
-`needs` you can only download artifacts from the jobs listed in the `needs:` configuration.
-
-Use `artifacts: true` (default) or `artifacts: false` to control when artifacts are
-downloaded in jobs that use `needs`.
-
-In the following example, the `rspec` job downloads the `build_job` artifacts, but the
-`rubocop` job does not:
-
-```yaml
-build_job:
- stage: build
- artifacts:
- paths:
- - binaries/
-
-rspec:
- stage: test
- needs:
- - job: build_job
- artifacts: true
-
-rubocop:
- stage: test
- needs:
- - job: build_job
- artifacts: false
-```
-
-In the following example, the `rspec` job downloads the artifacts from all three `build_jobs`.
-`artifacts` is:
-
-- Set to true for `build_job_1`.
-- Defaults to true for both `build_job_2` and `build_job_3`.
-
-```yaml
-rspec:
- needs:
- - job: build_job_1
- artifacts: true
- - job: build_job_2
- - build_job_3
-```
-
-In GitLab 12.6 and later, you can't combine the [`dependencies`](#dependencies) keyword
-with `needs`.
-
-#### Cross project artifact downloads with `needs` **(PREMIUM)**
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14311) in GitLab v12.7.
-
-Use `needs` to download artifacts from up to five jobs in pipelines:
-
-- [On other refs in the same project](#artifact-downloads-between-pipelines-in-the-same-project).
-- In different projects, groups and namespaces.
-
-```yaml
-build_job:
- stage: build
- script:
- - ls -lhR
- needs:
- - project: namespace/group/project-name
- job: build-1
- ref: main
- artifacts: true
-```
-
-`build_job` downloads the artifacts from the latest successful `build-1` job
-on the `main` branch in the `group/project-name` project. If the project is in the
-same group or namespace, you can omit them from the `project:` keyword. For example,
-`project: group/project-name` or `project: project-name`.
-
-The user running the pipeline must have at least `reporter` access to the group or project, or the group/project must have public visibility.
-
-##### Artifact downloads between pipelines in the same project
-
-Use `needs` to download artifacts from different pipelines in the current project.
-Set the `project` keyword as the current project's name, and specify a ref.
-
-In the following example, `build_job` downloads the artifacts for the latest successful
-`build-1` job with the `other-ref` ref:
-
-```yaml
-build_job:
- stage: build
- script:
- - ls -lhR
- needs:
- - project: group/same-project-name
- job: build-1
- ref: other-ref
- artifacts: true
-```
-
-CI/CD variable support for `project:`, `job:`, and `ref` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/202093)
-in GitLab 13.3. [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/235761) in GitLab 13.4.
-
-For example:
-
-```yaml
-build_job:
- stage: build
- script:
- - ls -lhR
- needs:
- - project: $CI_PROJECT_PATH
- job: $DEPENDENCY_JOB_NAME
- ref: $ARTIFACTS_DOWNLOAD_REF
- artifacts: true
-```
-
-You can't download artifacts from jobs that run in [`parallel:`](#parallel).
-
-To download artifacts between [parent-child pipelines](../parent_child_pipelines.md),
-use [`needs:pipeline`](#artifact-downloads-to-child-pipelines).
-
-You should not download artifacts from the same ref as a running pipeline. Concurrent
-pipelines running on the same ref could override the artifacts.
-
-##### Artifact downloads to child pipelines
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/255983) in GitLab v13.7.
-
-A [child pipeline](../parent_child_pipelines.md) can download artifacts from a job in
-its parent pipeline or another child pipeline in the same parent-child pipeline hierarchy.
-
-For example, with the following parent pipeline that has a job that creates some artifacts:
-
-```yaml
-create-artifact:
- stage: build
- script: echo 'sample artifact' > artifact.txt
- artifacts:
- paths: [artifact.txt]
-
-child-pipeline:
- stage: test
- trigger:
- include: child.yml
- strategy: depend
- variables:
- PARENT_PIPELINE_ID: $CI_PIPELINE_ID
-```
-
-A job in the child pipeline can download artifacts from the `create-artifact` job in
-the parent pipeline:
-
-```yaml
-use-artifact:
- script: cat artifact.txt
- needs:
- - pipeline: $PARENT_PIPELINE_ID
- job: create-artifact
-```
-
-The `pipeline` attribute accepts a pipeline ID and it must be a pipeline present
-in the same parent-child pipeline hierarchy of the given pipeline.
-
-The `pipeline` attribute does not accept the current pipeline ID (`$CI_PIPELINE_ID`).
-To download artifacts from a job in the current pipeline, use the basic form of [`needs`](#artifact-downloads-with-needs).
-
-#### Optional `needs`
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30680) in GitLab 13.10.
-> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/323891) in GitLab 14.0.
-
-To need a job that sometimes does not exist in the pipeline, add `optional: true`
-to the `needs` configuration. If not defined, `optional: false` is the default.
-
-Jobs that use [`rules`](#rules), [`only`, or `except`](#only--except), might
-not always exist in a pipeline. When the pipeline starts, it checks the `needs`
-relationships before running. Without `optional: true`, needs relationships that
-point to a job that does not exist stops the pipeline from starting and causes a pipeline
-error similar to:
-
-- `'job1' job needs 'job2' job, but it was not added to the pipeline`
-
-In this example:
-
-- When the branch is the default branch, the `build` job exists in the pipeline, and the `rspec`
- job waits for it to complete before starting.
-- When the branch is not the default branch, the `build` job does not exist in the pipeline.
- The `rspec` job runs immediately (similar to `needs: []`) because its `needs`
- relationship to the `build` job is optional.
-
-```yaml
-build:
- stage: build
- rules:
- - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
-
-rspec:
- stage: test
- needs:
- - job: build
- optional: true
-```
-
-### `tags`
-
-Use `tags` to select a specific runner from the list of all runners that are
-available for the project.
-
-When you register a runner, you can specify the runner's tags, for
-example `ruby`, `postgres`, `development`.
-
-In the following example, the job is run by a runner that
-has both `ruby` and `postgres` tags defined.
-
-```yaml
-job:
- tags:
- - ruby
- - postgres
-```
-
-You can use tags to run different jobs on different platforms. For
-example, if you have an OS X runner with tag `osx` and a Windows runner with tag
-`windows`, you can run a job on each platform:
-
-```yaml
-windows job:
- stage:
- - build
- tags:
- - windows
- script:
- - echo Hello, %USERNAME%!
-
-osx job:
- stage:
- - build
- tags:
- - osx
- script:
- - echo "Hello, $USER!"
-```
-
-### `allow_failure`
-
-Use `allow_failure` when you want to let a job fail without impacting the rest of the CI
-suite. The default value is `false`, except for [manual](#whenmanual) jobs that use
-the `when: manual` syntax.
-
-In jobs that use [`rules:`](#rules), all jobs default to `allow_failure: false`,
-*including* `when: manual` jobs.
-
-When `allow_failure` is set to `true` and the job fails, the job shows an orange warning in the UI.
-However, the logical flow of the pipeline considers the job a
-success/passed, and is not blocked.
-
-Assuming all other jobs are successful, the job's stage and its pipeline
-show the same orange warning. However, the associated commit is marked as
-"passed", without warnings.
-
-In the following example, `job1` and `job2` run in parallel. If `job1`
-fails, it doesn't stop the next stage from running, because it's marked with
-`allow_failure: true`:
-
-```yaml
-job1:
- stage: test
- script:
- - execute_script_that_will_fail
- allow_failure: true
-
-job2:
- stage: test
- script:
- - execute_script_that_will_succeed
-
-job3:
- stage: deploy
- script:
- - deploy_to_staging
-```
-
-#### `allow_failure:exit_codes`
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/273157) in GitLab 13.8.
-> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/292024) in GitLab 13.9.
-
-Use `allow_failure:exit_codes` to dynamically control if a job should be allowed
-to fail. You can list which exit codes are not considered failures. The job fails
-for any other exit code:
-
-```yaml
-test_job_1:
- script:
- - echo "Run a script that results in exit code 1. This job fails."
- - exit 1
- allow_failure:
- exit_codes: 137
-
-test_job_2:
- script:
- - echo "Run a script that results in exit code 137. This job is allowed to fail."
- - exit 137
- allow_failure:
- exit_codes:
- - 137
- - 255
-```
-
-### `when`
-
-Use `when` to implement jobs that run in case of failure or despite the
-failure.
-
-The valid values of `when` are:
-
-1. `on_success` (default) - Execute job only when all jobs in earlier stages succeed,
- or are considered successful because they have `allow_failure: true`.
-1. `on_failure` - Execute job only when at least one job in an earlier stage fails.
-1. `always` - Execute job regardless of the status of jobs in earlier stages.
-1. `manual` - Execute job [manually](#whenmanual).
-1. `delayed` - [Delay the execution of a job](#whendelayed) for a specified duration.
- Added in GitLab 11.14.
-1. `never`:
- - With job [`rules`](#rules), don't execute job.
- - With [`workflow:rules`](#workflow), don't run pipeline.
-
-In the following example, the script:
-
-1. Executes `cleanup_build_job` only when `build_job` fails.
-1. Always executes `cleanup_job` as the last step in pipeline regardless of
- success or failure.
-1. Executes `deploy_job` when you run it manually in the GitLab UI.
-
-```yaml
-stages:
- - build
- - cleanup_build
- - test
- - deploy
- - cleanup
-
-build_job:
- stage: build
- script:
- - make build
-
-cleanup_build_job:
- stage: cleanup_build
- script:
- - cleanup build when failed
- when: on_failure
-
-test_job:
- stage: test
- script:
- - make test
-
-deploy_job:
- stage: deploy
- script:
- - make deploy
- when: manual
-
-cleanup_job:
- stage: cleanup
- script:
- - cleanup after jobs
- when: always
-```
-
-#### `when:manual`
-
-A manual job is a type of job that is not executed automatically and must be explicitly
-started by a user. You might want to use manual jobs for things like deploying to production.
-
-To make a job manual, add `when: manual` to its configuration.
-
-When the pipeline starts, manual jobs display as skipped and do not run automatically.
-They can be started from the pipeline, job, [environment](../environments/index.md#configure-manual-deployments),
-and deployment views.
-
-Manual jobs can be either optional or blocking:
-
-- **Optional**: Manual jobs have [`allow_failure: true](#allow_failure) set by default
- and are considered optional. The status of an optional manual job does not contribute
- to the overall pipeline status. A pipeline can succeed even if all its manual jobs fail.
-
-- **Blocking**: To make a blocking manual job, add `allow_failure: false` to its configuration.
- Blocking manual jobs stop further execution of the pipeline at the stage where the
- job is defined. To let the pipeline continue running, click **{play}** (play) on
- the blocking manual job.
-
- Merge requests in projects with [merge when pipeline succeeds](../../user/project/merge_requests/merge_when_pipeline_succeeds.md)
- enabled can't be merged with a blocked pipeline. Blocked pipelines show a status
- of **blocked**.
-
-When you use [`rules:`](#rules), `allow_failure` defaults to `false`, including for manual jobs.
-
-To trigger a manual job, a user must have permission to merge to the assigned branch.
-You can use [protected branches](../../user/project/protected_branches.md) to more strictly
-[protect manual deployments](#protecting-manual-jobs) from being run by unauthorized users.
-
-In [GitLab 13.5](https://gitlab.com/gitlab-org/gitlab/-/issues/201938) and later, you
-can use `when:manual` in the same job as [`trigger`](#trigger). In GitLab 13.4 and
-earlier, using them together causes the error `jobs:#{job-name} when should be on_success, on_failure or always`.
-
-##### Protecting manual jobs **(PREMIUM)**
-
-Use [protected environments](../environments/protected_environments.md)
-to define a list of users authorized to run a manual job. You can authorize only
-the users associated with a protected environment to trigger manual jobs, which can:
-
-- More precisely limit who can deploy to an environment.
-- Block a pipeline until an approved user "approves" it.
-
-To protect a manual job:
-
-1. Add an `environment` to the job. For example:
-
- ```yaml
- deploy_prod:
- stage: deploy
- script:
- - echo "Deploy to production server"
- environment:
- name: production
- url: https://example.com
- when: manual
- rules:
- - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- ```
-
-1. In the [protected environments settings](../environments/protected_environments.md#protecting-environments),
- select the environment (`production` in this example) and add the users, roles or groups
- that are authorized to trigger the manual job to the **Allowed to Deploy** list. Only those in
- this list can trigger this manual job, as well as GitLab administrators
- who are always able to use protected environments.
-
-You can use protected environments with blocking manual jobs to have a list of users
-allowed to approve later pipeline stages. Add `allow_failure: false` to the protected
-manual job and the pipeline's next stages only run after the manual job is triggered
-by authorized users.
-
-#### `when:delayed`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/51352) in GitLab 11.4.
-
-Use `when: delayed` to execute scripts after a waiting period, or if you want to avoid
-jobs immediately entering the `pending` state.
-
-You can set the period with `start_in` keyword. The value of `start_in` is an elapsed time in seconds, unless a unit is
-provided. `start_in` must be less than or equal to one week. Examples of valid values include:
-
-- `'5'`
-- `5 seconds`
-- `30 minutes`
-- `1 day`
-- `1 week`
-
-When a stage includes a delayed job, the pipeline doesn't progress until the delayed job finishes.
-You can use this keyword to insert delays between different stages.
-
-The timer of a delayed job starts immediately after the previous stage completes.
-Similar to other types of jobs, a delayed job's timer doesn't start unless the previous stage passes.
-
-The following example creates a job named `timed rollout 10%` that is executed 30 minutes after the previous stage completes:
-
-```yaml
-timed rollout 10%:
- stage: deploy
- script: echo 'Rolling out 10% ...'
- when: delayed
- start_in: 30 minutes
-```
-
-To stop the active timer of a delayed job, click the **{time-out}** (**Unschedule**) button.
-This job can no longer be scheduled to run automatically. You can, however, execute the job manually.
-
-To start a delayed job immediately, click the **Play** button.
-Soon GitLab Runner picks up and starts the job.
-
-### `environment`
-
-Use `environment` to define the [environment](../environments/index.md) that a job deploys to.
-For example:
-
-```yaml
-deploy to production:
- stage: deploy
- script: git push production HEAD:main
- environment: production
-```
-
-You can assign a value to the `environment` keyword by using:
-
-- Plain text, like `production`.
-- Variables, including CI/CD variables, predefined, secure, or variables
- defined in the `.gitlab-ci.yml` file.
-
-You can't use variables defined in a `script` section.
-
-If you specify an `environment` and no environment with that name exists,
-an environment is created.
-
-#### `environment:name`
-
-Set a name for an [environment](../environments/index.md). For example:
-
-```yaml
-deploy to production:
- stage: deploy
- script: git push production HEAD:main
- environment:
- name: production
-```
-
-Common environment names are `qa`, `staging`, and `production`, but you can use any
-name you want.
-
-You can assign a value to the `name` keyword by using:
-
-- Plain text, like `staging`.
-- Variables, including CI/CD variables, predefined, secure, or variables
- defined in the `.gitlab-ci.yml` file.
-
-You can't use variables defined in a `script` section.
-
-The environment `name` can contain:
-
-- Letters
-- Digits
-- Spaces
-- `-`
-- `_`
-- `/`
-- `$`
-- `{`
-- `}`
-
-#### `environment:url`
-
-Set a URL for an [environment](../environments/index.md). For example:
-
-```yaml
-deploy to production:
- stage: deploy
- script: git push production HEAD:main
- environment:
- name: production
- url: https://prod.example.com
-```
-
-After the job completes, you can access the URL by using a button in the merge request,
-environment, or deployment pages.
-
-You can assign a value to the `url` keyword by using:
-
-- Plain text, like `https://prod.example.com`.
-- Variables, including CI/CD variables, predefined, secure, or variables
- defined in the `.gitlab-ci.yml` file.
-
-You can't use variables defined in a `script` section.
-
-#### `environment:on_stop`
-
-Closing (stopping) environments can be achieved with the `on_stop` keyword
-defined under `environment`. It declares a different job that runs to close the
-environment.
-
-Read the `environment:action` section for an example.
-
-#### `environment:action`
-
-Use the `action` keyword to specify jobs that prepare, start, or stop environments.
-
-| **Value** | **Description** |
-|-----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| `start` | Default value. Indicates that job starts the environment. The deployment is created after the job starts. |
-| `prepare` | Indicates that the job is only preparing the environment. It does not trigger deployments. [Read more about preparing environments](../environments/index.md#prepare-an-environment-without-creating-a-deployment). |
-| `stop` | Indicates that job stops deployment. See the example below. |
-
-Take for instance:
-
-```yaml
-review_app:
- stage: deploy
- script: make deploy-app
- environment:
- name: review/$CI_COMMIT_REF_NAME
- url: https://$CI_ENVIRONMENT_SLUG.example.com
- on_stop: stop_review_app
-
-stop_review_app:
- stage: deploy
- variables:
- GIT_STRATEGY: none
- script: make delete-app
- when: manual
- environment:
- name: review/$CI_COMMIT_REF_NAME
- action: stop
-```
-
-In the above example, the `review_app` job deploys to the `review`
-environment. A new `stop_review_app` job is listed under `on_stop`.
-After the `review_app` job is finished, it triggers the
-`stop_review_app` job based on what is defined under `when`. In this case,
-it is set to `manual`, so it needs a [manual action](#whenmanual) from
-the GitLab UI to run.
-
-Also in the example, `GIT_STRATEGY` is set to `none`. If the
-`stop_review_app` job is [automatically triggered](../environments/index.md#stopping-an-environment),
-the runner won't try to check out the code after the branch is deleted.
-
-The example also overwrites global variables. If your `stop` `environment` job depends
-on global variables, use [anchor variables](#yaml-anchors-for-variables) when you set the `GIT_STRATEGY`
-to change the job without overriding the global variables.
-
-The `stop_review_app` job is **required** to have the following keywords defined:
-
-- `when`, defined at either:
- - [The job level](#when).
- - [In a rules clause](#rules). If you use `rules:` and `when: manual`, you should
- also set [`allow_failure: true`](#allow_failure) so the pipeline can complete
- even if the job doesn't run.
-- `environment:name`
-- `environment:action`
-
-Additionally, both jobs should have matching [`rules`](#only--except)
-or [`only/except`](#only--except) configuration.
-
-In the examples above, if the configuration is not identical:
-
-- The `stop_review_app` job might not be included in all pipelines that include the `review_app` job.
-- It is not possible to trigger the `action: stop` to stop the environment automatically.
-
-#### `environment:auto_stop_in`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/20956) in GitLab 12.8.
-
-The `auto_stop_in` keyword is for specifying the lifetime of the environment,
-that when expired, GitLab automatically stops them.
-
-For example,
-
-```yaml
-review_app:
- script: deploy-review-app
- environment:
- name: review/$CI_COMMIT_REF_NAME
- auto_stop_in: 1 day
-```
-
-When the environment for `review_app` is created, the environment's lifetime is set to `1 day`.
-Every time the review app is deployed, that lifetime is also reset to `1 day`.
-
-For more information, see
-[the environments auto-stop documentation](../environments/index.md#stop-an-environment-after-a-certain-time-period)
-
-#### `environment:kubernetes`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27630) in GitLab 12.6.
-
-Use the `kubernetes` keyword to configure deployments to a
-[Kubernetes cluster](../../user/project/clusters/index.md) that is associated with your project.
-
-For example:
-
-```yaml
-deploy:
- stage: deploy
- script: make deploy-app
- environment:
- name: production
- kubernetes:
- namespace: production
-```
-
-This configuration sets up the `deploy` job to deploy to the `production`
-environment, using the `production`
-[Kubernetes namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/).
-
-For more information, see
-[Available settings for `kubernetes`](../environments/index.md#configure-kubernetes-deployments).
-
-NOTE:
-Kubernetes configuration is not supported for Kubernetes clusters
-that are [managed by GitLab](../../user/project/clusters/index.md#gitlab-managed-clusters).
-To follow progress on support for GitLab-managed clusters, see the
-[relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/38054).
-
-#### `environment:deployment_tier`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/300741) in GitLab 13.10.
-
-Use the `deployment_tier` keyword to specify the tier of the deployment environment:
-
-```yaml
-deploy:
- script: echo
- environment:
- name: customer-portal
- deployment_tier: production
-```
-
-For more information,
-see [Deployment tier of environments](../environments/index.md#deployment-tier-of-environments).
-
-#### Dynamic environments
-
-Use CI/CD [variables](../variables/README.md) to dynamically name environments.
-
-For example:
-
-```yaml
-deploy as review app:
- stage: deploy
- script: make deploy
- environment:
- name: review/$CI_COMMIT_REF_NAME
- url: https://$CI_ENVIRONMENT_SLUG.example.com/
-```
-
-The `deploy as review app` job is marked as a deployment to dynamically
-create the `review/$CI_COMMIT_REF_NAME` environment. `$CI_COMMIT_REF_NAME`
-is a [CI/CD variable](../variables/README.md) set by the runner. The
-`$CI_ENVIRONMENT_SLUG` variable is based on the environment name, but suitable
-for inclusion in URLs. If the `deploy as review app` job runs in a branch named
-`pow`, this environment would be accessible with a URL like `https://review-pow.example.com/`.
-
-The common use case is to create dynamic environments for branches and use them
-as Review Apps. You can see an example that uses Review Apps at
-<https://gitlab.com/gitlab-examples/review-apps-nginx/>.
-
-### `cache`
-
-Use `cache` to specify a list of files and directories to
-cache between jobs. You can only use paths that are in the local working copy.
-
-If `cache` is defined outside the scope of jobs, it's set
-globally and all jobs use that configuration.
-
-Caching is shared between pipelines and jobs. Caches are restored before [artifacts](#artifacts).
-
-Read how caching works and find out some good practices in the
-[caching dependencies documentation](../caching/index.md).
-
-#### `cache:paths`
-
-Use the `paths` directive to choose which files or directories to cache. Paths
-are relative to the project directory (`$CI_PROJECT_DIR`) and can't directly link outside it.
-You can use Wildcards that use [glob](https://en.wikipedia.org/wiki/Glob_(programming))
-patterns and:
-
-- In [GitLab Runner 13.0](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2620) and later,
-[`doublestar.Glob`](https://pkg.go.dev/github.com/bmatcuk/doublestar@v1.2.2?tab=doc#Match).
-- In GitLab Runner 12.10 and earlier,
-[`filepath.Match`](https://pkg.go.dev/path/filepath#Match).
-
-Cache all files in `binaries` that end in `.apk` and the `.config` file:
-
-```yaml
-rspec:
- script: test
- cache:
- paths:
- - binaries/*.apk
- - .config
-```
-
-Locally defined cache overrides globally defined options. The following `rspec`
-job caches only `binaries/`:
-
-```yaml
-cache:
- paths:
- - my/files
-
-rspec:
- script: test
- cache:
- key: rspec
- paths:
- - binaries/
-```
-
-The cache is shared between jobs, so if you're using different
-paths for different jobs, you should also set a different `cache:key`.
-Otherwise cache content can be overwritten.
-
-#### `cache:key`
-
-The `key` keyword defines the affinity of caching between jobs.
-You can have a single cache for all jobs, cache per-job, cache per-branch,
-or any other way that fits your workflow. You can fine tune caching,
-including caching data between different jobs or even different branches.
-
-The `cache:key` variable can use any of the
-[predefined variables](../variables/README.md). The default key, if not
-set, is just literal `default`, which means everything is shared between
-pipelines and jobs by default.
-
-For example, to enable per-branch caching:
-
-```yaml
-cache:
- key: "$CI_COMMIT_REF_SLUG"
- paths:
- - binaries/
-```
-
-If you use **Windows Batch** to run your shell scripts you need to replace
-`$` with `%`:
-
-```yaml
-cache:
- key: "%CI_COMMIT_REF_SLUG%"
- paths:
- - binaries/
-```
-
-The `cache:key` variable can't contain the `/` character, or the equivalent
-URI-encoded `%2F`. A value made only of dots (`.`, `%2E`) is also forbidden.
-
-You can specify a [fallback cache key](#fallback-cache-key) to use if the specified `cache:key` is not found.
-
-##### Multiple caches
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32814) in GitLab 13.10.
-> - [Feature Flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/321877), in GitLab 13.12.
-
-You can have a maximum of four caches:
-
-```yaml
-test-job:
- stage: build
- cache:
- - key:
- files:
- - Gemfile.lock
- paths:
- - vendor/ruby
- - key:
- files:
- - yarn.lock
- paths:
- - .yarn-cache/
- script:
- - bundle install --path=vendor
- - yarn install --cache-folder .yarn-cache
- - echo Run tests...
-```
-
-If multiple caches are combined with a [Fallback cache key](#fallback-cache-key),
-the fallback is fetched multiple times if multiple caches are not found.
-
-#### Fallback cache key
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/1534) in GitLab Runner 13.4.
-
-You can use the `$CI_COMMIT_REF_SLUG` [variable](#variables) to specify your [`cache:key`](#cachekey).
-For example, if your `$CI_COMMIT_REF_SLUG` is `test` you can set a job
-to download cache that's tagged with `test`.
-
-If a cache with this tag is not found, you can use `CACHE_FALLBACK_KEY` to
-specify a cache to use when none exists.
-
-In the following example, if the `$CI_COMMIT_REF_SLUG` is not found, the job uses the key defined
-by the `CACHE_FALLBACK_KEY` variable:
-
-```yaml
-variables:
- CACHE_FALLBACK_KEY: fallback-key
-
-cache:
- key: "$CI_COMMIT_REF_SLUG"
- paths:
- - binaries/
-```
-
-##### `cache:key:files`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18986) in GitLab v12.5.
-
-The `cache:key:files` keyword extends the `cache:key` functionality by making it easier
-to reuse some caches, and rebuild them less often, which speeds up subsequent pipeline
-runs.
-
-When you include `cache:key:files`, you must also list the project files that are used to generate the key, up to a maximum of two files.
-The cache `key` is a SHA checksum computed from the most recent commits (up to two, if two files are listed)
-that changed the given files. If neither file is changed in any commits,
-the fallback key is `default`.
-
-```yaml
-cache:
- key:
- files:
- - Gemfile.lock
- - package.json
- paths:
- - vendor/ruby
- - node_modules
-```
-
-This example creates a cache for Ruby and Node.js dependencies that
-is tied to current versions of the `Gemfile.lock` and `package.json` files. Whenever one of
-these files changes, a new cache key is computed and a new cache is created. Any future
-job runs that use the same `Gemfile.lock` and `package.json` with `cache:key:files`
-use the new cache, instead of rebuilding the dependencies.
-
-##### `cache:key:prefix`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18986) in GitLab v12.5.
-
-When you want to combine a prefix with the SHA computed for `cache:key:files`,
-use the `prefix` keyword with `key:files`.
-For example, if you add a `prefix` of `test`, the resulting key is: `test-feef9576d21ee9b6a32e30c5c79d0a0ceb68d1e5`.
-If neither file is changed in any commits, the prefix is added to `default`, so the
-key in the example would be `test-default`.
-
-Like `cache:key`, `prefix` can use any of the [predefined variables](../variables/README.md),
-but cannot include:
-
-- the `/` character (or the equivalent URI-encoded `%2F`)
-- a value made only of `.` (or the equivalent URI-encoded `%2E`)
-
-```yaml
-cache:
- key:
- files:
- - Gemfile.lock
- prefix: ${CI_JOB_NAME}
- paths:
- - vendor/ruby
-
-rspec:
- script:
- - bundle exec rspec
-```
-
-For example, adding a `prefix` of `$CI_JOB_NAME`
-causes the key to look like: `rspec-feef9576d21ee9b6a32e30c5c79d0a0ceb68d1e5` and
-the job cache is shared across different branches. If a branch changes
-`Gemfile.lock`, that branch has a new SHA checksum for `cache:key:files`. A new cache key
-is generated, and a new cache is created for that key.
-If `Gemfile.lock` is not found, the prefix is added to
-`default`, so the key in the example would be `rspec-default`.
-
-#### `cache:untracked`
-
-Set `untracked: true` to cache all files that are untracked in your Git
-repository:
-
-```yaml
-rspec:
- script: test
- cache:
- untracked: true
-```
-
-Cache all Git untracked files and files in `binaries`:
-
-```yaml
-rspec:
- script: test
- cache:
- untracked: true
- paths:
- - binaries/
-```
-
-#### `cache:when`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18969) in GitLab 13.5 and GitLab Runner v13.5.0.
-
-`cache:when` defines when to save the cache, based on the status of the job. You can
-set `cache:when` to:
-
-- `on_success` (default): Save the cache only when the job succeeds.
-- `on_failure`: Save the cache only when the job fails.
-- `always`: Always save the cache.
-
-For example, to store a cache whether or not the job fails or succeeds:
-
-```yaml
-rspec:
- script: rspec
- cache:
- paths:
- - rspec/
- when: 'always'
-```
-
-#### `cache:policy`
-
-The default behavior of a caching job is to download the files at the start of
-execution, and to re-upload them at the end. Any changes made by the
-job are persisted for future runs. This behavior is known as the `pull-push` cache
-policy.
-
-If you know the job does not alter the cached files, you can skip the upload step
-by setting `policy: pull` in the job specification. You can add an ordinary cache
-job at an earlier stage to ensure the cache is updated from time to time:
-
-```yaml
-stages:
- - setup
- - test
-
-prepare:
- stage: setup
- cache:
- key: gems
- paths:
- - vendor/bundle
- script:
- - bundle install --deployment
-
-rspec:
- stage: test
- cache:
- key: gems
- paths:
- - vendor/bundle
- policy: pull
- script:
- - bundle exec rspec ...
-```
-
-Use the `pull` policy when you have many jobs executing in parallel that use caches. This
-policy speeds up job execution and reduces load on the cache server.
-
-If you have a job that unconditionally recreates the cache without
-referring to its previous contents, you can skip the download step.
-To do so, add `policy: push` to the job.
-
-### `artifacts`
-
-Use `artifacts` to specify a list of files and directories that are
-attached to the job when it [succeeds, fails, or always](#artifactswhen).
-
-The artifacts are sent to GitLab after the job finishes. They are
-available for download in the GitLab UI if the size is not
-larger than the [maximum artifact size](../../user/gitlab_com/index.md#gitlab-cicd).
-
-By default, jobs in later stages automatically download all the artifacts created
-by jobs in earlier stages. You can control artifact download behavior in jobs with
-[`dependencies`](#dependencies).
-
-When using the [`needs`](#artifact-downloads-with-needs) keyword, jobs can only download
-artifacts from the jobs defined in the `needs` configuration.
-
-Job artifacts are only collected for successful jobs by default, and
-artifacts are restored after [caches](#cache).
-
-[Read more about artifacts](../pipelines/job_artifacts.md).
-
-#### `dependencies`
-
-By default, all `artifacts` from previous stages
-are passed to each job. However, you can use the `dependencies` keyword to
-define a limited list of jobs to fetch artifacts from. You can also set a job to download no artifacts at all.
-
-To use this feature, define `dependencies` in context of the job and pass
-a list of all previous jobs the artifacts should be downloaded from.
-
-You can define jobs from stages that were executed before the current one.
-An error occurs if you define jobs from the current or an upcoming stage.
-
-To prevent a job from downloading artifacts, define an empty array.
-
-When you use `dependencies`, the status of the previous job is not considered.
-If a job fails or it's a manual job that isn't triggered, no error occurs.
-
-The following example defines two jobs with artifacts: `build:osx` and
-`build:linux`. When the `test:osx` is executed, the artifacts from `build:osx`
-are downloaded and extracted in the context of the build. The same happens
-for `test:linux` and artifacts from `build:linux`.
-
-The job `deploy` downloads artifacts from all previous jobs because of
-the [stage](#stages) precedence:
-
-```yaml
-build:osx:
- stage: build
- script: make build:osx
- artifacts:
- paths:
- - binaries/
-
-build:linux:
- stage: build
- script: make build:linux
- artifacts:
- paths:
- - binaries/
-
-test:osx:
- stage: test
- script: make test:osx
- dependencies:
- - build:osx
-
-test:linux:
- stage: test
- script: make test:linux
- dependencies:
- - build:linux
-
-deploy:
- stage: deploy
- script: make deploy
-```
-
-##### When a dependent job fails
-
-> Introduced in GitLab 10.3.
-
-If the artifacts of the job that is set as a dependency are
-[expired](#artifactsexpire_in) or
-[deleted](../pipelines/job_artifacts.md#delete-job-artifacts), then
-the dependent job fails.
-
-#### `artifacts:exclude`
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15122) in GitLab 13.1
-> - Requires GitLab Runner 13.1
-
-`exclude` makes it possible to prevent files from being added to an artifacts
-archive.
-
-Similar to [`artifacts:paths`](#artifactspaths), `exclude` paths are relative
-to the project directory. You can use Wildcards that use
-[glob](https://en.wikipedia.org/wiki/Glob_(programming)) or
-[`doublestar.PathMatch`](https://pkg.go.dev/github.com/bmatcuk/doublestar@v1.2.2?tab=doc#PathMatch) patterns.
-
-For example, to store all files in `binaries/`, but not `*.o` files located in
-subdirectories of `binaries/`:
-
-```yaml
-artifacts:
- paths:
- - binaries/
- exclude:
- - binaries/**/*.o
-```
-
-Unlike [`artifacts:paths`](#artifactspaths), `exclude` paths are not recursive. To exclude all of the contents of a directory, you can match them explicitly rather than matching the directory itself.
-
-For example, to store all files in `binaries/` but nothing located in the `temp/` subdirectory:
-
-```yaml
-artifacts:
- paths:
- - binaries/
- exclude:
- - binaries/temp/**/*
-```
-
-Files matched by [`artifacts:untracked`](#artifactsuntracked) can be excluded using
-`artifacts:exclude` too.
-
-#### `artifacts:expire_in`
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16267) in GitLab 13.0 behind a disabled feature flag, the latest job artifacts are kept regardless of expiry time.
-> - [Made default behavior](https://gitlab.com/gitlab-org/gitlab/-/issues/229936) in GitLab 13.4.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/241026) in GitLab 13.8, keeping latest job artifacts can be disabled at the project level.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/276583) in GitLab 13.9, keeping latest job artifacts can be disabled instance-wide.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/321323) in GitLab 13.12, the latest pipeline artifacts are kept regardless of expiry time.
-
-Use `expire_in` to specify how long [job artifacts](../pipelines/job_artifacts.md) are stored before
-they expire and are deleted. The `expire_in` setting does not affect:
-
-- Artifacts from the latest job, unless this keeping the latest job artifacts is:
- - [Disabled at the project level](../pipelines/job_artifacts.md#keep-artifacts-from-most-recent-successful-jobs).
- - [Disabled instance-wide](../../user/admin_area/settings/continuous_integration.md#keep-the-latest-artifacts-for-all-jobs-in-the-latest-successful-pipelines).
-- [Pipeline artifacts](../pipelines/pipeline_artifacts.md). It's not possible to specify an
- expiration date for these:
- - Pipeline artifacts from the latest pipeline are kept forever.
- - Other pipeline artifacts are erased after one week.
-
-The value of `expire_in` is an elapsed time in seconds, unless a unit is provided. Valid values
-include:
-
-- `'42'`
-- `42 seconds`
-- `3 mins 4 sec`
-- `2 hrs 20 min`
-- `2h20min`
-- `6 mos 1 day`
-- `47 yrs 6 mos and 4d`
-- `3 weeks and 2 days`
-- `never`
-
-To expire artifacts one week after being uploaded:
-
-```yaml
-job:
- artifacts:
- expire_in: 1 week
-```
-
-The expiration time period begins when the artifact is uploaded and stored on GitLab. If the expiry
-time is not defined, it defaults to the
-[instance wide setting](../../user/admin_area/settings/continuous_integration.md#default-artifacts-expiration)
-(30 days by default).
-
-To override the expiration date and protect artifacts from being automatically deleted:
-
-- Use the **Keep** button on the job page.
-- [In GitLab 13.3 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/22761), set the value of
- `expire_in` to `never`.
-
-After their expiry, artifacts are deleted hourly by default (using a cron job), and are not
-accessible anymore.
-
-#### `artifacts:expose_as`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15018) in GitLab 12.5.
-
-Use the `expose_as` keyword to expose [job artifacts](../pipelines/job_artifacts.md)
-in the [merge request](../../user/project/merge_requests/index.md) UI.
-
-For example, to match a single file:
-
-```yaml
-test:
- script: ["echo 'test' > file.txt"]
- artifacts:
- expose_as: 'artifact 1'
- paths: ['file.txt']
-```
-
-With this configuration, GitLab adds a link **artifact 1** to the relevant merge request
-that points to `file1.txt`. To access the link, select **View exposed artifact**
-below the pipeline graph in the merge request overview.
-
-An example that matches an entire directory:
-
-```yaml
-test:
- script: ["mkdir test && echo 'test' > test/file.txt"]
- artifacts:
- expose_as: 'artifact 1'
- paths: ['test/']
-```
-
-Note the following:
-
-- Artifacts do not display in the merge request UI when using variables to define the `artifacts:paths`.
-- A maximum of 10 job artifacts per merge request can be exposed.
-- Glob patterns are unsupported.
-- If a directory is specified, the link is to the job [artifacts browser](../pipelines/job_artifacts.md#download-job-artifacts) if there is more than
- one file in the directory.
-- For exposed single file artifacts with `.html`, `.htm`, `.txt`, `.json`, `.xml`,
- and `.log` extensions, if [GitLab Pages](../../administration/pages/index.md) is:
- - Enabled, GitLab automatically renders the artifact.
- - Not enabled, the file is displayed in the artifacts browser.
-
-#### `artifacts:name`
-
-Use the `name` directive to define the name of the created artifacts
-archive. You can specify a unique name for every archive. The `artifacts:name`
-variable can make use of any of the [predefined variables](../variables/README.md).
-The default name is `artifacts`, which becomes `artifacts.zip` when you download it.
-
-To create an archive with a name of the current job:
-
-```yaml
-job:
- artifacts:
- name: "$CI_JOB_NAME"
- paths:
- - binaries/
-```
-
-To create an archive with a name of the current branch or tag including only
-the binaries directory:
-
-```yaml
-job:
- artifacts:
- name: "$CI_COMMIT_REF_NAME"
- paths:
- - binaries/
-```
-
-If your branch-name contains forward slashes
-(for example `feature/my-feature`) it's advised to use `$CI_COMMIT_REF_SLUG`
-instead of `$CI_COMMIT_REF_NAME` for proper naming of the artifact.
-
-To create an archive with a name of the current job and the current branch or
-tag including only the binaries directory:
-
-```yaml
-job:
- artifacts:
- name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME"
- paths:
- - binaries/
-```
-
-To create an archive with a name of the current [stage](#stages) and branch name:
-
-```yaml
-job:
- artifacts:
- name: "$CI_JOB_STAGE-$CI_COMMIT_REF_NAME"
- paths:
- - binaries/
-```
-
----
-
-If you use **Windows Batch** to run your shell scripts you need to replace
-`$` with `%`:
-
-```yaml
-job:
- artifacts:
- name: "%CI_JOB_STAGE%-%CI_COMMIT_REF_NAME%"
- paths:
- - binaries/
-```
-
-If you use **Windows PowerShell** to run your shell scripts you need to replace
-`$` with `$env:`:
-
-```yaml
-job:
- artifacts:
- name: "$env:CI_JOB_STAGE-$env:CI_COMMIT_REF_NAME"
- paths:
- - binaries/
-```
-
-#### `artifacts:paths`
-
-Paths are relative to the project directory (`$CI_PROJECT_DIR`) and can't directly
-link outside it. You can use Wildcards that use [glob](https://en.wikipedia.org/wiki/Glob_(programming))
-patterns and:
-
-- In [GitLab Runner 13.0](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2620) and later,
-[`doublestar.Glob`](https://pkg.go.dev/github.com/bmatcuk/doublestar@v1.2.2?tab=doc#Match).
-- In GitLab Runner 12.10 and earlier,
-[`filepath.Match`](https://pkg.go.dev/path/filepath#Match).
-
-To restrict which jobs a specific job fetches artifacts from, see [dependencies](#dependencies).
-
-Send all files in `binaries` and `.config`:
-
-```yaml
-artifacts:
- paths:
- - binaries/
- - .config
-```
-
-To disable artifact passing, define the job with empty [dependencies](#dependencies):
-
-```yaml
-job:
- stage: build
- script: make build
- dependencies: []
-```
-
-You may want to create artifacts only for tagged releases to avoid filling the
-build server storage with temporary build artifacts.
-
-Create artifacts only for tags (`default-job` doesn't create artifacts):
-
-```yaml
-default-job:
- script:
- - mvn test -U
- rules:
- - if: $CI_COMMIT_BRANCH
-
-release-job:
- script:
- - mvn package -U
- artifacts:
- paths:
- - target/*.war
- rules:
- - if: $CI_COMMIT_TAG
-```
-
-You can use wildcards for directories too. For example, if you want to get all the files inside the directories that end with `xyz`:
-
-```yaml
-job:
- artifacts:
- paths:
- - path/*xyz/*
-```
-
-#### `artifacts:public`
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49775) in GitLab 13.8
-> - It's [deployed behind a feature flag](../../user/feature_flags.md), disabled by default.
-> - It's disabled on GitLab.com.
-> - It's recommended for production use.
-
-Use `artifacts:public` to determine whether the job artifacts should be
-publicly available.
-
-The default for `artifacts:public` is `true` which means that the artifacts in
-public pipelines are available for download by anonymous and guest users:
-
-```yaml
-artifacts:
- public: true
-```
-
-To deny read access for anonymous and guest users to artifacts in public
-pipelines, set `artifacts:public` to `false`:
-
-```yaml
-artifacts:
- public: false
-```
-
-#### `artifacts:reports`
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/20390) in GitLab 11.2.
-> - Requires GitLab Runner 11.2 and above.
-
-Use [`artifacts:reports`](#artifactsreports)
-to collect test reports, code quality reports, and security reports from jobs.
-It also exposes these reports in the GitLab UI (merge requests, pipeline views, and security dashboards).
-
-The test reports are collected regardless of the job results (success or failure).
-You can use [`artifacts:expire_in`](#artifactsexpire_in) to set up an expiration
-date for their artifacts.
-
-If you also want the ability to browse the report output files, include the
-[`artifacts:paths`](#artifactspaths) keyword.
-
-##### `artifacts:reports:api_fuzzing` **(ULTIMATE)**
-
-> - Introduced in GitLab 13.4.
-> - Requires GitLab Runner 13.4 or later.
-
-The `api_fuzzing` report collects [API Fuzzing bugs](../../user/application_security/api_fuzzing/index.md)
-as artifacts.
-
-The collected API Fuzzing report uploads to GitLab as an artifact and is summarized in merge
-requests and the pipeline view. It's also used to provide data for security dashboards.
-
-##### `artifacts:reports:cobertura`
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3708) in GitLab 12.9.
-> - Requires [GitLab Runner](https://docs.gitlab.com/runner/) 11.5 and above.
-
-The `cobertura` report collects [Cobertura coverage XML files](../../user/project/merge_requests/test_coverage_visualization.md).
-The collected Cobertura coverage reports upload to GitLab as an artifact
-and display in merge requests.
-
-Cobertura was originally developed for Java, but there are many
-third party ports for other languages like JavaScript, Python, Ruby, and so on.
-
-##### `artifacts:reports:codequality`
-
-> - Introduced in GitLab 11.5.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212499) to GitLab Free in 13.2.
-> - Requires GitLab Runner 11.5 and above.
-
-The `codequality` report collects [Code Quality issues](../../user/project/merge_requests/code_quality.md)
-as artifacts.
-
-The collected Code Quality report uploads to GitLab as an artifact and is summarized in merge requests.
-
-##### `artifacts:reports:container_scanning` **(ULTIMATE)**
-
-> - Introduced in GitLab 11.5.
-> - Requires GitLab Runner 11.5 and above.
-
-The `container_scanning` report collects [Container Scanning vulnerabilities](../../user/application_security/container_scanning/index.md)
-as artifacts.
-
-The collected Container Scanning report uploads to GitLab as an artifact and
-is summarized in merge requests and the pipeline view. It's also used to provide data for security
-dashboards.
-
-##### `artifacts:reports:coverage_fuzzing` **(ULTIMATE)**
-
-> - Introduced in GitLab 13.4.
-> - Requires GitLab Runner 13.4 or later.
-
-The `coverage_fuzzing` report collects [coverage fuzzing bugs](../../user/application_security/coverage_fuzzing/index.md)
-as artifacts.
-
-The collected coverage fuzzing report uploads to GitLab as an artifact and is summarized in merge
-requests and the pipeline view. It's also used to provide data for security dashboards.
-
-##### `artifacts:reports:dast` **(ULTIMATE)**
-
-> - Introduced in GitLab 11.5.
-> - Requires GitLab Runner 11.5 and above.
-
-The `dast` report collects [DAST vulnerabilities](../../user/application_security/dast/index.md)
-as artifacts.
-
-The collected DAST report uploads to GitLab as an artifact and is summarized in merge requests and the pipeline view. It's also used to provide data for security
-dashboards.
-
-##### `artifacts:reports:dependency_scanning` **(ULTIMATE)**
-
-> - Introduced in GitLab 11.5.
-> - Requires GitLab Runner 11.5 and above.
-
-The `dependency_scanning` report collects [Dependency Scanning vulnerabilities](../../user/application_security/dependency_scanning/index.md)
-as artifacts.
-
-The collected Dependency Scanning report uploads to GitLab as an artifact and is summarized in merge requests and the pipeline view. It's also used to provide data for security
-dashboards.
-
-##### `artifacts:reports:dotenv`
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/17066) in GitLab 12.9.
-> - Requires GitLab Runner 11.5 and later.
-
-The `dotenv` report collects a set of environment variables as artifacts.
-
-The collected variables are registered as runtime-created variables of the job,
-which is useful to [set dynamic environment URLs after a job finishes](../environments/index.md#set-dynamic-environment-urls-after-a-job-finishes).
-
-There are a couple of exceptions to the [original dotenv rules](https://github.com/motdotla/dotenv#rules):
-
-- The variable key can contain only letters, digits, and underscores (`_`).
-- The maximum size of the `.env` file is 5 KB.
-- In GitLab 13.5 and older, the maximum number of inherited variables is 10.
-- In [GitLab 13.6 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/247913),
- the maximum number of inherited variables is 20.
-- Variable substitution in the `.env` file is not supported.
-- The `.env` file can't have empty lines or comments (starting with `#`).
-- Key values in the `env` file cannot have spaces or newline characters (`\n`), including when using single or double quotes.
-- Quote escaping during parsing (`key = 'value'` -> `{key: "value"}`) is not supported.
-
-##### `artifacts:reports:junit`
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/20390) in GitLab 11.2.
-> - Requires GitLab Runner 11.2 and above.
-
-The `junit` report collects [JUnit report format XML files](https://www.ibm.com/support/knowledgecenter/en/SSQ2R2_14.1.0/com.ibm.rsar.analysis.codereview.cobol.doc/topics/cac_useresults_junit.html)
-as artifacts. Although JUnit was originally developed in Java, there are many
-third party ports for other
-languages like JavaScript, Python, Ruby, and so on.
-
-See [Unit test reports](../unit_test_reports.md) for more details and examples.
-Below is an example of collecting a JUnit report format XML file from Ruby's RSpec test tool:
-
-```yaml
-rspec:
- stage: test
- script:
- - bundle install
- - rspec --format RspecJunitFormatter --out rspec.xml
- artifacts:
- reports:
- junit: rspec.xml
-```
-
-The collected Unit test reports upload to GitLab as an artifact and display in merge requests.
-
-If the JUnit tool you use exports to multiple XML files, specify
-multiple test report paths within a single job to
-concatenate them into a single file. Use a filename pattern (`junit: rspec-*.xml`),
-an array of filenames (`junit: [rspec-1.xml, rspec-2.xml, rspec-3.xml]`), or a
-combination thereof (`junit: [rspec.xml, test-results/TEST-*.xml]`).
-
-##### `artifacts:reports:license_scanning` **(ULTIMATE)**
-
-> - Introduced in GitLab 12.8.
-> - Requires GitLab Runner 11.5 and above.
-
-The `license_scanning` report collects [Licenses](../../user/compliance/license_compliance/index.md)
-as artifacts.
-
-The License Compliance report uploads to GitLab as an artifact and displays automatically in merge requests and the pipeline view, and provide data for security
-dashboards.
-
-##### `artifacts:reports:load_performance` **(PREMIUM)**
-
-> - Introduced in [GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35260) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.2.
-> - Requires GitLab Runner 11.5 and above.
-
-The `load_performance` report collects [Load Performance Testing metrics](../../user/project/merge_requests/load_performance_testing.md)
-as artifacts.
-
-The report is uploaded to GitLab as an artifact and is
-shown in merge requests automatically.
-
-##### `artifacts:reports:metrics` **(PREMIUM)**
-
-> Introduced in GitLab 11.10.
-
-The `metrics` report collects [Metrics](../metrics_reports.md)
-as artifacts.
-
-The collected Metrics report uploads to GitLab as an artifact and displays in merge requests.
-
-##### `artifacts:reports:browser_performance` **(PREMIUM)**
-
-> - Introduced in GitLab 11.5.
-> - Requires GitLab Runner 11.5 and above.
-> - [Name changed](https://gitlab.com/gitlab-org/gitlab/-/issues/225914) from `artifacts:reports:performance` in GitLab 14.0.
-
-The `browser_performance` report collects [Browser Performance Testing metrics](../../user/project/merge_requests/browser_performance_testing.md)
-as artifacts.
-
-The collected Browser Performance report uploads to GitLab as an artifact and displays in merge requests.
-
-##### `artifacts:reports:requirements` **(ULTIMATE)**
-
-> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2859) in GitLab 13.1.
-> - Requires GitLab Runner 11.5 and above.
-
-The `requirements` report collects `requirements.json` files as artifacts.
-
-The collected Requirements report uploads to GitLab as an artifact and
-existing [requirements](../../user/project/requirements/index.md) are
-marked as Satisfied.
-
-##### `artifacts:reports:sast`
-
-> - Introduced in GitLab 11.5.
-> - Made [available in all tiers](https://gitlab.com/groups/gitlab-org/-/epics/2098) in GitLab 13.3.
-> - Requires GitLab Runner 11.5 and above.
-
-The `sast` report collects [SAST vulnerabilities](../../user/application_security/sast/index.md)
-as artifacts.
-
-The collected SAST report uploads to GitLab as an artifact and is summarized
-in merge requests and the pipeline view. It's also used to provide data for security
-dashboards.
-
-##### `artifacts:reports:secret_detection`
-
-> - Introduced in GitLab 13.1.
-> - Made [available in all tiers](https://gitlab.com/gitlab-org/gitlab/-/issues/222788) in GitLab
- 13.3.
-> - Requires GitLab Runner 11.5 and above.
-
-The `secret-detection` report collects [detected secrets](../../user/application_security/secret_detection/index.md)
-as artifacts.
-
-The collected Secret Detection report is uploaded to GitLab as an artifact and summarized
-in the merge requests and pipeline view. It's also used to provide data for security
-dashboards.
-
-##### `artifacts:reports:terraform`
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207528) in GitLab 13.0.
-> - Requires [GitLab Runner](https://docs.gitlab.com/runner/) 11.5 and above.
-
-The `terraform` report obtains a Terraform `tfplan.json` file. [JQ processing required to remove credentials](../../user/infrastructure/mr_integration.md#setup). The collected Terraform
-plan report uploads to GitLab as an artifact and displays
-in merge requests. For more information, see
-[Output `terraform plan` information into a merge request](../../user/infrastructure/mr_integration.md).
-
-#### `artifacts:untracked`
-
-Use `artifacts:untracked` to add all Git untracked files as artifacts (along
-with the paths defined in `artifacts:paths`). `artifacts:untracked` ignores configuration
-in the repository's `.gitignore` file.
-
-Send all Git untracked files:
-
-```yaml
-artifacts:
- untracked: true
-```
-
-Send all Git untracked files and files in `binaries`:
-
-```yaml
-artifacts:
- untracked: true
- paths:
- - binaries/
-```
-
-Send all untracked files but [exclude](#artifactsexclude) `*.txt`:
-
-```yaml
-artifacts:
- untracked: true
- exclude:
- - "*.txt"
-```
-
-#### `artifacts:when`
-
-Use `artifacts:when` to upload artifacts on job failure or despite the
-failure.
-
-`artifacts:when` can be set to one of the following values:
-
-1. `on_success` (default): Upload artifacts only when the job succeeds.
-1. `on_failure`: Upload artifacts only when the job fails.
-1. `always`: Always upload artifacts. Useful, for example, when
- [uploading artifacts](../unit_test_reports.md#viewing-junit-screenshots-on-gitlab) required to
- troubleshoot failing tests.
-
-For example, to upload artifacts only when a job fails:
-
-```yaml
-job:
- artifacts:
- when: on_failure
-```
-
-### `coverage`
-
-Use `coverage` to configure how code coverage is extracted from the
-job output.
-
-Regular expressions are the only valid kind of value expected here. So, using
-surrounding `/` is mandatory to consistently and explicitly represent
-a regular expression string. You must escape special characters if you want to
-match them literally.
-
-For example:
-
-```yaml
-job1:
- script: rspec
- coverage: '/Code coverage: \d+\.\d+/'
-```
-
-The coverage is shown in the UI if at least one line in the job output matches the regular expression.
-If there is more than one matched line in the job output, the last line is used.
-For the matched line, the first occurrence of `\d+(\.\d+)?` is the code coverage.
-Leading zeros are removed.
-
-Coverage output from [child pipelines](../parent_child_pipelines.md) is not recorded
-or displayed. Check [the related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/280818)
-for more details.
-
-### `retry`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/3515) in GitLab 11.5, you can control which failures to retry on.
-
-Use `retry` to configure how many times a job is retried in
-case of a failure.
-
-When a job fails, the job is processed again,
-until the limit specified by the `retry` keyword is reached.
-
-If `retry` is set to `2`, and a job succeeds in a second run (first retry), it is not retried.
-The `retry` value must be a positive integer, from `0` to `2`
-(two retries maximum, three runs in total).
-
-The following example retries all failure cases:
-
-```yaml
-test:
- script: rspec
- retry: 2
-```
-
-By default, a job is retried on all failure cases. To have better control
-over which failures to retry, `retry` can be a hash with the following keys:
-
-- `max`: The maximum number of retries.
-- `when`: The failure cases to retry.
-
-To retry only runner system failures at maximum two times:
-
-```yaml
-test:
- script: rspec
- retry:
- max: 2
- when: runner_system_failure
-```
-
-If there is another failure, other than a runner system failure, the job
-is not retried.
-
-To retry on multiple failure cases, `when` can also be an array of failures:
-
-```yaml
-test:
- script: rspec
- retry:
- max: 2
- when:
- - runner_system_failure
- - stuck_or_timeout_failure
-```
-
-Possible values for `when` are:
-
-<!--
- If you change any of the values below, make sure to update the `RETRY_WHEN_IN_DOCUMENTATION`
- array in `spec/lib/gitlab/ci/config/entry/retry_spec.rb`.
- The test there makes sure that all documented
- values are valid as a configuration option and therefore should always
- stay in sync with this documentation.
--->
-
-- `always`: Retry on any failure (default).
-- `unknown_failure`: Retry when the failure reason is unknown.
-- `script_failure`: Retry when the script failed.
-- `api_failure`: Retry on API failure.
-- `stuck_or_timeout_failure`: Retry when the job got stuck or timed out.
-- `runner_system_failure`: Retry if there is a runner system failure (for example, job setup failed).
-- `missing_dependency_failure`: Retry if a dependency is missing.
-- `runner_unsupported`: Retry if the runner is unsupported.
-- `stale_schedule`: Retry if a delayed job could not be executed.
-- `job_execution_timeout`: Retry if the script exceeded the maximum execution time set for the job.
-- `archived_failure`: Retry if the job is archived and can't be run.
-- `unmet_prerequisites`: Retry if the job failed to complete prerequisite tasks.
-- `scheduler_failure`: Retry if the scheduler failed to assign the job to a runner.
-- `data_integrity_failure`: Retry if there is a structural integrity problem detected.
-
-You can specify the number of [retry attempts for certain stages of job execution](../runners/configure_runners.md#job-stages-attempts) using variables.
-
-### `timeout`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14887) in GitLab 12.3.
-
-Use `timeout` to configure a timeout for a specific job. For example:
-
-```yaml
-build:
- script: build.sh
- timeout: 3 hours 30 minutes
-
-test:
- script: rspec
- timeout: 3h 30m
-```
-
-The job-level timeout can exceed the
-[project-level timeout](../pipelines/settings.md#timeout) but can't
-exceed the runner-specific timeout.
-
-### `parallel`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/21480) in GitLab 11.5.
-
-Use `parallel` to configure how many instances of a job to run in parallel.
-The value can be from 2 to 50.
-
-The `parallel` keyword creates N instances of the same job that run in parallel.
-They are named sequentially from `job_name 1/N` to `job_name N/N`:
-
-```yaml
-test:
- script: rspec
- parallel: 5
-```
-
-Every parallel job has a `CI_NODE_INDEX` and `CI_NODE_TOTAL`
-[predefined CI/CD variable](../variables/README.md#predefined-cicd-variables) set.
-
-Different languages and test suites have different methods to enable parallelization.
-For example, use [Semaphore Test Boosters](https://github.com/renderedtext/test-boosters)
-and RSpec to run Ruby tests in parallel:
-
-```ruby
-# Gemfile
-source 'https://rubygems.org'
-
-gem 'rspec'
-gem 'semaphore_test_boosters'
-```
-
-```yaml
-test:
- parallel: 3
- script:
- - bundle
- - bundle exec rspec_booster --job $CI_NODE_INDEX/$CI_NODE_TOTAL
-```
-
-WARNING:
-Test Boosters reports usage statistics to the author.
-
-You can then navigate to the **Jobs** tab of a new pipeline build and see your RSpec
-job split into three separate jobs.
-
-#### Parallel `matrix` jobs
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15356) in GitLab 13.3.
-
-Use `matrix:` to run a job multiple times in parallel in a single pipeline,
-but with different variable values for each instance of the job.
-There can be from 2 to 50 jobs.
-
-Jobs can only run in parallel if there are multiple runners, or a single runner is
-[configured to run multiple jobs concurrently](#use-your-own-runners).
-
-Every job gets the same `CI_NODE_TOTAL` [CI/CD variable](../variables/README.md#predefined-cicd-variables) value, and a unique `CI_NODE_INDEX` value.
-
-```yaml
-deploystacks:
- stage: deploy
- script:
- - bin/deploy
- parallel:
- matrix:
- - PROVIDER: aws
- STACK:
- - monitoring
- - app1
- - app2
- - PROVIDER: ovh
- STACK: [monitoring, backup, app]
- - PROVIDER: [gcp, vultr]
- STACK: [data, processing]
-```
-
-The following example generates 10 parallel `deploystacks` jobs, each with different values
-for `PROVIDER` and `STACK`:
-
-```plaintext
-deploystacks: [aws, monitoring]
-deploystacks: [aws, app1]
-deploystacks: [aws, app2]
-deploystacks: [ovh, monitoring]
-deploystacks: [ovh, backup]
-deploystacks: [ovh, app]
-deploystacks: [gcp, data]
-deploystacks: [gcp, processing]
-deploystacks: [vultr, data]
-deploystacks: [vultr, processing]
-```
-
-The job naming style was [improved in GitLab 13.4](https://gitlab.com/gitlab-org/gitlab/-/issues/230452).
-
-##### One-dimensional `matrix` jobs
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/26362) in GitLab 13.5.
-
-You can also have one-dimensional matrices with a single job:
-
-```yaml
-deploystacks:
- stage: deploy
- script:
- - bin/deploy
- parallel:
- matrix:
- - PROVIDER: [aws, ovh, gcp, vultr]
-```
-
-##### Parallel `matrix` trigger jobs
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/270957) in GitLab 13.10.
-
-Use `matrix:` to run a [trigger](#trigger) job multiple times in parallel in a single pipeline,
-but with different variable values for each instance of the job.
-
-```yaml
-deploystacks:
- stage: deploy
- trigger:
- include: path/to/child-pipeline.yml
- parallel:
- matrix:
- - PROVIDER: aws
- STACK: [monitoring, app1]
- - PROVIDER: ovh
- STACK: [monitoring, backup]
- - PROVIDER: [gcp, vultr]
- STACK: [data]
-```
-
-This example generates 6 parallel `deploystacks` trigger jobs, each with different values
-for `PROVIDER` and `STACK`, and they create 6 different child pipelines with those variables.
-
-```plaintext
-deploystacks: [aws, monitoring]
-deploystacks: [aws, app1]
-deploystacks: [ovh, monitoring]
-deploystacks: [ovh, backup]
-deploystacks: [gcp, data]
-deploystacks: [vultr, data]
-```
-
-### `trigger`
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8997) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.8.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/199224) to GitLab Free in 12.8.
-
-Use `trigger` to define a downstream pipeline trigger. When GitLab starts a `trigger` job,
-a downstream pipeline is created.
-
-Jobs with `trigger` can only use a [limited set of keywords](../multi_project_pipelines.md#limitations).
-For example, you can't run commands with [`script`](#script), [`before_script`](#before_script),
-or [`after_script`](#after_script).
-
-You can use this keyword to create two different types of downstream pipelines:
-
-- [Multi-project pipelines](../multi_project_pipelines.md#creating-multi-project-pipelines-from-gitlab-ciyml)
-- [Child pipelines](../parent_child_pipelines.md)
-
-[In GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/issues/197140/) and later, you can
-view which job triggered a downstream pipeline. In the [pipeline graph](../pipelines/index.md#visualize-pipelines),
-hover over the downstream pipeline job.
-
-In [GitLab 13.5](https://gitlab.com/gitlab-org/gitlab/-/issues/201938) and later, you
-can use [`when:manual`](#whenmanual) in the same job as `trigger`. In GitLab 13.4 and
-earlier, using them together causes the error `jobs:#{job-name} when should be on_success, on_failure or always`.
-You [cannot start `manual` trigger jobs with the API](https://gitlab.com/gitlab-org/gitlab/-/issues/284086).
-
-#### Basic `trigger` syntax for multi-project pipelines
-
-You can configure a downstream trigger by using the `trigger` keyword
-with a full path to a downstream project:
-
-```yaml
-rspec:
- stage: test
- script: bundle exec rspec
-
-staging:
- stage: deploy
- trigger: my/deployment
-```
-
-#### Complex `trigger` syntax for multi-project pipelines
-
-You can configure a branch name that GitLab uses to create
-a downstream pipeline with:
-
-```yaml
-rspec:
- stage: test
- script: bundle exec rspec
-
-staging:
- stage: deploy
- trigger:
- project: my/deployment
- branch: stable
-```
-
-To mirror the status from a triggered pipeline:
-
-```yaml
-trigger_job:
- trigger:
- project: my/project
- strategy: depend
-```
-
-To mirror the status from an upstream pipeline:
-
-```yaml
-upstream_bridge:
- stage: test
- needs:
- pipeline: other/project
-```
-
-#### `trigger` syntax for child pipeline
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16094) in GitLab 12.7.
-
-To create a [child pipeline](../parent_child_pipelines.md), specify the path to the
-YAML file that contains the configuration of the child pipeline:
-
-```yaml
-trigger_job:
- trigger:
- include: path/to/child-pipeline.yml
-```
-
-Similar to [multi-project pipelines](../multi_project_pipelines.md#mirroring-status-from-triggered-pipeline),
-it's possible to mirror the status from a triggered pipeline:
-
-```yaml
-trigger_job:
- trigger:
- include:
- - local: path/to/child-pipeline.yml
- strategy: depend
-```
-
-##### Trigger child pipeline with generated configuration file
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35632) in GitLab 12.9.
-
-You can also trigger a child pipeline from a [dynamically generated configuration file](../parent_child_pipelines.md#dynamic-child-pipelines):
-
-```yaml
-generate-config:
- stage: build
- script: generate-ci-config > generated-config.yml
- artifacts:
- paths:
- - generated-config.yml
-
-child-pipeline:
- stage: test
- trigger:
- include:
- - artifact: generated-config.yml
- job: generate-config
-```
-
-The `generated-config.yml` is extracted from the artifacts and used as the configuration
-for triggering the child pipeline.
-
-##### Trigger child pipeline with files from another project
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/205157) in GitLab 13.5.
-
-To trigger child pipelines with files from another private project under the same
-GitLab instance, use [`include:file`](#includefile):
-
-```yaml
-child-pipeline:
- trigger:
- include:
- - project: 'my-group/my-pipeline-library'
- ref: 'main'
- file: '/path/to/child-pipeline.yml'
-```
-
-#### Linking pipelines with `trigger:strategy`
-
-By default, the `trigger` job completes with the `success` status
-as soon as the downstream pipeline is created.
-
-To force the `trigger` job to wait for the downstream (multi-project or child) pipeline to complete, use
-`strategy: depend`. This setting makes the trigger job wait with a "running" status until the triggered
-pipeline completes. At that point, the `trigger` job completes and displays the same status as
-the downstream job.
-
-This setting can help keep your pipeline execution linear. In the following example, jobs from
-subsequent stages wait for the triggered pipeline to successfully complete before
-starting, which reduces parallelization.
-
-```yaml
-trigger_job:
- trigger:
- include: path/to/child-pipeline.yml
- strategy: depend
-```
-
-#### Trigger a pipeline by API call
-
-To force a rebuild of a specific branch, tag, or commit, you can use an API call
-with a trigger token.
-
-The trigger token is different than the [`trigger`](#trigger) keyword.
-
-[Read more in the triggers documentation.](../triggers/README.md)
-
-### `interruptible`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32022) in GitLab 12.3.
-
-Use `interruptible` to indicate that a running job should be canceled if made redundant by a newer pipeline run.
-Defaults to `false` (uninterruptible). Jobs that have not started yet (pending) are considered interruptible
-and safe to be cancelled.
-This value is used only if the [automatic cancellation of redundant pipelines feature](../pipelines/settings.md#auto-cancel-redundant-pipelines)
-is enabled.
-
-When enabled, a pipeline is immediately canceled when a new pipeline starts on the same branch if either of the following is true:
-
-- All jobs in the pipeline are set as interruptible.
-- Any uninterruptible jobs have not started yet.
-
-Set jobs as interruptible that can be safely canceled once started (for instance, a build job).
-
-In the following example, a new pipeline run causes an existing running pipeline to be:
-
-- Canceled, if only `step-1` is running or pending.
-- Not canceled, once `step-2` starts running.
-
-After an uninterruptible job starts running, the pipeline cannot be canceled.
-
-```yaml
-stages:
- - stage1
- - stage2
- - stage3
-
-step-1:
- stage: stage1
- script:
- - echo "Can be canceled."
- interruptible: true
-
-step-2:
- stage: stage2
- script:
- - echo "Can not be canceled."
-
-step-3:
- stage: stage3
- script:
- - echo "Because step-2 can not be canceled, this step can never be canceled, even though it's set as interruptible."
- interruptible: true
-```
-
-### `resource_group`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15536) in GitLab 12.7.
-
-Sometimes running multiple jobs or pipelines at the same time in an environment
-can lead to errors during the deployment.
-
-To avoid these errors, use the `resource_group` attribute to make sure that
-the runner doesn't run certain jobs simultaneously. Resource groups behave similar
-to semaphores in other programming languages.
-
-When the `resource_group` keyword is defined for a job in the `.gitlab-ci.yml` file,
-job executions are mutually exclusive across different pipelines for the same project.
-If multiple jobs belonging to the same resource group are enqueued simultaneously,
-only one of the jobs is picked by the runner. The other jobs wait until the
-`resource_group` is free.
-
-For example:
-
-```yaml
-deploy-to-production:
- script: deploy
- resource_group: production
-```
-
-In this case, two `deploy-to-production` jobs in two separate pipelines can never run at the same time. As a result,
-you can ensure that concurrent deployments never happen to the production environment.
-
-You can define multiple resource groups per environment. For example,
-when deploying to physical devices, you may have multiple physical devices. Each device
-can be deployed to, but there can be only one deployment per device at any given time.
-
-The `resource_group` value can only contain letters, digits, `-`, `_`, `/`, `$`, `{`, `}`, `.`, and spaces.
-It can't start or end with `/`.
-
-For more information, see [Deployments Safety](../environments/deployment_safety.md).
-
-#### Pipeline-level concurrency control with Cross-Project/Parent-Child pipelines
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/39057) in GitLab 13.9.
-
-You can define `resource_group` for downstream pipelines that are sensitive to concurrent
-executions. The [`trigger` keyword](#trigger) can trigger downstream pipelines. The
-[`resource_group` keyword](#resource_group) can co-exist with it. This is useful to control the
-concurrency for deployment pipelines, while running non-sensitive jobs concurrently.
-
-The following example has two pipeline configurations in a project. When a pipeline starts running,
-non-sensitive jobs are executed first and aren't affected by concurrent executions in other
-pipelines. However, GitLab ensures that there are no other deployment pipelines running before
-triggering a deployment (child) pipeline. If other deployment pipelines are running, GitLab waits
-until those pipelines finish before running another one.
-
-```yaml
-# .gitlab-ci.yml (parent pipeline)
-
-build:
- stage: build
- script: echo "Building..."
-
-test:
- stage: test
- script: echo "Testing..."
-
-deploy:
- stage: deploy
- trigger:
- include: deploy.gitlab-ci.yml
- strategy: depend
- resource_group: AWS-production
-```
-
-```yaml
-# deploy.gitlab-ci.yml (child pipeline)
-
-stages:
- - provision
- - deploy
-
-provision:
- stage: provision
- script: echo "Provisioning..."
-
-deployment:
- stage: deploy
- script: echo "Deploying..."
-```
-
-You must define [`strategy: depend`](#linking-pipelines-with-triggerstrategy)
-with the `trigger` keyword. This ensures that the lock isn't released until the downstream pipeline
-finishes.
-
-### `release`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/19298) in GitLab 13.2.
-
-Use `release` to create a [release](../../user/project/releases/index.md).
-Requires the [`release-cli`](https://gitlab.com/gitlab-org/release-cli/-/tree/master/docs)
-to be available in your GitLab Runner Docker or shell executor.
-
-These keywords are supported:
-
-- [`tag_name`](#releasetag_name)
-- [`description`](#releasedescription)
-- [`name`](#releasename) (optional)
-- [`ref`](#releaseref) (optional)
-- [`milestones`](#releasemilestones) (optional)
-- [`released_at`](#releasereleased_at) (optional)
-- [`assets:links`](#releaseassetslinks) (optional)
-
-The release is created only if the job processes without error. If the Rails API
-returns an error during release creation, the `release` job fails.
-
-#### `release-cli` Docker image
-
-You must specify the Docker image to use for the `release-cli`:
-
-```yaml
-image: registry.gitlab.com/gitlab-org/release-cli:latest
-```
-
-#### `release-cli` for shell executors
-
-> [Introduced](https://gitlab.com/gitlab-org/release-cli/-/issues/21) in GitLab 13.8.
-
-For GitLab Runner shell executors, you can download and install the `release-cli` manually for your [supported OS and architecture](https://release-cli-downloads.s3.amazonaws.com/latest/index.html).
-Once installed, the `release` keyword should be available to you.
-
-**Install on Unix/Linux**
-
-1. Download the binary for your system, in the following example for amd64 systems:
-
- ```shell
- curl --location --output /usr/local/bin/release-cli "https://release-cli-downloads.s3.amazonaws.com/latest/release-cli-linux-amd64"
- ```
-
-1. Give it permissions to execute:
-
- ```shell
- sudo chmod +x /usr/local/bin/release-cli
- ```
-
-1. Verify `release-cli` is available:
-
- ```shell
- $ release-cli -v
-
- release-cli version 0.6.0
- ```
-
-**Install on Windows PowerShell**
-
-1. Create a folder somewhere in your system, for example `C:\GitLab\Release-CLI\bin`
-
- ```shell
- New-Item -Path 'C:\GitLab\Release-CLI\bin' -ItemType Directory
- ```
-
-1. Download the executable file:
-
- ```shell
- PS C:\> Invoke-WebRequest -Uri "https://release-cli-downloads.s3.amazonaws.com/latest/release-cli-windows-amd64.exe" -OutFile "C:\GitLab\Release-CLI\bin\release-cli.exe"
-
- Directory: C:\GitLab\Release-CLI
- Mode LastWriteTime Length Name
- ---- ------------- ------ ----
- d----- 3/16/2021 4:17 AM bin
-
- ```
-
-1. Add the directory to your `$env:PATH`:
-
- ```shell
- $env:PATH += ";C:\GitLab\Release-CLI\bin"
- ```
-
-1. Verify `release-cli` is available:
-
- ```shell
- PS C:\> release-cli -v
-
- release-cli version 0.6.0
- ```
-
-#### Use a custom SSL CA certificate authority
-
-You can use the `ADDITIONAL_CA_CERT_BUNDLE` CI/CD variable to configure a custom SSL CA certificate authority,
-which is used to verify the peer when the `release-cli` creates a release through the API using HTTPS with custom certificates.
-The `ADDITIONAL_CA_CERT_BUNDLE` value should contain the
-[text representation of the X.509 PEM public-key certificate](https://tools.ietf.org/html/rfc7468#section-5.1)
-or the `path/to/file` containing the certificate authority.
-For example, to configure this value in the `.gitlab-ci.yml` file, use the following:
-
-```yaml
-release:
- variables:
- ADDITIONAL_CA_CERT_BUNDLE: |
- -----BEGIN CERTIFICATE-----
- MIIGqTCCBJGgAwIBAgIQI7AVxxVwg2kch4d56XNdDjANBgkqhkiG9w0BAQsFADCB
- ...
- jWgmPqF3vUbZE0EyScetPJquRFRKIesyJuBFMAs=
- -----END CERTIFICATE-----
- script:
- - echo "Create release"
- release:
- name: 'My awesome release'
- tag_name: '$CI_COMMIT_TAG'
-```
-
-The `ADDITIONAL_CA_CERT_BUNDLE` value can also be configured as a
-[custom variable in the UI](../variables/README.md#custom-cicd-variables),
-either as a `file`, which requires the path to the certificate, or as a variable,
-which requires the text representation of the certificate.
-
-#### `script`
-
-All jobs except [trigger](#trigger) jobs must have the `script` keyword. A `release`
-job can use the output from script commands, but you can use a placeholder script if
-the script is not needed:
-
-```yaml
-script:
- - echo 'release job'
-```
-
-An [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/223856) exists to remove this requirement in an upcoming version of GitLab.
-
-A pipeline can have multiple `release` jobs, for example:
-
-```yaml
-ios-release:
- script:
- - echo 'iOS release job'
- release:
- tag_name: v1.0.0-ios
- description: 'iOS release v1.0.0'
-
-android-release:
- script:
- - echo 'Android release job'
- release:
- tag_name: v1.0.0-android
- description: 'Android release v1.0.0'
-```
-
-#### `release:tag_name`
-
-You must specify a `tag_name` for the release. The tag can refer to an existing Git tag or
-you can specify a new tag.
-
-When the specified tag doesn't exist in the repository, a new tag is created from the associated SHA of the pipeline.
-
-For example, when creating a release from a Git tag:
-
-```yaml
-job:
- release:
- tag_name: $CI_COMMIT_TAG
- description: 'Release description'
-```
-
-It is also possible for the release job to automatically create a new unique tag. In that case,
-do not use [`rules`](#rules) or [`only`](#only--except) to configure the job to
-only run for tags.
-
-A semantic versioning example:
-
-```yaml
-job:
- release:
- tag_name: ${MAJOR}_${MINOR}_${REVISION}
- description: 'Release description'
-```
-
-- The release is created only if the job's main script succeeds.
-- If the release already exists, it is not updated and the job with the `release` keyword fails.
-- The `release` section executes after the `script` tag and before the `after_script`.
-
-#### `release:name`
-
-The release name. If omitted, it is populated with the value of `release: tag_name`.
-
-#### `release:description`
-
-Specifies the long description of the release. You can also specify a file that contains the
-description.
-
-##### Read description from a file
-
-> [Introduced](https://gitlab.com/gitlab-org/release-cli/-/merge_requests/67) in GitLab 13.7.
-
-You can specify a file in `$CI_PROJECT_DIR` that contains the description. The file must be relative
-to the project directory (`$CI_PROJECT_DIR`), and if the file is a symbolic link it can't reside
-outside of `$CI_PROJECT_DIR`. The `./path/to/file` and filename can't contain spaces.
-
-```yaml
-job:
- release:
- tag_name: ${MAJOR}_${MINOR}_${REVISION}
- description: './path/to/CHANGELOG.md'
-```
-
-#### `release:ref`
-
-If the `release: tag_name` doesn't exist yet, the release is created from `ref`.
-`ref` can be a commit SHA, another tag name, or a branch name.
-
-#### `release:milestones`
-
-The title of each milestone the release is associated with.
-
-#### `release:released_at`
-
-The date and time when the release is ready. Defaults to the current date and time if not
-defined. Should be enclosed in quotes and expressed in ISO 8601 format.
-
-```json
-released_at: '2021-03-15T08:00:00Z'
-```
-
-#### `release:assets:links`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/271454) in GitLab 13.12.
-
-Include [asset links](../../user/project/releases/index.md#release-assets) in the release.
-
-NOTE:
-Requires `release-cli` version v0.4.0 or higher.
-
-```yaml
-assets:
- links:
- - name: 'asset1'
- url: 'https://example.com/assets/1'
- - name: 'asset2'
- url: 'https://example.com/assets/2'
- filepath: '/pretty/url/1' # optional
- link_type: 'other' # optional
-```
-
-#### Complete example for `release`
-
-If you combine the previous examples for `release`, you get two options, depending on how you generate the
-tags. You can't use these options together, so choose one:
-
-- To create a release when you push a Git tag, or when you add a Git tag
- in the UI by going to **Repository > Tags**:
-
- ```yaml
- release_job:
- stage: release
- image: registry.gitlab.com/gitlab-org/release-cli:latest
- rules:
- - if: $CI_COMMIT_TAG # Run this job when a tag is created manually
- script:
- - echo 'running release_job'
- release:
- name: 'Release $CI_COMMIT_TAG'
- description: 'Created using the release-cli $EXTRA_DESCRIPTION' # $EXTRA_DESCRIPTION must be defined
- tag_name: '$CI_COMMIT_TAG' # elsewhere in the pipeline.
- ref: '$CI_COMMIT_TAG'
- milestones:
- - 'm1'
- - 'm2'
- - 'm3'
- released_at: '2020-07-15T08:00:00Z' # Optional, is auto generated if not defined, or can use a variable.
- assets: # Optional, multiple asset links
- links:
- - name: 'asset1'
- url: 'https://example.com/assets/1'
- - name: 'asset2'
- url: 'https://example.com/assets/2'
- filepath: '/pretty/url/1' # optional
- link_type: 'other' # optional
- ```
-
-- To create a release automatically when commits are pushed or merged to the default branch,
- using a new Git tag that is defined with variables:
-
- NOTE:
- Environment variables set in `before_script` or `script` are not available for expanding
- in the same job. Read more about
- [potentially making variables available for expanding](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/6400).
-
- ```yaml
- prepare_job:
- stage: prepare # This stage must run before the release stage
- rules:
- - if: $CI_COMMIT_TAG
- when: never # Do not run this job when a tag is created manually
- - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch
- script:
- - echo "EXTRA_DESCRIPTION=some message" >> variables.env # Generate the EXTRA_DESCRIPTION and TAG environment variables
- - echo "TAG=v$(cat VERSION)" >> variables.env # and append to the variables.env file
- artifacts:
- reports:
- dotenv: variables.env # Use artifacts:reports:dotenv to expose the variables to other jobs
-
- release_job:
- stage: release
- image: registry.gitlab.com/gitlab-org/release-cli:latest
- needs:
- - job: prepare_job
- artifacts: true
- rules:
- - if: $CI_COMMIT_TAG
- when: never # Do not run this job when a tag is created manually
- - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch
- script:
- - echo 'running release_job for $TAG'
- release:
- name: 'Release $TAG'
- description: 'Created using the release-cli $EXTRA_DESCRIPTION' # $EXTRA_DESCRIPTION and the $TAG
- tag_name: '$TAG' # variables must be defined elsewhere
- ref: '$CI_COMMIT_SHA' # in the pipeline. For example, in the
- milestones: # prepare_job
- - 'm1'
- - 'm2'
- - 'm3'
- released_at: '2020-07-15T08:00:00Z' # Optional, is auto generated if not defined, or can use a variable.
- assets:
- links:
- - name: 'asset1'
- url: 'https://example.com/assets/1'
- - name: 'asset2'
- url: 'https://example.com/assets/2'
- filepath: '/pretty/url/1' # optional
- link_type: 'other' # optional
- ```
-
-#### Release assets as Generic packages
-
-You can use [Generic packages](../../user/packages/generic_packages/) to host your release assets.
-For a complete example, see the [Release assets as Generic packages](https://gitlab.com/gitlab-org/release-cli/-/tree/master/docs/examples/release-assets-as-generic-package/)
-project.
-
-#### `release-cli` command line
-
-The entries under the `release` node are transformed into a `bash` command line and sent
-to the Docker container, which contains the [release-cli](https://gitlab.com/gitlab-org/release-cli).
-You can also call the `release-cli` directly from a `script` entry.
-
-For example, if you use the YAML described previously:
-
-```shell
-release-cli create --name "Release $CI_COMMIT_SHA" --description "Created using the release-cli $EXTRA_DESCRIPTION" --tag-name "v${MAJOR}.${MINOR}.${REVISION}" --ref "$CI_COMMIT_SHA" --released-at "2020-07-15T08:00:00Z" --milestone "m1" --milestone "m2" --milestone "m3" --assets-link "{\"name\":\"asset1\",\"url\":\"https://example.com/assets/1\",\"link_type\":\"other\"}
-```
-
-### `secrets`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33014) in GitLab 13.4.
-
-Use `secrets` to specify the [CI/CD Secrets](../secrets/index.md) the job needs. It should be a hash,
-and the keys should be the names of the variables that are made available to the job.
-The value of each secret is saved in a temporary file. This file's path is stored in these
-variables.
-
-#### `secrets:vault` **(PREMIUM)**
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/28321) in GitLab 13.4.
-
-Use `vault` to specify secrets provided by [Hashicorp's Vault](https://www.vaultproject.io/).
-
-This syntax has multiple forms. The shortest form assumes the use of the
-[KV-V2](https://www.vaultproject.io/docs/secrets/kv/kv-v2) secrets engine,
-mounted at the default path `kv-v2`. The last part of the secret's path is the
-field to fetch the value for:
-
-```yaml
-job:
- secrets:
- DATABASE_PASSWORD:
- vault: production/db/password # translates to secret `kv-v2/data/production/db`, field `password`
-```
-
-You can specify a custom secrets engine path by adding a suffix starting with `@`:
-
-```yaml
-job:
- secrets:
- DATABASE_PASSWORD:
- vault: production/db/password@ops # translates to secret `ops/data/production/db`, field `password`
-```
-
-In the detailed form of the syntax, you can specify all details explicitly:
-
-```yaml
-job:
- secrets:
- DATABASE_PASSWORD: # translates to secret `ops/data/production/db`, field `password`
- vault:
- engine:
- name: kv-v2
- path: ops
- path: production/db
- field: password
-```
-
-### `pages`
-
-Use `pages` to upload static content to GitLab. The content
-is then published as a website. You must:
-
-- Place any static content in a `public/` directory.
-- Define [`artifacts`](#artifacts) with a path to the `public/` directory.
-
-The following example moves all files from the root of the project to the
-`public/` directory. The `.public` workaround is so `cp` does not also copy
-`public/` to itself in an infinite loop:
-
-```yaml
-pages:
- stage: deploy
- script:
- - mkdir .public
- - cp -r * .public
- - mv .public public
- artifacts:
- paths:
- - public
- rules:
- - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
-```
-
-View the [GitLab Pages user documentation](../../user/project/pages/index.md).
-
-### `inherit`
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207484) in GitLab 12.9.
-
-Use `inherit:` to control inheritance of globally-defined defaults
-and variables.
-
-To enable or disable the inheritance of all `default:` or `variables:` keywords, use:
-
-- `default: true` or `default: false`
-- `variables: true` or `variables: false`
-
-To inherit only a subset of `default:` keywords or `variables:`, specify what
-you wish to inherit. Anything not listed is **not** inherited. Use
-one of the following formats:
-
-```yaml
-inherit:
- default: [keyword1, keyword2]
- variables: [VARIABLE1, VARIABLE2]
-```
-
-Or:
-
-```yaml
-inherit:
- default:
- - keyword1
- - keyword2
- variables:
- - VARIABLE1
- - VARIABLE2
-```
-
-In the following example:
-
-- `rubocop`:
- - inherits: Nothing.
-- `rspec`:
- - inherits: the default `image` and the `WEBHOOK_URL` variable.
- - does **not** inherit: the default `before_script` and the `DOMAIN` variable.
-- `capybara`:
- - inherits: the default `before_script` and `image`.
- - does **not** inherit: the `DOMAIN` and `WEBHOOK_URL` variables.
-- `karma`:
- - inherits: the default `image` and `before_script`, and the `DOMAIN` variable.
- - does **not** inherit: `WEBHOOK_URL` variable.
-
-```yaml
-default:
- image: 'ruby:2.4'
- before_script:
- - echo Hello World
-
-variables:
- DOMAIN: example.com
- WEBHOOK_URL: https://my-webhook.example.com
-
-rubocop:
- inherit:
- default: false
- variables: false
- script: bundle exec rubocop
-
-rspec:
- inherit:
- default: [image]
- variables: [WEBHOOK_URL]
- script: bundle exec rspec
-
-capybara:
- inherit:
- variables: false
- script: bundle exec capybara
-
-karma:
- inherit:
- default: true
- variables: [DOMAIN]
- script: karma
-```
-
-## `variables`
-
-> Introduced in GitLab Runner v0.5.0.
-
-[CI/CD variables](../variables/README.md) are configurable values that are passed to jobs.
-They can be set globally and per-job.
-
-There are two types of variables.
-
-- [Custom variables](../variables/README.md#custom-cicd-variables):
- You can define their values in the `.gitlab-ci.yml` file, in the GitLab UI,
- or by using the API. You can also input variables in the GitLab UI when
- [running a pipeline manually](../pipelines/index.md#run-a-pipeline-manually).
-- [Predefined variables](../variables/predefined_variables.md):
- These values are set by the runner itself.
- One example is `CI_COMMIT_REF_NAME`, which is the branch or tag the project is built for.
-
-After you define a variable, you can use it in all executed commands and scripts.
-
-Variables are meant for non-sensitive project configuration, for example:
-
-```yaml
-variables:
- DEPLOY_SITE: "https://example.com/"
-
-deploy_job:
- stage: deploy
- script:
- - deploy-script --url $DEPLOY_SITE --path "/"
-
-deploy_review_job:
- stage: deploy
- variables:
- REVIEW_PATH: "/review"
- script:
- - deploy-review-script --url $DEPLOY_SITE --path $REVIEW_PATH
-```
-
-You can use only integers and strings for the variable's name and value.
-
-If you define a variable at the top level of the `gitlab-ci.yml` file, it is global,
-meaning it applies to all jobs. If you define a variable in a job, it's available
-to that job only.
-
-If a variable of the same name is defined globally and for a specific job, the
-[job-specific variable overrides the global variable](../variables/README.md#cicd-variable-precedence).
-
-All YAML-defined variables are also set to any linked
-[Docker service containers](../services/index.md).
-
-You can use [YAML anchors for variables](#yaml-anchors-for-variables).
-
-### Prefill variables in manual pipelines
-
-> [Introduced in](https://gitlab.com/gitlab-org/gitlab/-/issues/30101) GitLab 13.7.
-
-Use the `value` and `description` keywords to define [pipeline-level (global) variables that are prefilled](../pipelines/index.md#prefill-variables-in-manual-pipelines)
-when [running a pipeline manually](../pipelines/index.md#run-a-pipeline-manually):
-
-```yaml
-variables:
- DEPLOY_ENVIRONMENT:
- value: "staging" # Deploy to staging by default
- description: "The deployment target. Change this variable to 'canary' or 'production' if needed."
-```
-
-You cannot set job-level variables to be pre-filled when you run a pipeline manually.
-
-### Configure runner behavior with variables
-
-You can use [CI/CD variables](../variables/README.md) to configure how the runner processes Git requests:
-
-- [`GIT_STRATEGY`](../runners/configure_runners.md#git-strategy)
-- [`GIT_SUBMODULE_STRATEGY`](../runners/configure_runners.md#git-submodule-strategy)
-- [`GIT_CHECKOUT`](../runners/configure_runners.md#git-checkout)
-- [`GIT_CLEAN_FLAGS`](../runners/configure_runners.md#git-clean-flags)
-- [`GIT_FETCH_EXTRA_FLAGS`](../runners/configure_runners.md#git-fetch-extra-flags)
-- [`GIT_DEPTH`](../runners/configure_runners.md#shallow-cloning) (shallow cloning)
-- [`GIT_CLONE_PATH`](../runners/configure_runners.md#custom-build-directories) (custom build directories)
-- [`TRANSFER_METER_FREQUENCY`](../runners/configure_runners.md#artifact-and-cache-settings) (artifact/cache meter update frequency)
-- [`ARTIFACT_COMPRESSION_LEVEL`](../runners/configure_runners.md#artifact-and-cache-settings) (artifact archiver compression level)
-- [`CACHE_COMPRESSION_LEVEL`](../runners/configure_runners.md#artifact-and-cache-settings) (cache archiver compression level)
-
-You can also use variables to configure how many times a runner
-[attempts certain stages of job execution](../runners/configure_runners.md#job-stages-attempts).
-
-## YAML-specific features
-
-In your `.gitlab-ci.yml` file, you can use YAML-specific features like anchors (`&`), aliases (`*`),
-and map merging (`<<`). Use these features to reduce the complexity
-of the code in the `.gitlab-ci.yml` file.
-
-Read more about the various [YAML features](https://learnxinyminutes.com/docs/yaml/).
-
-In most cases, the [`extends` keyword](#extends) is more user friendly and you should
-use it when possible.
-
-You can use YAML anchors to merge YAML arrays.
-
-### Anchors
-
-YAML has a feature called 'anchors' that you can use to duplicate
-content across your document.
-
-Use anchors to duplicate or inherit properties. Use anchors with [hidden jobs](#hide-jobs)
-to provide templates for your jobs. When there are duplicate keys, GitLab
-performs a reverse deep merge based on the keys.
-
-You can't use YAML anchors across multiple files when using the [`include`](#include)
-keyword. Anchors are only valid in the file they were defined in. To reuse configuration
-from different YAML files, use [`!reference` tags](#reference-tags) or the
-[`extends` keyword](#extends).
-
-The following example uses anchors and map merging. It creates two jobs,
-`test1` and `test2`, that inherit the `.job_template` configuration, each
-with their own custom `script` defined:
-
-```yaml
-.job_template: &job_configuration # Hidden yaml configuration that defines an anchor named 'job_configuration'
- image: ruby:2.6
- services:
- - postgres
- - redis
-
-test1:
- <<: *job_configuration # Merge the contents of the 'job_configuration' alias
- script:
- - test1 project
-
-test2:
- <<: *job_configuration # Merge the contents of the 'job_configuration' alias
- script:
- - test2 project
-```
-
-`&` sets up the name of the anchor (`job_configuration`), `<<` means "merge the
-given hash into the current one," and `*` includes the named anchor
-(`job_configuration` again). The expanded version of this example is:
-
-```yaml
-.job_template:
- image: ruby:2.6
- services:
- - postgres
- - redis
-
-test1:
- image: ruby:2.6
- services:
- - postgres
- - redis
- script:
- - test1 project
-
-test2:
- image: ruby:2.6
- services:
- - postgres
- - redis
- script:
- - test2 project
-```
-
-You can use anchors to define two sets of services. For example, `test:postgres`
-and `test:mysql` share the `script` defined in `.job_template`, but use different
-`services`, defined in `.postgres_services` and `.mysql_services`:
-
-```yaml
-.job_template: &job_configuration
- script:
- - test project
- tags:
- - dev
-
-.postgres_services:
- services: &postgres_configuration
- - postgres
- - ruby
-
-.mysql_services:
- services: &mysql_configuration
- - mysql
- - ruby
-
-test:postgres:
- <<: *job_configuration
- services: *postgres_configuration
- tags:
- - postgres
-
-test:mysql:
- <<: *job_configuration
- services: *mysql_configuration
-```
-
-The expanded version is:
-
-```yaml
-.job_template:
- script:
- - test project
- tags:
- - dev
-
-.postgres_services:
- services:
- - postgres
- - ruby
-
-.mysql_services:
- services:
- - mysql
- - ruby
-
-test:postgres:
- script:
- - test project
- services:
- - postgres
- - ruby
- tags:
- - postgres
-
-test:mysql:
- script:
- - test project
- services:
- - mysql
- - ruby
- tags:
- - dev
-```
-
-You can see that the hidden jobs are conveniently used as templates, and
-`tags: [postgres]` overwrites `tags: [dev]`.
-
-#### YAML anchors for scripts
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23005) in GitLab 12.5.
-
-You can use [YAML anchors](#anchors) with [script](#script), [`before_script`](#before_script),
-and [`after_script`](#after_script) to use predefined commands in multiple jobs:
-
-```yaml
-.some-script-before: &some-script-before
- - echo "Execute this script first"
-
-.some-script: &some-script
- - echo "Execute this script second"
- - echo "Execute this script too"
-
-.some-script-after: &some-script-after
- - echo "Execute this script last"
-
-job1:
- before_script:
- - *some-script-before
- script:
- - *some-script
- - echo "Execute something, for this job only"
- after_script:
- - *some-script-after
-
-job2:
- script:
- - *some-script-before
- - *some-script
- - echo "Execute something else, for this job only"
- - *some-script-after
-```
-
-#### YAML anchors for variables
-
-Use [YAML anchors](#anchors) with `variables` to repeat assignment
-of variables across multiple jobs. You can also use YAML anchors when a job
-requires a specific `variables` block that would otherwise override the global variables.
-
-The following example shows how override the `GIT_STRATEGY` variable without affecting
-the use of the `SAMPLE_VARIABLE` variable:
-
-```yaml
-# global variables
-variables: &global-variables
- SAMPLE_VARIABLE: sample_variable_value
- ANOTHER_SAMPLE_VARIABLE: another_sample_variable_value
-
-# a job that must set the GIT_STRATEGY variable, yet depend on global variables
-job_no_git_strategy:
- stage: cleanup
- variables:
- <<: *global-variables
- GIT_STRATEGY: none
- script: echo $SAMPLE_VARIABLE
-```
-
-### Hide jobs
-
-If you want to temporarily disable a job, rather than commenting out all the
-lines where the job is defined:
-
-```yaml
-# hidden_job:
-# script:
-# - run test
-```
-
-Instead, you can start its name with a dot (`.`) and it is not processed by
-GitLab CI/CD. In the following example, `.hidden_job` is ignored:
-
-```yaml
-.hidden_job:
- script:
- - run test
-```
-
-Use this feature to ignore jobs, or use the
-[YAML-specific features](#yaml-specific-features) and transform the hidden jobs
-into templates.
-
-### `!reference` tags
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/266173) in GitLab 13.9.
-
-Use the `!reference` custom YAML tag to select keyword configuration from other job
-sections and reuse it in the current section. Unlike [YAML anchors](#anchors), you can
-use `!reference` tags to reuse configuration from [included](#include) configuration
-files as well.
-
-In the following example, a `script` and an `after_script` from two different locations are
-reused in the `test` job:
-
-- `setup.yml`:
-
- ```yaml
- .setup:
- script:
- - echo creating environment
- ```
-
-- `.gitlab-ci.yml`:
-
- ```yaml
- include:
- - local: setup.yml
-
- .teardown:
- after_script:
- - echo deleting environment
-
- test:
- script:
- - !reference [.setup, script]
- - echo running my own command
- after_script:
- - !reference [.teardown, after_script]
- ```
-
-In the following example, `test-vars-1` reuses all the variables in `.vars`, while `test-vars-2`
-selects a specific variable and reuses it as a new `MY_VAR` variable.
-
-```yaml
-.vars:
- variables:
- URL: "http://my-url.internal"
- IMPORTANT_VAR: "the details"
-
-test-vars-1:
- variables: !reference [.vars, variables]
- script:
- - printenv
-
-test-vars-2:
- variables:
- MY_VAR: !reference [.vars, variables, IMPORTANT_VAR]
- script:
- - printenv
-```
-
-You can't reuse a section that already includes a `!reference` tag. Only one level
-of nesting is supported.
-
-## Skip Pipeline
-
-To push a commit without triggering a pipeline, add `[ci skip]` or `[skip ci]`, using any
-capitalization, to your commit message.
-
-Alternatively, if you are using Git 2.10 or later, use the `ci.skip` [Git push option](../../user/project/push_options.md#push-options-for-gitlab-cicd).
-The `ci.skip` push option does not skip merge request
-pipelines.
-
-## Processing Git pushes
-
-GitLab creates at most four branch and tag pipelines when
-pushing multiple changes in a single `git push` invocation.
-
-This limitation does not affect any of the updated merge request pipelines.
-All updated merge requests have a pipeline created when using
-[pipelines for merge requests](../merge_request_pipelines/index.md).
-
-## Deprecated keywords
-
-The following keywords are deprecated.
-
-### Globally-defined `types`
-
-WARNING:
-`types` is deprecated, and could be removed in a future release.
-Use [`stages`](#stages) instead.
-
-### Job-defined `type`
-
-WARNING:
-`type` is deprecated, and could be removed in one of the future releases.
-Use [`stage`](#stage) instead.
-
-### Globally-defined `image`, `services`, `cache`, `before_script`, `after_script`
-
-Defining `image`, `services`, `cache`, `before_script`, and
-`after_script` globally is deprecated. Support could be removed
-from a future release.
-
-Use [`default:`](#custom-default-keyword-values) instead. For example:
-
-```yaml
-default:
- image: ruby:3.0
- services:
- - docker:dind
- cache:
- paths: [vendor/]
- before_script:
- - bundle config set path vendor/bundle
- - bundle install
- after_script:
- - rm -rf tmp/
-```
-
-<!-- ## Troubleshooting
-
-Include any troubleshooting steps that you can foresee. If you know beforehand what issues
-one might have when setting this up, or when something is changed, or on upgrading, it's
-important to describe those, too. Think of things that may go wrong and include them here.
-This is important to minimize requests for support, and to avoid doc comments with
-questions that you know someone might ask.
-
-Each scenario can be a third-level heading, e.g. `### Getting error message X`.
-If you have none to add when creating a doc, leave this section in place
-but commented out to help encourage others to add to it in the future. -->
+<!-- This redirect file can be deleted after 2021-09-28. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/ci/yaml/gitlab_ci_yaml.md b/doc/ci/yaml/gitlab_ci_yaml.md
index 266b35bd27f..2723cb19c1f 100644
--- a/doc/ci/yaml/gitlab_ci_yaml.md
+++ b/doc/ci/yaml/gitlab_ci_yaml.md
@@ -6,14 +6,14 @@ type: reference
---
<!-- markdownlint-disable MD044 -->
<!-- vale gitlab.Spelling = NO -->
-# The .gitlab-ci.yml file
+# The .gitlab-ci.yml file **(FREE)**
<!-- vale gitlab.Spelling = YES -->
<!-- markdownlint-enable MD044 -->
To use GitLab CI/CD, you need:
- Application code hosted in a Git repository.
-- A file called [`.gitlab-ci.yml`](README.md) in the root of your repository, which
+- A file called [`.gitlab-ci.yml`](index.md) in the root of your repository, which
contains the CI/CD configuration.
In the `.gitlab-ci.yml` file, you can define:
@@ -27,7 +27,7 @@ In the `.gitlab-ci.yml` file, you can define:
The scripts are grouped into **jobs**, and jobs run as part of a larger
**pipeline**. You can group multiple independent jobs into **stages** that run in a defined order.
-The CI/CD configuration needs at least one job that is [not hidden](README.md#hide-jobs).
+The CI/CD configuration needs at least one job that is [not hidden](index.md#hide-jobs).
You should organize your jobs in a sequence that suits your application and is in accordance with
the tests you wish to perform. To [visualize](../pipeline_editor/index.md#visualize-ci-configuration) the process, imagine
@@ -89,4 +89,4 @@ If anything goes wrong, you can
![rollback button](img/rollback.png)
-[View the full syntax for the `.gitlab-ci.yml` file](README.md).
+[View the full syntax for the `.gitlab-ci.yml` file](index.md).
diff --git a/doc/ci/yaml/includes.md b/doc/ci/yaml/includes.md
index 549a6fb964b..673a4e75c35 100644
--- a/doc/ci/yaml/includes.md
+++ b/doc/ci/yaml/includes.md
@@ -5,10 +5,10 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# GitLab CI/CD include examples
+# GitLab CI/CD include examples **(FREE)**
-In addition to the [`includes` examples](README.md#include) listed in the
-[GitLab CI YAML reference](README.md), this page lists more variations of `include`
+In addition to the [`includes` examples](index.md#include) listed in the
+[GitLab CI YAML reference](index.md), this page lists more variations of `include`
usage.
## Single string or array of multiple values
diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md
new file mode 100644
index 00000000000..c2b8ef50e6a
--- /dev/null
+++ b/doc/ci/yaml/index.md
@@ -0,0 +1,4935 @@
+---
+stage: Verify
+group: Pipeline Execution
+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
+type: reference
+---
+
+<!-- markdownlint-disable MD044 -->
+<!-- vale gitlab.Spelling = NO -->
+# Keyword reference for the .gitlab-ci.yml file **(FREE)**
+<!-- vale gitlab.Spelling = YES -->
+<!-- markdownlint-enable MD044 -->
+
+This document lists the configuration options for your GitLab `.gitlab-ci.yml` file.
+
+- For a quick introduction to GitLab CI/CD, follow the [quick start guide](../quick_start/index.md).
+- For a collection of examples, see [GitLab CI/CD Examples](../examples/README.md).
+- To view a large `.gitlab-ci.yml` file used in an enterprise, see the [`.gitlab-ci.yml` file for `gitlab`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab-ci.yml).
+
+When you are editing your `.gitlab-ci.yml` file, you can validate it with the
+[CI Lint](../lint.md) tool.
+
+## Job keywords
+
+A job is defined as a list of keywords that define the job's behavior.
+
+The keywords available for jobs are:
+
+| Keyword | Description |
+| :-------------------------------------------|:------------|
+| [`after_script`](#after_script) | Override a set of commands that are executed after job. |
+| [`allow_failure`](#allow_failure) | Allow job to fail. A failed job does not cause the pipeline to fail. |
+| [`artifacts`](#artifacts) | List of files and directories to attach to a job on success. |
+| [`before_script`](#before_script) | Override a set of commands that are executed before job. |
+| [`cache`](#cache) | List of files that should be cached between subsequent runs. |
+| [`coverage`](#coverage) | Code coverage settings for a given job. |
+| [`dast_configuration`](#dast_configuration) | Use configuration from DAST profiles on a job level. |
+| [`dependencies`](#dependencies) | Restrict which artifacts are passed to a specific job by providing a list of jobs to fetch artifacts from. |
+| [`environment`](#environment) | Name of an environment to which the job deploys. |
+| [`except`](#only--except) | Control when jobs are not created. |
+| [`extends`](#extends) | Configuration entries that this job inherits from. |
+| [`image`](#image) | Use Docker images. |
+| [`include`](#include) | Include external YAML files. |
+| [`inherit`](#inherit) | Select which global defaults all jobs inherit. |
+| [`interruptible`](#interruptible) | Defines if a job can be canceled when made redundant by a newer run. |
+| [`needs`](#needs) | Execute jobs earlier than the stage ordering. |
+| [`only`](#only--except) | Control when jobs are created. |
+| [`pages`](#pages) | Upload the result of a job to use with GitLab Pages. |
+| [`parallel`](#parallel) | How many instances of a job should be run in parallel. |
+| [`release`](#release) | Instructs the runner to generate a [release](../../user/project/releases/index.md) object. |
+| [`resource_group`](#resource_group) | Limit job concurrency. |
+| [`retry`](#retry) | When and how many times a job can be auto-retried in case of a failure. |
+| [`rules`](#rules) | List of conditions to evaluate and determine selected attributes of a job, and whether or not it's created. |
+| [`script`](#script) | Shell script that is executed by a runner. |
+| [`secrets`](#secrets) | The CI/CD secrets the job needs. |
+| [`services`](#services) | Use Docker services images. |
+| [`stage`](#stage) | Defines a job stage. |
+| [`tags`](#tags) | List of tags that are used to select a runner. |
+| [`timeout`](#timeout) | Define a custom job-level timeout that takes precedence over the project-wide setting. |
+| [`trigger`](#trigger) | Defines a downstream pipeline trigger. |
+| [`variables`](#variables) | Define job variables on a job level. |
+| [`when`](#when) | When to run job. |
+
+### Unavailable names for jobs
+
+You can't use these keywords as job names:
+
+- `image`
+- `services`
+- `stages`
+- `types`
+- `before_script`
+- `after_script`
+- `variables`
+- `cache`
+- `include`
+
+### Custom default keyword values
+
+You can set global defaults for some keywords. Jobs that do not define one or more
+of the listed keywords use the value defined in the `default:` section.
+
+These job keywords can be defined inside a `default:` section:
+
+- [`after_script`](#after_script)
+- [`artifacts`](#artifacts)
+- [`before_script`](#before_script)
+- [`cache`](#cache)
+- [`image`](#image)
+- [`interruptible`](#interruptible)
+- [`retry`](#retry)
+- [`services`](#services)
+- [`tags`](#tags)
+- [`timeout`](#timeout)
+
+The following example sets the `ruby:3.0` image as the default for all jobs in the pipeline.
+The `rspec 2.7` job does not use the default, because it overrides the default with
+a job-specific `image:` section:
+
+```yaml
+default:
+ image: ruby:3.0
+
+rspec:
+ script: bundle exec rspec
+
+rspec 2.7:
+ image: ruby:2.7
+ script: bundle exec rspec
+```
+
+## Global keywords
+
+Some keywords are not defined in a job. These keywords control pipeline behavior
+or import additional pipeline configuration:
+
+| Keyword | Description |
+|-------------------------|:------------|
+| [`stages`](#stages) | The names and order of the pipeline stages. |
+| [`workflow`](#workflow) | Control what types of pipeline run. |
+| [`include`](#include) | Import configuration from other YAML files. |
+
+### `stages`
+
+Use `stages` to define stages that contain groups of jobs. `stages` is defined globally
+for the pipeline. Use [`stage`](#stage) in a job to define which stage the job is
+part of.
+
+The order of the `stages` items defines the execution order for jobs:
+
+- Jobs in the same stage run in parallel.
+- Jobs in the next stage run after the jobs from the previous stage complete successfully.
+
+For example:
+
+```yaml
+stages:
+ - build
+ - test
+ - deploy
+```
+
+1. All jobs in `build` execute in parallel.
+1. If all jobs in `build` succeed, the `test` jobs execute in parallel.
+1. If all jobs in `test` succeed, the `deploy` jobs execute in parallel.
+1. If all jobs in `deploy` succeed, the pipeline is marked as `passed`.
+
+If any job fails, the pipeline is marked as `failed` and jobs in later stages do not
+start. Jobs in the current stage are not stopped and continue to run.
+
+If no `stages` are defined in the `.gitlab-ci.yml` file, then `build`, `test` and `deploy`
+are the default pipeline stages.
+
+If a job does not specify a [`stage`](#stage), the job is assigned the `test` stage.
+
+If a stage is defined, but no jobs use it, the stage is not visible in the pipeline. This is
+useful for [compliance pipeline configuration](../../user/project/settings/index.md#compliance-pipeline-configuration)
+because:
+
+- Stages can be defined in the compliance configuration but remain hidden if not used.
+- The defined stages become visible when developers use them in job definitions.
+
+To make a job start earlier and ignore the stage order, use
+the [`needs`](#needs) keyword.
+
+### `workflow`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/29654) in GitLab 12.5
+
+Use `workflow:` to determine whether or not a pipeline is created.
+Define this keyword at the top level, with a single `rules:` keyword that
+is similar to [`rules:` defined in jobs](#rules).
+
+You can use the [`workflow:rules` templates](#workflowrules-templates) to import
+a preconfigured `workflow: rules` entry.
+
+`workflow: rules` accepts these keywords:
+
+- [`if`](#rulesif): Check this rule to determine when to run a pipeline.
+- [`when`](#when): Specify what to do when the `if` rule evaluates to true.
+ - To run a pipeline, set to `always`.
+ - To prevent pipelines from running, set to `never`.
+- [`variables`](#workflowrulesvariables): If not defined, uses the [variables defined elsewhere](#variables).
+
+When no rules evaluate to true, the pipeline does not run.
+
+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.
+
+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:
+
+```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.
+
+If your rules match both branch pipelines and merge request pipelines,
+[duplicate pipelines](../jobs/job_control.md#avoid-duplicate-pipelines) can occur.
+
+#### `workflow:rules:variables`
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/294232) in GitLab 13.11.
+> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/300997) in GitLab 14.1.
+
+You can use [`variables`](#variables) in `workflow:rules:` to define variables for specific pipeline conditions.
+
+For example:
+
+```yaml
+variables:
+ DEPLOY_VARIABLE: "default-deploy"
+
+workflow:
+ rules:
+ - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
+ variables:
+ DEPLOY_VARIABLE: "deploy-production" # Override globally-defined DEPLOY_VARIABLE
+ - if: $CI_COMMIT_REF_NAME =~ /feature/
+ variables:
+ IS_A_FEATURE: "true" # Define a new variable.
+ - when: always # Run the pipeline in other cases
+
+job1:
+ variables:
+ DEPLOY_VARIABLE: "job1-default-deploy"
+ rules:
+ - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
+ variables: # Override DEPLOY_VARIABLE defined
+ DEPLOY_VARIABLE: "job1-deploy-production" # at the job level.
+ - when: on_success # Run the job in other cases
+ script:
+ - echo "Run script with $DEPLOY_VARIABLE as an argument"
+ - echo "Run another script if $IS_A_FEATURE exists"
+
+job2:
+ script:
+ - echo "Run script with $DEPLOY_VARIABLE as an argument"
+ - echo "Run another script if $IS_A_FEATURE exists"
+```
+
+When the branch is the default branch:
+
+- job1's `DEPLOY_VARIABLE` is `job1-deploy-production`.
+- job2's `DEPLOY_VARIABLE` is `deploy-production`.
+
+When the branch is `feature`:
+
+- job1's `DEPLOY_VARIABLE` is `job1-default-deploy`, and `IS_A_FEATURE` is `true`.
+- job2's `DEPLOY_VARIABLE` is `default-deploy`, and `IS_A_FEATURE` is `true`.
+
+When the branch is something else:
+
+- job1's `DEPLOY_VARIABLE` is `job1-default-deploy`.
+- job2's `DEPLOY_VARIABLE` is `default-deploy`.
+
+#### `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
+[pipelines for merged results](../pipelines/pipelines_for_merged_results.md)
+or [merge trains](../pipelines/merge_trains.md).
+This template intentionally avoids those features.
+
+To [include](#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 [pipelines for merge requests features](../pipelines/merge_request_pipelines.md).
+
+To [include](#include) it:
+
+```yaml
+include:
+ - template: 'Workflows/MergeRequest-Pipelines.gitlab-ci.yml'
+```
+
+#### Switch between branch pipelines and merge request pipelines
+
+> [Introduced in](https://gitlab.com/gitlab-org/gitlab/-/issues/201845) 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 the pipeline is triggered by:
+
+- A merge request, run a merge request pipeline. For example, a merge request pipeline
+ can be triggered by a push to a branch with an associated open merge request.
+- A change to a branch, but a merge request is open for that branch, do not run a branch pipeline.
+- A change to a branch, but without any open merge requests, run a 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.
+
+### `include`
+
+> [Moved](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/42861) to GitLab Free in 11.4.
+
+Use `include` to include external YAML files in your CI/CD configuration.
+You can break down one long `gitlab-ci.yml` file into multiple files to increase readability,
+or reduce duplication of the same configuration in multiple places.
+
+You can also store template files in a central repository and `include` them in projects.
+
+`include` requires the external YAML file to have the extensions `.yml` or `.yaml`,
+otherwise the external file is not included.
+
+You can't use [YAML anchors](#anchors) across different YAML files sourced by `include`.
+You can only refer to anchors in the same file. To reuse configuration from different
+YAML files, use [`!reference` tags](#reference-tags) or the [`extends` keyword](#extends).
+
+`include` supports the following inclusion methods:
+
+| Keyword | Method |
+|:--------------------------------|:------------------------------------------------------------------|
+| [`local`](#includelocal) | Include a file from the local project repository. |
+| [`file`](#includefile) | Include a file from a different project repository. |
+| [`remote`](#includeremote) | Include a file from a remote URL. Must be publicly accessible. |
+| [`template`](#includetemplate) | Include templates that are provided by GitLab. |
+
+When the pipeline starts, the `.gitlab-ci.yml` file configuration included by all methods is evaluated.
+The configuration is a snapshot in time and persists in the database. GitLab does not reflect any changes to
+the referenced `.gitlab-ci.yml` file configuration until the next pipeline starts.
+
+The `include` files are:
+
+- Deep merged with those in the `.gitlab-ci.yml` file.
+- Always evaluated first and merged with the content of the `.gitlab-ci.yml` file,
+ regardless of the position of the `include` keyword.
+
+NOTE:
+Use merging to customize and override included CI/CD configurations with local
+configurations. Local configurations in the `.gitlab-ci.yml` file override included configurations.
+
+#### Variables with `include` **(FREE SELF)**
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/284883) in GitLab 13.8.
+> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/294294) in GitLab 13.9.
+
+You can [use some predefined variables in `include` sections](../variables/where_variables_can_be_used.md#gitlab-ciyml-file)
+in your `.gitlab-ci.yml` file:
+
+```yaml
+include:
+ project: '$CI_PROJECT_PATH'
+ file: '.compliance-gitlab-ci.yml'
+```
+
+For an example of how you can include these predefined variables, and the variables' impact on CI/CD jobs,
+see this [CI/CD variable demo](https://youtu.be/4XR8gw3Pkos).
+
+#### `include:local`
+
+Use `include:local` to include a file that is in the same repository as the `.gitlab-ci.yml` file.
+Use a full path relative to the root directory (`/`).
+
+If you use `include:local`, make sure that both the `.gitlab-ci.yml` file and the local file
+are on the same branch.
+
+You can't include local files through Git submodules paths.
+
+All [nested includes](#nested-includes) are executed in the scope of the same project,
+so it's possible to use local, project, remote, or template includes.
+
+Example:
+
+```yaml
+include:
+ - local: '/templates/.gitlab-ci-template.yml'
+```
+
+You can also use shorter syntax to define the path:
+
+```yaml
+include: '.gitlab-ci-production.yml'
+```
+
+Use local includes instead of symbolic links.
+
+##### `include:local` with wildcard file paths
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/25921) in GitLab 13.11.
+> - [Deployed behind a feature flag](../../user/feature_flags.md), disabled by default.
+> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/327315) in GitLab 13.12.
+> - Enabled on GitLab.com.
+> - Recommended for production use.
+> - For GitLab self-managed instances, GitLab administrators can opt to disable it. **(CORE ONLY)**
+
+There can be
+[risks when disabling released features](../../user/feature_flags.md#risks-when-disabling-released-features).
+Refer to this feature's version history for more details.
+
+You can use wildcard paths (`*` and `**`) with `include:local`.
+
+Example:
+
+```yaml
+include: 'configs/*.yml'
+```
+
+When the pipeline runs, GitLab:
+
+- Adds all `.yml` files in the `configs` directory into the pipeline configuration.
+- Does not add `.yml` files in subfolders of the `configs` directory. To allow this,
+ add the following configuration:
+
+ ```yaml
+ # This matches all `.yml` files in `configs` and any subfolder in it.
+ include: 'configs/**.yml'
+
+ # This matches all `.yml` files only in subfolders of `configs`.
+ include: 'configs/**/*.yml'
+ ```
+
+The wildcard file paths feature is under development but ready for production use.
+It is deployed behind a feature flag that is **enabled by default**.
+[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md)
+can opt to disable it.
+
+To enable it:
+
+```ruby
+Feature.enable(:ci_wildcard_file_paths)
+```
+
+To disable it:
+
+```ruby
+Feature.disable(:ci_wildcard_file_paths)
+```
+
+#### `include:file`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53903) in GitLab 11.7.
+
+To include files from another private project on the same GitLab instance,
+use `include:file`. You can use `include:file` in combination with `include:project` only.
+Use a full path, relative to the root directory (`/`).
+
+For example:
+
+```yaml
+include:
+ - project: 'my-group/my-project'
+ file: '/templates/.gitlab-ci-template.yml'
+```
+
+You can also specify a `ref`. If you do not specify a value, the ref defaults to the `HEAD` of the project:
+
+```yaml
+include:
+ - project: 'my-group/my-project'
+ ref: main
+ file: '/templates/.gitlab-ci-template.yml'
+
+ - project: 'my-group/my-project'
+ ref: v1.0.0
+ file: '/templates/.gitlab-ci-template.yml'
+
+ - project: 'my-group/my-project'
+ ref: 787123b47f14b552955ca2786bc9542ae66fee5b # Git SHA
+ file: '/templates/.gitlab-ci-template.yml'
+```
+
+All [nested includes](#nested-includes) are executed in the scope of the target project.
+You can use local (relative to target project), project, remote, or template includes.
+
+##### Multiple files from a project
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/26793) in GitLab 13.6.
+> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/271560) in GitLab 13.8.
+
+You can include multiple files from the same project:
+
+```yaml
+include:
+ - project: 'my-group/my-project'
+ ref: main
+ file:
+ - '/templates/.builds.yml'
+ - '/templates/.tests.yml'
+```
+
+#### `include:remote`
+
+Use `include:remote` with a full URL to include a file from a different location.
+The remote file must be publicly accessible by an HTTP/HTTPS `GET` request, because
+authentication in the remote URL is not supported. For example:
+
+```yaml
+include:
+ - remote: 'https://gitlab.com/example-project/-/raw/main/.gitlab-ci.yml'
+```
+
+All [nested includes](#nested-includes) execute without context as a public user,
+so you can only `include` public projects or templates.
+
+#### `include:template`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53445) in GitLab 11.7.
+
+Use `include:template` to include `.gitlab-ci.yml` templates that are
+[shipped with GitLab](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates).
+
+For example:
+
+```yaml
+# File sourced from the GitLab template collection
+include:
+ - template: Auto-DevOps.gitlab-ci.yml
+```
+
+Multiple `include:template` files:
+
+```yaml
+include:
+ - template: Android-Fastlane.gitlab-ci.yml
+ - template: Auto-DevOps.gitlab-ci.yml
+```
+
+All [nested includes](#nested-includes) are executed only with the permission of the user,
+so it's possible to use project, remote or template includes.
+
+#### Nested includes
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/56836) in GitLab 11.9.
+
+Use nested includes to compose a set of includes.
+
+You can have up to 100 includes, but you can't have duplicate includes.
+
+In [GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/issues/28212) and later, the time limit
+to resolve all files is 30 seconds.
+
+#### Additional `includes` examples
+
+View [additional `includes` examples](includes.md).
+
+## Keyword details
+
+The following topics explain how to use keywords to configure CI/CD pipelines.
+
+### `image`
+
+Use `image` to specify [a Docker image](../docker/using_docker_images.md#what-is-an-image) to use for the job.
+
+For:
+
+- Usage examples, see [Define `image` in the `.gitlab-ci.yml` file](../docker/using_docker_images.md#define-image-in-the-gitlab-ciyml-file).
+- Detailed usage information, refer to [Docker integration](../docker/index.md) documentation.
+
+#### `image:name`
+
+An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
+
+For more information, see [Available settings for `image`](../docker/using_docker_images.md#available-settings-for-image).
+
+#### `image:entrypoint`
+
+An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
+
+For more information, see [Available settings for `image`](../docker/using_docker_images.md#available-settings-for-image).
+
+#### `services`
+
+Use `services` to specify a [service Docker image](../services/index.md), linked to a base image specified in [`image`](#image).
+
+For:
+
+- Usage examples, see [Define `services` in the `.gitlab-ci.yml` file](../services/index.md#define-services-in-the-gitlab-ciyml-file).
+- Detailed usage information, refer to [Docker integration](../docker/index.md) documentation.
+- Example services, see [GitLab CI/CD Services](../services/index.md).
+
+##### `services:name`
+
+An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
+
+For more information, see [Available settings for `services`](../services/index.md#available-settings-for-services).
+
+##### `services:alias`
+
+An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
+
+For more information, see [Available settings for `services`](../services/index.md#available-settings-for-services).
+
+##### `services:entrypoint`
+
+An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
+
+For more information, see [Available settings for `services`](../services/index.md#available-settings-for-services).
+
+##### `services:command`
+
+An [extended Docker configuration option](../docker/using_docker_images.md#extended-docker-configuration-options).
+
+For more information, see [Available settings for `services`](../services/index.md#available-settings-for-services).
+
+### `script`
+
+Use `script` to specify a shell script for the runner to execute.
+
+All jobs except [trigger jobs](#trigger) require a `script` keyword.
+
+For example:
+
+```yaml
+job:
+ script: "bundle exec rspec"
+```
+
+You can use [YAML anchors with `script`](#yaml-anchors-for-scripts).
+
+The `script` keyword can also contain several commands in an array:
+
+```yaml
+job:
+ script:
+ - uname -a
+ - bundle exec rspec
+```
+
+Sometimes, `script` commands must be wrapped in single or double quotes.
+For example, commands that contain a colon (`:`) must be wrapped in single quotes (`'`).
+The YAML parser needs to interpret the text as a string rather than
+a "key: value" pair.
+
+For example, this script uses a colon:
+
+```yaml
+job:
+ script:
+ - curl --request POST --header 'Content-Type: application/json' "https://gitlab/api/v4/projects"
+```
+
+To be considered valid YAML, you must wrap the entire command in single quotes. If
+the command already uses single quotes, you should change them to double quotes (`"`)
+if possible:
+
+```yaml
+job:
+ script:
+ - 'curl --request POST --header "Content-Type: application/json" "https://gitlab/api/v4/projects"'
+```
+
+You can verify the syntax is valid with the [CI Lint](../lint.md) tool.
+
+Be careful when using these characters as well:
+
+- `{`, `}`, `[`, `]`, `,`, `&`, `*`, `#`, `?`, `|`, `-`, `<`, `>`, `=`, `!`, `%`, `@`, `` ` ``.
+
+If any of the script commands return an exit code other than zero, the job
+fails and further commands are not executed. Store the exit code in a variable to
+avoid this behavior:
+
+```yaml
+job:
+ script:
+ - false || exit_code=$?
+ - if [ $exit_code -ne 0 ]; then echo "Previous command failed"; fi;
+```
+
+#### `before_script`
+
+Use `before_script` to define an array of commands that should run before each job,
+but after [artifacts](#artifacts) are restored.
+
+Scripts you specify in `before_script` are concatenated with any scripts you specify
+in the main [`script`](#script). The combine scripts execute together in a single shell.
+
+You can overwrite a globally-defined `before_script` if you define it in a job:
+
+```yaml
+default:
+ before_script:
+ - echo "Execute this script in all jobs that don't already have a before_script section."
+
+job1:
+ script:
+ - echo "This script executes after the global before_script."
+
+job:
+ before_script:
+ - echo "Execute this script instead of the global before_script."
+ script:
+ - echo "This script executes after the job's `before_script`"
+```
+
+You can use [YAML anchors with `before_script`](#yaml-anchors-for-scripts).
+
+#### `after_script`
+
+Use `after_script` to define an array of commands that run after each job,
+including failed jobs.
+
+If a job times out or is cancelled, the `after_script` commands do not execute.
+An [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/15603) exists to support
+executing `after_script` commands for timed-out or cancelled jobs.
+
+Scripts you specify in `after_script` execute in a new shell, separate from any
+`before_script` or `script` scripts. As a result, they:
+
+- Have a current working directory set back to the default.
+- Have no access to changes done by scripts defined in `before_script` or `script`, including:
+ - Command aliases and variables exported in `script` scripts.
+ - Changes outside of the working tree (depending on the runner executor), like
+ software installed by a `before_script` or `script` script.
+- Have a separate timeout, which is hard coded to 5 minutes. See the
+ [related issue](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2716) for details.
+- Don't affect the job's exit code. If the `script` section succeeds and the
+ `after_script` times out or fails, the job exits with code `0` (`Job Succeeded`).
+
+```yaml
+default:
+ after_script:
+ - echo "Execute this script in all jobs that don't already have an after_script section."
+
+job1:
+ script:
+ - echo "This script executes first. When it completes, the global after_script executes."
+
+job:
+ script:
+ - echo "This script executes first. When it completes, the job's `after_script` executes."
+ after_script:
+ - echo "Execute this script instead of the global after_script."
+```
+
+You can use [YAML anchors with `after_script`](#yaml-anchors-for-scripts).
+
+#### Script syntax
+
+You can use syntax in [`script`](#script) sections to:
+
+- [Split long commands](script.md#split-long-commands) into multiline commands.
+- [Use color codes](script.md#add-color-codes-to-script-output) to make job logs easier to review.
+- [Create custom collapsible sections](../jobs/index.md#custom-collapsible-sections)
+ to simplify job log output.
+
+### `stage`
+
+Use `stage` to define which stage a job runs in. Jobs in the same
+`stage` can execute in parallel (subject to [certain conditions](#use-your-own-runners)).
+
+Jobs without a `stage` entry use the `test` stage by default. If you do not define
+[`stages`](#stages) in the pipeline, you can use the 5 default stages, which execute in
+this order:
+
+- [`.pre`](#pre-and-post)
+- `build`
+- `test`
+- `deploy`
+- [`.post`](#pre-and-post)
+For example:
+
+```yaml
+stages:
+ - build
+ - test
+ - deploy
+
+job 0:
+ stage: .pre
+ script: make something useful before build stage
+
+job 1:
+ stage: build
+ script: make build dependencies
+
+job 2:
+ stage: build
+ script: make build artifacts
+
+job 3:
+ stage: test
+ script: make test
+
+job 4:
+ stage: deploy
+ script: make deploy
+
+job 5:
+ stage: .post
+ script: make something useful at the end of pipeline
+```
+
+#### Use your own runners
+
+When you use your own runners, each runner runs only one job at a time by default.
+Jobs can run in parallel if they run on different runners.
+
+If you have only one runner, jobs can run in parallel if the runner's
+[`concurrent` setting](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-global-section)
+is greater than `1`.
+
+#### `.pre` and `.post`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/31441) in GitLab 12.4.
+
+Use `pre` and `post` for jobs that need to run first or last in a pipeline.
+
+- `.pre` is guaranteed to always be the first stage in a pipeline.
+- `.post` is guaranteed to always be the last stage in a pipeline.
+
+User-defined stages are executed after `.pre` and before `.post`.
+
+You must have a job in at least one stage other than `.pre` or `.post`.
+
+You can't change the order of `.pre` and `.post`, even if you define them out of order in the `.gitlab-ci.yml` file.
+For example, the following configurations are equivalent:
+
+```yaml
+stages:
+ - .pre
+ - a
+ - b
+ - .post
+```
+
+```yaml
+stages:
+ - a
+ - .pre
+ - b
+ - .post
+```
+
+```yaml
+stages:
+ - a
+ - b
+```
+
+### `extends`
+
+> Introduced in GitLab 11.3.
+
+Use `extends` to reuse configuration sections. It's an alternative to [YAML anchors](#anchors)
+and is a little more flexible and readable. You can use `extends` to reuse configuration
+from [included configuration files](#use-extends-and-include-together).
+
+In the following example, the `rspec` job uses the configuration from the `.tests` template job.
+GitLab:
+
+- Performs a reverse deep merge based on the keys.
+- Merges the `.tests` content with the `rspec` job.
+- Doesn't merge the values of the keys.
+
+```yaml
+.tests:
+ script: rake test
+ stage: test
+ only:
+ refs:
+ - branches
+
+rspec:
+ extends: .tests
+ script: rake rspec
+ only:
+ variables:
+ - $RSPEC
+```
+
+The result is this `rspec` job:
+
+```yaml
+rspec:
+ script: rake rspec
+ stage: test
+ only:
+ refs:
+ - branches
+ variables:
+ - $RSPEC
+```
+
+`.tests` in this example is a [hidden job](#hide-jobs), but it's
+possible to extend configuration from regular jobs as well.
+
+`extends` supports multi-level inheritance. You should avoid using more than three levels,
+but you can use as many as eleven. The following example has two levels of inheritance:
+
+```yaml
+.tests:
+ rules:
+ - if: $CI_PIPELINE_SOURCE == "push"
+
+.rspec:
+ extends: .tests
+ script: rake rspec
+
+rspec 1:
+ variables:
+ RSPEC_SUITE: '1'
+ extends: .rspec
+
+rspec 2:
+ variables:
+ RSPEC_SUITE: '2'
+ extends: .rspec
+
+spinach:
+ extends: .tests
+ script: rake spinach
+```
+
+In GitLab 12.0 and later, it's also possible to use multiple parents for
+`extends`.
+
+#### Merge details
+
+You can use `extends` to merge hashes but not arrays.
+The algorithm used for merge is "closest scope wins," so
+keys from the last member always override anything defined on other
+levels. For example:
+
+```yaml
+.only-important:
+ variables:
+ URL: "http://my-url.internal"
+ IMPORTANT_VAR: "the details"
+ rules:
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
+ - if: $CI_COMMIT_BRANCH == "stable"
+ tags:
+ - production
+ script:
+ - echo "Hello world!"
+
+.in-docker:
+ variables:
+ URL: "http://docker-url.internal"
+ tags:
+ - docker
+ image: alpine
+
+rspec:
+ variables:
+ GITLAB: "is-awesome"
+ extends:
+ - .only-important
+ - .in-docker
+ script:
+ - rake rspec
+```
+
+The result is this `rspec` job:
+
+```yaml
+rspec:
+ variables:
+ URL: "http://docker-url.internal"
+ IMPORTANT_VAR: "the details"
+ GITLAB: "is-awesome"
+ rules:
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
+ - if: $CI_COMMIT_BRANCH == "stable"
+ tags:
+ - docker
+ image: alpine
+ script:
+ - rake rspec
+```
+
+In this example:
+
+- The `variables` sections merge, but `URL: "http://docker-url.internal"` overwrites `URL: "http://my-url.internal"`.
+- `tags: ['docker']` overwrites `tags: ['production']`.
+- `script` does not merge, but `script: ['rake rspec']` overwrites
+ `script: ['echo "Hello world!"']`. You can use [YAML anchors](#anchors) to merge arrays.
+
+#### Use `extends` and `include` together
+
+To reuse configuration from different configuration files,
+combine `extends` and [`include`](#include).
+
+In the following example, a `script` is defined in the `included.yml` file.
+Then, in the `.gitlab-ci.yml` file, `extends` refers
+to the contents of the `script`:
+
+- `included.yml`:
+
+ ```yaml
+ .template:
+ script:
+ - echo Hello!
+ ```
+
+- `.gitlab-ci.yml`:
+
+ ```yaml
+ include: included.yml
+
+ useTemplate:
+ image: alpine
+ extends: .template
+ ```
+
+### `rules`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27863) in GitLab 12.3.
+
+Use `rules` to include or exclude jobs in pipelines.
+
+Rules are evaluated *in order* until the first match. When a match is found, the job
+is either included or excluded from the pipeline, depending on the configuration.
+
+`rules` replaces [`only/except`](#only--except) and they can't be used together
+in the same job. If you configure one job to use both keywords, the GitLab returns
+a `key may not be used with rules` error.
+
+`rules` accepts an array of rules defined with:
+
+- `if`
+- `changes`
+- `exists`
+- `allow_failure`
+- `variables`
+- `when`
+
+You can combine multiple keywords together for [complex rules](../jobs/job_control.md#complex-rules).
+
+The job is added to the pipeline:
+
+- If an `if`, `changes`, or `exists` rule matches and also has `when: on_success` (default),
+ `when: delayed`, or `when: always`.
+- If a rule is reached that is only `when: on_success`, `when: delayed`, or `when: always`.
+
+The job is not added to the pipeline:
+
+- If no rules match.
+- If a rule matches and has `when: never`.
+
+#### `rules:if`
+
+Use `rules:if` clauses to specify when to add a job to a pipeline:
+
+- If an `if` statement is true, add the job to the pipeline.
+- If an `if` statement is true, but it's combined with `when: never`, do not add the job to the pipeline.
+- If no `if` statements are true, do not add the job to the pipeline.
+
+`if:` clauses are evaluated based on the values of [predefined CI/CD variables](../variables/predefined_variables.md)
+or [custom CI/CD variables](../variables/index.md#custom-cicd-variables).
+
+**Keyword type**: Job-specific and pipeline-specific. You can use it as part of a job
+to configure the job behavior, or with [`workflow`](#workflow) to configure the pipeline behavior.
+
+**Possible inputs**: A [CI/CD variable expression](../jobs/job_control.md#cicd-variable-expressions).
+
+**Example of `rules:if`**:
+
+```yaml
+job:
+ script: echo "Hello, Rules!"
+ rules:
+ - if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature/ && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != $CI_DEFAULT_BRANCH'
+ when: never
+ - if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feature/'
+ when: manual
+ allow_failure: true
+ - if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME'
+```
+
+**Additional details**:
+
+- If a rule matches and has no `when` defined, the rule uses the `when`
+ defined for the job, which defaults to `on_success` if not defined.
+- You can define `when` once per rule, or once at the job-level, which applies to
+ all rules. You can't mix `when` at the job-level with `when` in rules.
+- Unlike variables in [`script`](../variables/index.md#use-cicd-variables-in-job-scripts)
+ sections, variables in rules expressions are always formatted as `$VARIABLE`.
+
+**Related topics**:
+
+- [Common `if` expressions for `rules`](../jobs/job_control.md#common-if-clauses-for-rules).
+- [Avoid duplicate pipelines](../jobs/job_control.md#avoid-duplicate-pipelines).
+
+#### `rules:changes`
+
+Use `rules:changes` to specify when to add a job to a pipeline by checking for changes
+to specific files.
+
+WARNING:
+You should use `rules: changes` only with **branch pipelines** or **merge request pipelines**.
+You can use `rules: changes` with other pipeline types, but `rules: changes` always
+evaluates to true when there is no Git `push` event. Tag pipelines, scheduled pipelines,
+and so on do **not** have a Git `push` event associated with them. A `rules: changes` job
+is **always** added to those pipelines if there is no `if:` that limits the job to
+branch or merge request pipelines.
+
+**Keyword type**: Job keyword. You can use it only as part of a job.
+
+**Possible inputs**: An array of file paths. In GitLab 13.6 and later,
+[file paths can include variables](../jobs/job_control.md#variables-in-ruleschanges).
+
+**Example of `rules:changes`**:
+
+```yaml
+docker build:
+ script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
+ rules:
+ - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
+ changes:
+ - Dockerfile
+ when: manual
+ allow_failure: true
+```
+
+- If the pipeline is a merge request pipeline, check `Dockerfile` for changes.
+- If `Dockerfile` has changed, add the job to the pipeline as a manual job, and the pipeline
+ continues running even if the job is not triggered (`allow_failure: true`).
+- If `Dockerfile` has not changed, do not add job to any pipeline (same as `when: never`).
+
+**Additional details**:
+
+- `rules: changes` works the same way as [`only: changes` and `except: changes`](#onlychanges--exceptchanges).
+- You can use `when: never` to implement a rule similar to [`except:changes`](#onlychanges--exceptchanges).
+
+#### `rules:exists`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/24021) in GitLab 12.4.
+
+Use `exists` to run a job when certain files exist in the repository.
+
+**Keyword type**: Job keyword. You can use it only as part of a job.
+
+**Possible inputs**: An array of file paths. Paths are relative to the project directory (`$CI_PROJECT_DIR`)
+and can't directly link outside it. File paths can use glob patterns.
+
+**Example of `rules:exists`**:
+
+```yaml
+job:
+ script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
+ rules:
+ - exists:
+ - Dockerfile
+```
+
+`job` runs if a `Dockerfile` exists anywhere in the repository.
+
+**Additional details**:
+
+- Glob patterns are interpreted with Ruby [`File.fnmatch`](https://docs.ruby-lang.org/en/2.7.0/File.html#method-c-fnmatch)
+ with the flags `File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB`.
+- For performance reasons, GitLab matches a maximum of 10,000 `exists` patterns or
+ file paths. After the 10,000th check, rules with patterned globs always match.
+ In other words, the `exists` rule always assumes a match in projects with more
+ than 10,000 files.
+
+#### `rules:allow_failure`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30235) in GitLab 12.8.
+
+Use [`allow_failure: true`](#allow_failure) in `rules:` to allow a job to fail
+without stopping the pipeline.
+
+You can also use `allow_failure: true` with a manual job. The pipeline continues
+running without waiting for the result of the manual job. `allow_failure: false`
+combined with `when: manual` in rules causes the pipeline to wait for the manual
+job to run before continuing.
+
+**Keyword type**: Job keyword. You can use it only as part of a job.
+
+**Possible inputs**: `true` or `false`. Defaults to `false` if not defined.
+
+**Example of `rules:allow_failure`**:
+
+```yaml
+job:
+ script: echo "Hello, Rules!"
+ rules:
+ - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH'
+ when: manual
+ allow_failure: true
+```
+
+If the rule matches, then the job is a manual job with `allow_failure: true`.
+
+**Additional details**:
+
+- The rule-level `rules:allow_failure` overrides the job-level [`allow_failure`](#allow_failure),
+ and only applies when the specific rule triggers the job.
+
+#### `rules:variables`
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/209864) in GitLab 13.7.
+> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/289803) in GitLab 13.10.
+
+Use [`variables`](#variables) in `rules:` to define variables for specific conditions.
+
+**Keyword type**: Job-specific. You can use it only as part of a job.
+
+**Possible inputs**: A hash of variables in the format `VARIABLE-NAME: value`.
+
+**Example of `rules:variables`**:
+
+```yaml
+job:
+ variables:
+ DEPLOY_VARIABLE: "default-deploy"
+ rules:
+ - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
+ variables: # Override DEPLOY_VARIABLE defined
+ DEPLOY_VARIABLE: "deploy-production" # at the job level.
+ - if: $CI_COMMIT_REF_NAME =~ /feature/
+ variables:
+ IS_A_FEATURE: "true" # Define a new variable.
+ script:
+ - echo "Run script with $DEPLOY_VARIABLE as an argument"
+ - echo "Run another script if $IS_A_FEATURE exists"
+```
+
+### `only` / `except`
+
+NOTE:
+`only` and `except` are not being actively developed. [`rules`](#rules) is the preferred
+keyword to control when to add jobs to pipelines.
+
+You can use `only` and `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.
+
+Four keywords can be used with `only` and `except`:
+
+- [`refs`](#onlyrefs--exceptrefs)
+- [`variables`](#onlyvariables--exceptvariables)
+- [`changes`](#onlychanges--exceptchanges)
+- [`kubernetes`](#onlykubernetes--exceptkubernetes)
+
+See [specify when jobs run with `only` and `except`](../jobs/job_control.md#specify-when-jobs-run-with-only-and-except)
+for more details and examples.
+
+#### `only:refs` / `except:refs`
+
+Use the `only:refs` and `except:refs` keywords to control when to add jobs to a
+pipeline based on branch names or pipeline types.
+
+**Keyword type**: Job keyword. You can use it only as part of a job.
+
+**Possible inputs**: An array including any number of:
+
+- Branch names, for example `main` or `my-feature-branch`.
+- [Regular expressions](../jobs/job_control.md#only--except-regex-syntax)
+ that match against branch names, for example `/^feature-.*/`.
+- The following keywords:
+
+ | **Value** | **Description** |
+ | -------------------------|-----------------|
+ | `api` | For pipelines triggered by the [pipelines API](../../api/pipelines.md#create-a-new-pipeline). |
+ | `branches` | When the Git reference for a pipeline is a branch. |
+ | `chat` | For pipelines created by using a [GitLab ChatOps](../chatops/index.md) command. |
+ | `external` | When you use CI services other than GitLab. |
+ | `external_pull_requests` | When an external pull request on GitHub is created or updated (See [Pipelines for external pull requests](../ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests)). |
+ | `merge_requests` | For pipelines created when a merge request is created or updated. Enables [merge request pipelines](../pipelines/merge_request_pipelines.md), [merged results pipelines](../pipelines/pipelines_for_merged_results.md), and [merge trains](../pipelines/merge_trains.md). |
+ | `pipelines` | For [multi-project pipelines](../pipelines/multi_project_pipelines.md) created by [using the API with `CI_JOB_TOKEN`](../pipelines/multi_project_pipelines.md#create-multi-project-pipelines-by-using-the-api), or the [`trigger`](#trigger) keyword. |
+ | `pushes` | For pipelines triggered by a `git push` event, including for branches and tags. |
+ | `schedules` | For [scheduled pipelines](../pipelines/schedules.md). |
+ | `tags` | When the Git reference for a pipeline is a tag. |
+ | `triggers` | For pipelines created by using a [trigger token](../triggers/index.md#trigger-token). |
+ | `web` | For pipelines created by using **Run pipeline** button in the GitLab UI, from the project's **CI/CD > Pipelines** section. |
+
+**Example of `only:refs` and `except:refs`**:
+
+```yaml
+job1:
+ script: echo
+ only:
+ - main
+ - /^issue-.*$/
+ - merge_requests
+
+job2:
+ script: echo
+ except:
+ - main
+ - /^stable-branch.*$/
+ - schedules
+```
+
+**Additional details:**
+
+- Scheduled pipelines run on specific branches, so jobs configured with `only: branches`
+ run on scheduled pipelines too. Add `except: schedules` to prevent jobs with `only: branches`
+ from running on scheduled pipelines.
+- `only` or `except` used without any other keywords are equivalent to `only: refs`
+ or `except: refs`. For example, the following two jobs configurations have the same
+ behavior:
+
+ ```yaml
+ job1:
+ script: echo
+ only:
+ - branches
+
+ job2:
+ script: echo
+ only:
+ refs:
+ - branches
+ ```
+
+- If a job does not use `only`, `except`, or [`rules`](#rules), then `only` is set to `branches`
+ and `tags` by default.
+
+ For example, `job1` and `job2` are equivalent:
+
+ ```yaml
+ job1:
+ script: echo 'test'
+
+ job2:
+ script: echo 'test'
+ only:
+ - branches
+ - tags
+ ```
+
+#### `only:variables` / `except:variables`
+
+Use the `only:variables` or `except:variables` keywords to control when to add jobs
+to a pipeline, based on the status of [CI/CD variables](../variables/index.md).
+
+**Keyword type**: Job keyword. You can use it only as part of a job.
+
+**Possible inputs**: An array of [CI/CD variable expressions](../jobs/job_control.md#cicd-variable-expressions).
+
+**Example of `only:variables`**:
+
+```yaml
+deploy:
+ script: cap staging deploy
+ only:
+ variables:
+ - $RELEASE == "staging"
+ - $STAGING
+```
+
+**Related topics**:
+
+- [`only:variables` and `except:variables` examples](../jobs/job_control.md#only-variables--except-variables-examples).
+
+#### `only:changes` / `except:changes`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/19232) in GitLab 11.4.
+
+Use the `changes` keyword with `only` to run a job, or with `except` to skip a job,
+when a Git push event modifies a file.
+
+Use `changes` in pipelines with the following refs:
+
+- `branches`
+- `external_pull_requests`
+- `merge_requests` (see additional details about [using `only:changes` with pipelines for merge requests](../jobs/job_control.md#use-onlychanges-with-pipelines-for-merge-requests))
+
+**Keyword type**: Job keyword. You can use it only as part of a job.
+
+**Possible inputs**: An array including any number of:
+
+- Paths to files.
+- Wildcard paths for single directories, for example `path/to/directory/*`, or a directory
+ and all its subdirectories, for example `path/to/directory/**/*`.
+- Wildcard ([glob](https://en.wikipedia.org/wiki/Glob_(programming))) paths for all
+ files with the same extension or multiple extensions, for example `*.md` or `path/to/directory/*.{rb,py,sh}`.
+- Wildcard paths to files in the root directory, or all directories, wrapped in double quotes.
+ For example `"*.json"` or `"**/*.json"`.
+
+**Example of `only:changes`**:
+
+```yaml
+docker build:
+ script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
+ only:
+ refs:
+ - branches
+ changes:
+ - Dockerfile
+ - docker/scripts/*
+ - dockerfiles/**/*
+ - more_scripts/*.{rb,py,sh}
+```
+
+**Additional details**:
+
+- If you use refs other than `branches`, `external_pull_requests`, or `merge_requests`,
+ `changes` can't determine if a given file is new or old and always returns `true`.
+- If you use `only: changes` with other refs, jobs ignore the changes and always run.
+- If you use `except: changes` with other refs, jobs ignore the changes and never run.
+
+**Related topics**:
+
+- [`only: changes` and `except: changes` examples](../jobs/job_control.md#onlychanges--exceptchanges-examples).
+- If you use `changes` with [only allow merge requests to be merged if the pipeline succeeds](../../user/project/merge_requests/merge_when_pipeline_succeeds.md#only-allow-merge-requests-to-be-merged-if-the-pipeline-succeeds),
+ you should [also use `only:merge_requests`](../jobs/job_control.md#use-onlychanges-with-pipelines-for-merge-requests).
+- Use `changes` with [new branches or tags *without* pipelines for merge requests](../jobs/job_control.md#use-onlychanges-without-pipelines-for-merge-requests).
+- Use `changes` with [scheduled pipelines](../jobs/job_control.md#use-onlychanges-with-scheduled-pipelines).
+
+#### `only:kubernetes` / `except:kubernetes`
+
+Use `only:kubernetes` or `except:kubernetes` to control if jobs are added to the pipeline
+when the Kubernetes service is active in the project.
+
+**Keyword type**: Job-specific. You can use it only as part of a job.
+
+**Possible inputs**: The `kubernetes` strategy accepts only the `active` keyword.
+
+**Example of `only:kubernetes`**:
+
+```yaml
+deploy:
+ only:
+ kubernetes: active
+```
+
+In this example, the `deploy` job runs only when the Kubernetes service is active
+in the project.
+
+### `needs`
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/47063) in GitLab 12.2.
+> - In GitLab 12.3, maximum number of jobs in `needs` array raised from five to 50.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30631) in GitLab 12.8, `needs: []` lets jobs start immediately.
+
+Use `needs:` to execute jobs out-of-order. Relationships between jobs
+that use `needs` can be visualized as a [directed acyclic graph](../directed_acyclic_graph/index.md).
+
+You can ignore stage ordering and run some jobs without waiting for others to complete.
+Jobs in multiple stages can run concurrently.
+
+The following example creates four paths of execution:
+
+- Linter: the `lint` job runs immediately without waiting for the `build` stage
+ to complete because it has no needs (`needs: []`).
+- Linux path: the `linux:rspec` and `linux:rubocop` jobs runs as soon as the `linux:build`
+ job finishes without waiting for `mac:build` to finish.
+- macOS path: the `mac:rspec` and `mac:rubocop` jobs runs as soon as the `mac:build`
+ job finishes, without waiting for `linux:build` to finish.
+- The `production` job runs as soon as all previous jobs finish; in this case:
+ `linux:build`, `linux:rspec`, `linux:rubocop`, `mac:build`, `mac:rspec`, `mac:rubocop`.
+
+```yaml
+linux:build:
+ stage: build
+ script: echo "Building linux..."
+
+mac:build:
+ stage: build
+ script: echo "Building mac..."
+
+lint:
+ stage: test
+ needs: []
+ script: echo "Linting..."
+
+linux:rspec:
+ stage: test
+ needs: ["linux:build"]
+ script: echo "Running rspec on linux..."
+
+linux:rubocop:
+ stage: test
+ needs: ["linux:build"]
+ script: echo "Running rubocop on linux..."
+
+mac:rspec:
+ stage: test
+ needs: ["mac:build"]
+ script: echo "Running rspec on mac..."
+
+mac:rubocop:
+ stage: test
+ needs: ["mac:build"]
+ script: echo "Running rubocop on mac..."
+
+production:
+ stage: deploy
+ script: echo "Running production..."
+```
+
+#### Requirements and limitations
+
+- In [GitLab 14.1 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/30632)
+ you can refer to jobs in the same stage as the job you are configuring. This feature
+ is [Deployed behind a feature flag](../../user/feature_flags.md), disabled by default.
+- Disabled on GitLab.com.
+- Not recommended for production use.
+- For GitLab self-managed instances, GitLab adminsitrators
+ can choose to [disable it](#enable-or-disable-needs-for-jobs-in-the-same-stage)
+- In GitLab 14.0 and older, you can only refer to jobs in earlier stages.
+- In GitLab 13.9 and older, if `needs:` refers to a job that might not be added to
+ a pipeline because of `only`, `except`, or `rules`, the pipeline might fail to create.
+- The maximum number of jobs that a single job can need in the `needs:` array is limited:
+ - For GitLab.com, the limit is 50. For more information, see our
+ [infrastructure issue](https://gitlab.com/gitlab-com/gl-infra/infrastructure/-/issues/7541).
+ - For self-managed instances, the limit is: 50. This limit [can be changed](#changing-the-needs-job-limit).
+- If `needs:` refers to a job that uses the [`parallel`](#parallel) keyword,
+ it depends on all jobs created in parallel, not just one job. It also downloads
+ artifacts from all the parallel jobs by default. If the artifacts have the same
+ name, they overwrite each other and only the last one downloaded is saved.
+- `needs:` is similar to `dependencies:` in that it must use jobs from prior stages,
+ meaning it's impossible to create circular dependencies. Depending on jobs in the
+ current stage is not possible either, but support [is planned](https://gitlab.com/gitlab-org/gitlab/-/issues/30632).
+- Stages must be explicitly defined for all jobs
+ that have the keyword `needs:` or are referred to by one.
+
+##### Enable or disable `needs` for jobs in the same stage **(FREE SELF)**
+
+`needs` for jobs in the same stage is under development but ready for production use.
+It is deployed behind a feature flag that is **enabled by default**.
+[GitLab administrators with access to the GitLab Rails
+console](../../administration/feature_flags.md)
+can opt to disable it.
+
+To enable it:
+
+`Feature.enable(:ci_same_stage_job_needs)`
+
+To disable it:
+
+`Feature.disable(:ci_same_stage_job_needs)`
+
+##### Changing the `needs:` job limit **(FREE SELF)**
+
+The maximum number of jobs that can be defined in `needs:` defaults to 50.
+
+A GitLab administrator with [access to the GitLab Rails console](../../administration/feature_flags.md)
+can choose a custom limit. For example, to set the limit to 100:
+
+```ruby
+Plan.default.actual_limits.update!(ci_needs_size_limit: 100)
+```
+
+To disable directed acyclic graphs (DAG), set the limit to `0`.
+
+#### Artifact downloads with `needs`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14311) in GitLab v12.6.
+
+When a job uses `needs`, it no longer downloads all artifacts from previous stages
+by default, because jobs with `needs` can start before earlier stages complete. With
+`needs` you can only download artifacts from the jobs listed in the `needs:` configuration.
+
+Use `artifacts: true` (default) or `artifacts: false` to control when artifacts are
+downloaded in jobs that use `needs`.
+
+In the following example, the `rspec` job downloads the `build_job` artifacts, but the
+`rubocop` job does not:
+
+```yaml
+build_job:
+ stage: build
+ artifacts:
+ paths:
+ - binaries/
+
+rspec:
+ stage: test
+ needs:
+ - job: build_job
+ artifacts: true
+
+rubocop:
+ stage: test
+ needs:
+ - job: build_job
+ artifacts: false
+```
+
+In the following example, the `rspec` job downloads the artifacts from all three `build_jobs`.
+`artifacts` is:
+
+- Set to true for `build_job_1`.
+- Defaults to true for both `build_job_2` and `build_job_3`.
+
+```yaml
+rspec:
+ needs:
+ - job: build_job_1
+ artifacts: true
+ - job: build_job_2
+ - build_job_3
+```
+
+In GitLab 12.6 and later, you can't combine the [`dependencies`](#dependencies) keyword
+with `needs`.
+
+#### Cross project artifact downloads with `needs` **(PREMIUM)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14311) in GitLab v12.7.
+
+Use `needs` to download artifacts from up to five jobs in pipelines:
+
+- [On other refs in the same project](#artifact-downloads-between-pipelines-in-the-same-project).
+- In different projects, groups and namespaces.
+
+```yaml
+build_job:
+ stage: build
+ script:
+ - ls -lhR
+ needs:
+ - project: namespace/group/project-name
+ job: build-1
+ ref: main
+ artifacts: true
+```
+
+`build_job` downloads the artifacts from the latest successful `build-1` job
+on the `main` branch in the `group/project-name` project. If the project is in the
+same group or namespace, you can omit them from the `project:` keyword. For example,
+`project: group/project-name` or `project: project-name`.
+
+The user running the pipeline must have at least `reporter` access to the group or project, or the group/project must have public visibility.
+
+##### Artifact downloads between pipelines in the same project
+
+Use `needs` to download artifacts from different pipelines in the current project.
+Set the `project` keyword as the current project's name, and specify a ref.
+
+In the following example, `build_job` downloads the artifacts for the latest successful
+`build-1` job with the `other-ref` ref:
+
+```yaml
+build_job:
+ stage: build
+ script:
+ - ls -lhR
+ needs:
+ - project: group/same-project-name
+ job: build-1
+ ref: other-ref
+ artifacts: true
+```
+
+CI/CD variable support for `project:`, `job:`, and `ref` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/202093)
+in GitLab 13.3. [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/235761) in GitLab 13.4.
+
+For example:
+
+```yaml
+build_job:
+ stage: build
+ script:
+ - ls -lhR
+ needs:
+ - project: $CI_PROJECT_PATH
+ job: $DEPENDENCY_JOB_NAME
+ ref: $ARTIFACTS_DOWNLOAD_REF
+ artifacts: true
+```
+
+You can't download artifacts from jobs that run in [`parallel:`](#parallel).
+
+To download artifacts between [parent-child pipelines](../pipelines/parent_child_pipelines.md),
+use [`needs:pipeline`](#artifact-downloads-to-child-pipelines).
+
+You should not download artifacts from the same ref as a running pipeline. Concurrent
+pipelines running on the same ref could override the artifacts.
+
+#### Artifact downloads to child pipelines
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/255983) in GitLab v13.7.
+
+A [child pipeline](../pipelines/parent_child_pipelines.md) can download artifacts from a job in
+its parent pipeline or another child pipeline in the same parent-child pipeline hierarchy.
+
+For example, with the following parent pipeline that has a job that creates some artifacts:
+
+```yaml
+create-artifact:
+ stage: build
+ script: echo 'sample artifact' > artifact.txt
+ artifacts:
+ paths: [artifact.txt]
+
+child-pipeline:
+ stage: test
+ trigger:
+ include: child.yml
+ strategy: depend
+ variables:
+ PARENT_PIPELINE_ID: $CI_PIPELINE_ID
+```
+
+A job in the child pipeline can download artifacts from the `create-artifact` job in
+the parent pipeline:
+
+```yaml
+use-artifact:
+ script: cat artifact.txt
+ needs:
+ - pipeline: $PARENT_PIPELINE_ID
+ job: create-artifact
+```
+
+The `pipeline` attribute accepts a pipeline ID and it must be a pipeline present
+in the same parent-child pipeline hierarchy of the given pipeline.
+
+The `pipeline` attribute does not accept the current pipeline ID (`$CI_PIPELINE_ID`).
+To download artifacts from a job in the current pipeline, use the basic form of [`needs`](#artifact-downloads-with-needs).
+
+#### Optional `needs`
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/30680) in GitLab 13.10.
+> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/323891) in GitLab 14.0.
+
+To need a job that sometimes does not exist in the pipeline, add `optional: true`
+to the `needs` configuration. If not defined, `optional: false` is the default.
+
+Jobs that use [`rules`](#rules), [`only`, or `except`](#only--except), might
+not always exist in a pipeline. When the pipeline starts, it checks the `needs`
+relationships before running. Without `optional: true`, needs relationships that
+point to a job that does not exist stops the pipeline from starting and causes a pipeline
+error similar to:
+
+- `'job1' job needs 'job2' job, but it was not added to the pipeline`
+
+In this example:
+
+- When the branch is the default branch, the `build` job exists in the pipeline, and the `rspec`
+ job waits for it to complete before starting.
+- When the branch is not the default branch, the `build` job does not exist in the pipeline.
+ The `rspec` job runs immediately (similar to `needs: []`) because its `needs`
+ relationship to the `build` job is optional.
+
+```yaml
+build:
+ stage: build
+ rules:
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
+
+rspec:
+ stage: test
+ needs:
+ - job: build
+ optional: true
+```
+
+### `tags`
+
+Use `tags` to select a specific runner from the list of all runners that are
+available for the project.
+
+When you register a runner, you can specify the runner's tags, for
+example `ruby`, `postgres`, `development`.
+
+In the following example, the job is run by a runner that
+has both `ruby` and `postgres` tags defined.
+
+```yaml
+job:
+ tags:
+ - ruby
+ - postgres
+```
+
+You can use tags to run different jobs on different platforms. For
+example, if you have an OS X runner with tag `osx` and a Windows runner with tag
+`windows`, you can run a job on each platform:
+
+```yaml
+windows job:
+ stage:
+ - build
+ tags:
+ - windows
+ script:
+ - echo Hello, %USERNAME%!
+
+osx job:
+ stage:
+ - build
+ tags:
+ - osx
+ script:
+ - echo "Hello, $USER!"
+```
+
+### `allow_failure`
+
+Use `allow_failure` when you want to let a job fail without impacting the rest of the CI
+suite. The default value is `false`, except for [manual](#whenmanual) jobs that use
+the `when: manual` syntax.
+
+In jobs that use [`rules:`](#rules), all jobs default to `allow_failure: false`,
+*including* `when: manual` jobs.
+
+When `allow_failure` is set to `true` and the job fails, the job shows an orange warning in the UI.
+However, the logical flow of the pipeline considers the job a
+success/passed, and is not blocked.
+
+Assuming all other jobs are successful, the job's stage and its pipeline
+show the same orange warning. However, the associated commit is marked as
+"passed", without warnings.
+
+In the following example, `job1` and `job2` run in parallel. If `job1`
+fails, it doesn't stop the next stage from running, because it's marked with
+`allow_failure: true`:
+
+```yaml
+job1:
+ stage: test
+ script:
+ - execute_script_that_will_fail
+ allow_failure: true
+
+job2:
+ stage: test
+ script:
+ - execute_script_that_will_succeed
+
+job3:
+ stage: deploy
+ script:
+ - deploy_to_staging
+```
+
+#### `allow_failure:exit_codes`
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/273157) in GitLab 13.8.
+> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/292024) in GitLab 13.9.
+
+Use `allow_failure:exit_codes` to dynamically control if a job should be allowed
+to fail. You can list which exit codes are not considered failures. The job fails
+for any other exit code:
+
+```yaml
+test_job_1:
+ script:
+ - echo "Run a script that results in exit code 1. This job fails."
+ - exit 1
+ allow_failure:
+ exit_codes: 137
+
+test_job_2:
+ script:
+ - echo "Run a script that results in exit code 137. This job is allowed to fail."
+ - exit 137
+ allow_failure:
+ exit_codes:
+ - 137
+ - 255
+```
+
+### `when`
+
+Use `when` to implement jobs that run in case of failure or despite the
+failure.
+
+The valid values of `when` are:
+
+1. `on_success` (default) - Execute job only when all jobs in earlier stages succeed,
+ or are considered successful because they have `allow_failure: true`.
+1. `on_failure` - Execute job only when at least one job in an earlier stage fails.
+1. `always` - Execute job regardless of the status of jobs in earlier stages.
+1. `manual` - Execute job [manually](#whenmanual).
+1. `delayed` - [Delay the execution of a job](#whendelayed) for a specified duration.
+ Added in GitLab 11.14.
+1. `never`:
+ - With job [`rules`](#rules), don't execute job.
+ - With [`workflow:rules`](#workflow), don't run pipeline.
+
+In the following example, the script:
+
+1. Executes `cleanup_build_job` only when `build_job` fails.
+1. Always executes `cleanup_job` as the last step in pipeline regardless of
+ success or failure.
+1. Executes `deploy_job` when you run it manually in the GitLab UI.
+
+```yaml
+stages:
+ - build
+ - cleanup_build
+ - test
+ - deploy
+ - cleanup
+
+build_job:
+ stage: build
+ script:
+ - make build
+
+cleanup_build_job:
+ stage: cleanup_build
+ script:
+ - cleanup build when failed
+ when: on_failure
+
+test_job:
+ stage: test
+ script:
+ - make test
+
+deploy_job:
+ stage: deploy
+ script:
+ - make deploy
+ when: manual
+
+cleanup_job:
+ stage: cleanup
+ script:
+ - cleanup after jobs
+ when: always
+```
+
+#### `when:manual`
+
+A manual job is a type of job that is not executed automatically and must be explicitly
+started by a user. You might want to use manual jobs for things like deploying to production.
+
+To make a job manual, add `when: manual` to its configuration.
+
+When the pipeline starts, manual jobs display as skipped and do not run automatically.
+They can be started from the pipeline, job, [environment](../environments/index.md#configure-manual-deployments),
+and deployment views.
+
+Manual jobs can be either optional or blocking:
+
+- **Optional**: Manual jobs have [`allow_failure: true](#allow_failure) set by default
+ and are considered optional. The status of an optional manual job does not contribute
+ to the overall pipeline status. A pipeline can succeed even if all its manual jobs fail.
+
+- **Blocking**: To make a blocking manual job, add `allow_failure: false` to its configuration.
+ Blocking manual jobs stop further execution of the pipeline at the stage where the
+ job is defined. To let the pipeline continue running, click **{play}** (play) on
+ the blocking manual job.
+
+ Merge requests in projects with [merge when pipeline succeeds](../../user/project/merge_requests/merge_when_pipeline_succeeds.md)
+ enabled can't be merged with a blocked pipeline. Blocked pipelines show a status
+ of **blocked**.
+
+When you use [`rules:`](#rules), `allow_failure` defaults to `false`, including for manual jobs.
+
+To trigger a manual job, a user must have permission to merge to the assigned branch.
+You can use [protected branches](../../user/project/protected_branches.md) to more strictly
+[protect manual deployments](#protecting-manual-jobs) from being run by unauthorized users.
+
+In [GitLab 13.5](https://gitlab.com/gitlab-org/gitlab/-/issues/201938) and later, you
+can use `when:manual` in the same job as [`trigger`](#trigger). In GitLab 13.4 and
+earlier, using them together causes the error `jobs:#{job-name} when should be on_success, on_failure or always`.
+
+##### Protecting manual jobs **(PREMIUM)**
+
+Use [protected environments](../environments/protected_environments.md)
+to define a list of users authorized to run a manual job. You can authorize only
+the users associated with a protected environment to trigger manual jobs, which can:
+
+- More precisely limit who can deploy to an environment.
+- Block a pipeline until an approved user "approves" it.
+
+To protect a manual job:
+
+1. Add an `environment` to the job. For example:
+
+ ```yaml
+ deploy_prod:
+ stage: deploy
+ script:
+ - echo "Deploy to production server"
+ environment:
+ name: production
+ url: https://example.com
+ when: manual
+ rules:
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
+ ```
+
+1. In the [protected environments settings](../environments/protected_environments.md#protecting-environments),
+ select the environment (`production` in this example) and add the users, roles or groups
+ that are authorized to trigger the manual job to the **Allowed to Deploy** list. Only those in
+ this list can trigger this manual job, as well as GitLab administrators
+ who are always able to use protected environments.
+
+You can use protected environments with blocking manual jobs to have a list of users
+allowed to approve later pipeline stages. Add `allow_failure: false` to the protected
+manual job and the pipeline's next stages only run after the manual job is triggered
+by authorized users.
+
+#### `when:delayed`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/51352) in GitLab 11.4.
+
+Use `when: delayed` to execute scripts after a waiting period, or if you want to avoid
+jobs immediately entering the `pending` state.
+
+You can set the period with `start_in` keyword. The value of `start_in` is an elapsed time in seconds, unless a unit is
+provided. `start_in` must be less than or equal to one week. Examples of valid values include:
+
+- `'5'`
+- `5 seconds`
+- `30 minutes`
+- `1 day`
+- `1 week`
+
+When a stage includes a delayed job, the pipeline doesn't progress until the delayed job finishes.
+You can use this keyword to insert delays between different stages.
+
+The timer of a delayed job starts immediately after the previous stage completes.
+Similar to other types of jobs, a delayed job's timer doesn't start unless the previous stage passes.
+
+The following example creates a job named `timed rollout 10%` that is executed 30 minutes after the previous stage completes:
+
+```yaml
+timed rollout 10%:
+ stage: deploy
+ script: echo 'Rolling out 10% ...'
+ when: delayed
+ start_in: 30 minutes
+```
+
+To stop the active timer of a delayed job, click the **{time-out}** (**Unschedule**) button.
+This job can no longer be scheduled to run automatically. You can, however, execute the job manually.
+
+To start a delayed job immediately, click the **Play** button.
+Soon GitLab Runner picks up and starts the job.
+
+### `environment`
+
+Use `environment` to define the [environment](../environments/index.md) that a job deploys to.
+For example:
+
+```yaml
+deploy to production:
+ stage: deploy
+ script: git push production HEAD:main
+ environment: production
+```
+
+You can assign a value to the `environment` keyword by using:
+
+- Plain text, like `production`.
+- Variables, including CI/CD variables, predefined, secure, or variables
+ defined in the `.gitlab-ci.yml` file.
+
+You can't use variables defined in a `script` section.
+
+If you specify an `environment` and no environment with that name exists,
+an environment is created.
+
+#### `environment:name`
+
+Set a name for an [environment](../environments/index.md). For example:
+
+```yaml
+deploy to production:
+ stage: deploy
+ script: git push production HEAD:main
+ environment:
+ name: production
+```
+
+Common environment names are `qa`, `staging`, and `production`, but you can use any
+name you want.
+
+You can assign a value to the `name` keyword by using:
+
+- Plain text, like `staging`.
+- Variables, including CI/CD variables, predefined, secure, or variables
+ defined in the `.gitlab-ci.yml` file.
+
+You can't use variables defined in a `script` section.
+
+The environment `name` can contain:
+
+- Letters
+- Digits
+- Spaces
+- `-`
+- `_`
+- `/`
+- `$`
+- `{`
+- `}`
+
+#### `environment:url`
+
+Set a URL for an [environment](../environments/index.md). For example:
+
+```yaml
+deploy to production:
+ stage: deploy
+ script: git push production HEAD:main
+ environment:
+ name: production
+ url: https://prod.example.com
+```
+
+After the job completes, you can access the URL by using a button in the merge request,
+environment, or deployment pages.
+
+You can assign a value to the `url` keyword by using:
+
+- Plain text, like `https://prod.example.com`.
+- Variables, including CI/CD variables, predefined, secure, or variables
+ defined in the `.gitlab-ci.yml` file.
+
+You can't use variables defined in a `script` section.
+
+#### `environment:on_stop`
+
+Closing (stopping) environments can be achieved with the `on_stop` keyword
+defined under `environment`. It declares a different job that runs to close the
+environment.
+
+Read the `environment:action` section for an example.
+
+#### `environment:action`
+
+Use the `action` keyword to specify jobs that prepare, start, or stop environments.
+
+| **Value** | **Description** |
+|-----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `start` | Default value. Indicates that job starts the environment. The deployment is created after the job starts. |
+| `prepare` | Indicates that the job is only preparing the environment. It does not trigger deployments. [Read more about preparing environments](../environments/index.md#prepare-an-environment-without-creating-a-deployment). |
+| `stop` | Indicates that job stops deployment. See the example below. |
+
+Take for instance:
+
+```yaml
+review_app:
+ stage: deploy
+ script: make deploy-app
+ environment:
+ name: review/$CI_COMMIT_REF_NAME
+ url: https://$CI_ENVIRONMENT_SLUG.example.com
+ on_stop: stop_review_app
+
+stop_review_app:
+ stage: deploy
+ variables:
+ GIT_STRATEGY: none
+ script: make delete-app
+ when: manual
+ environment:
+ name: review/$CI_COMMIT_REF_NAME
+ action: stop
+```
+
+In the above example, the `review_app` job deploys to the `review`
+environment. A new `stop_review_app` job is listed under `on_stop`.
+After the `review_app` job is finished, it triggers the
+`stop_review_app` job based on what is defined under `when`. In this case,
+it is set to `manual`, so it needs a [manual action](#whenmanual) from
+the GitLab UI to run.
+
+Also in the example, `GIT_STRATEGY` is set to `none`. If the
+`stop_review_app` job is [automatically triggered](../environments/index.md#stopping-an-environment),
+the runner won't try to check out the code after the branch is deleted.
+
+The example also overwrites global variables. If your `stop` `environment` job depends
+on global variables, use [anchor variables](#yaml-anchors-for-variables) when you set the `GIT_STRATEGY`
+to change the job without overriding the global variables.
+
+The `stop_review_app` job is **required** to have the following keywords defined:
+
+- `when`, defined at either:
+ - [The job level](#when).
+ - [In a rules clause](#rules). If you use `rules:` and `when: manual`, you should
+ also set [`allow_failure: true`](#allow_failure) so the pipeline can complete
+ even if the job doesn't run.
+- `environment:name`
+- `environment:action`
+
+Additionally, both jobs should have matching [`rules`](#only--except)
+or [`only/except`](#only--except) configuration.
+
+In the examples above, if the configuration is not identical:
+
+- The `stop_review_app` job might not be included in all pipelines that include the `review_app` job.
+- It is not possible to trigger the `action: stop` to stop the environment automatically.
+
+#### `environment:auto_stop_in`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/20956) in GitLab 12.8.
+
+The `auto_stop_in` keyword is for specifying the lifetime of the environment,
+that when expired, GitLab automatically stops them.
+
+For example,
+
+```yaml
+review_app:
+ script: deploy-review-app
+ environment:
+ name: review/$CI_COMMIT_REF_NAME
+ auto_stop_in: 1 day
+```
+
+When the environment for `review_app` is created, the environment's lifetime is set to `1 day`.
+Every time the review app is deployed, that lifetime is also reset to `1 day`.
+
+For more information, see
+[the environments auto-stop documentation](../environments/index.md#stop-an-environment-after-a-certain-time-period)
+
+#### `environment:kubernetes`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27630) in GitLab 12.6.
+
+Use the `kubernetes` keyword to configure deployments to a
+[Kubernetes cluster](../../user/project/clusters/index.md) that is associated with your project.
+
+For example:
+
+```yaml
+deploy:
+ stage: deploy
+ script: make deploy-app
+ environment:
+ name: production
+ kubernetes:
+ namespace: production
+```
+
+This configuration sets up the `deploy` job to deploy to the `production`
+environment, using the `production`
+[Kubernetes namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/).
+
+For more information, see
+[Available settings for `kubernetes`](../environments/index.md#configure-kubernetes-deployments).
+
+NOTE:
+Kubernetes configuration is not supported for Kubernetes clusters
+that are [managed by GitLab](../../user/project/clusters/index.md#gitlab-managed-clusters).
+To follow progress on support for GitLab-managed clusters, see the
+[relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/38054).
+
+#### `environment:deployment_tier`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/300741) in GitLab 13.10.
+
+Use the `deployment_tier` keyword to specify the tier of the deployment environment:
+
+```yaml
+deploy:
+ script: echo
+ environment:
+ name: customer-portal
+ deployment_tier: production
+```
+
+For more information,
+see [Deployment tier of environments](../environments/index.md#deployment-tier-of-environments).
+
+#### Dynamic environments
+
+Use CI/CD [variables](../variables/index.md) to dynamically name environments.
+
+For example:
+
+```yaml
+deploy as review app:
+ stage: deploy
+ script: make deploy
+ environment:
+ name: review/$CI_COMMIT_REF_NAME
+ url: https://$CI_ENVIRONMENT_SLUG.example.com/
+```
+
+The `deploy as review app` job is marked as a deployment to dynamically
+create the `review/$CI_COMMIT_REF_NAME` environment. `$CI_COMMIT_REF_NAME`
+is a [CI/CD variable](../variables/index.md) set by the runner. The
+`$CI_ENVIRONMENT_SLUG` variable is based on the environment name, but suitable
+for inclusion in URLs. If the `deploy as review app` job runs in a branch named
+`pow`, this environment would be accessible with a URL like `https://review-pow.example.com/`.
+
+The common use case is to create dynamic environments for branches and use them
+as Review Apps. You can see an example that uses Review Apps at
+<https://gitlab.com/gitlab-examples/review-apps-nginx/>.
+
+### `cache`
+
+Use `cache` to specify a list of files and directories to
+cache between jobs. You can only use paths that are in the local working copy.
+
+Caching is shared between pipelines and jobs. Caches are restored before [artifacts](#artifacts).
+
+Learn more about caches in [Caching in GitLab CI/CD](../caching/index.md).
+
+#### `cache:paths`
+
+Use the `cache:paths` keyword to choose which files or directories to cache.
+
+**Keyword type**: Job-specific. You can use it only as part of a job.
+
+**Possible inputs**: An array of paths relative to the project directory (`$CI_PROJECT_DIR`).
+You can use wildcards that use [glob](https://en.wikipedia.org/wiki/Glob_(programming))
+patterns:
+
+- In [GitLab Runner 13.0](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2620) and later,
+[`doublestar.Glob`](https://pkg.go.dev/github.com/bmatcuk/doublestar@v1.2.2?tab=doc#Match).
+- In GitLab Runner 12.10 and earlier,
+[`filepath.Match`](https://pkg.go.dev/path/filepath#Match).
+
+**Example of `cache:paths`**:
+
+Cache all files in `binaries` that end in `.apk` and the `.config` file:
+
+```yaml
+rspec:
+ script:
+ - echo "This job uses a cache."
+ cache:
+ key: binaries-cache
+ paths:
+ - binaries/*.apk
+ - .config
+```
+
+**Related topics**:
+
+- See the [common `cache` use cases](../caching/index.md#common-use-cases-for-caches) for more
+ `cache:paths` examples.
+
+#### `cache:key`
+
+Use the `cache:key` keyword to give each cache a unique identifying key. All jobs
+that use the same cache key use the same cache, including in different pipelines.
+
+If not set, the default key is `default`. All jobs with the `cache:` keyword but
+no `cache:key` share the `default` cache.
+
+**Keyword type**: Job-specific. You can use it only as part of a job.
+
+**Possible inputs**:
+
+- A string.
+- A [predefined variables](../variables/index.md).
+- A combination of both.
+
+**Example of `cache:key`**:
+
+```yaml
+cache-job:
+ script:
+ - echo "This job uses a cache."
+ cache:
+ key: binaries-cache-$CI_COMMIT_REF_SLUG
+ paths:
+ - binaries/
+```
+
+**Additional details**:
+
+- If you use **Windows Batch** to run your shell scripts you need to replace
+ `$` with `%`. For example: `key: %CI_COMMIT_REF_SLUG%`
+- The `cache:key` value can't contain:
+
+ - The `/` character, or the equivalent URI-encoded `%2F`.
+ - Only the `.` character (any number), or the equivalent URI-encoded `%2E`.
+
+- The cache is shared between jobs, so if you're using different
+ paths for different jobs, you should also set a different `cache:key`.
+ Otherwise cache content can be overwritten.
+
+**Related topics**:
+
+- You can specify a [fallback cache key](../caching/index.md#use-a-fallback-cache-key)
+ to use if the specified `cache:key` is not found.
+- You can [use multiple cache keys](../caching/index.md#use-multiple-caches) in a single job.
+- See the [common `cache` use cases](../caching/index.md#common-use-cases-for-caches) for more
+ `cache:key` examples.
+
+##### `cache:key:files`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18986) in GitLab v12.5.
+
+Use the `cache:key:files` keyword to generate a new key when one or two specific files
+change. `cache:key:files` lets you reuse some caches, and rebuild them less often,
+which speeds up subsequent pipeline runs.
+
+**Keyword type**: Job-specific. You can use it only as part of a job.
+
+**Possible inputs**: An array of one or two file paths.
+
+**Example of `cache:key:files`**:
+
+```yaml
+cache-job:
+ script:
+ - echo "This job uses a cache."
+ cache:
+ key:
+ files:
+ - Gemfile.lock
+ - package.json
+ paths:
+ - vendor/ruby
+ - node_modules
+```
+
+This example creates a cache for Ruby and Node.js dependencies. The cache
+is tied to the current versions of the `Gemfile.lock` and `package.json` files. When one of
+these files changes, a new cache key is computed and a new cache is created. Any future
+job runs that use the same `Gemfile.lock` and `package.json` with `cache:key:files`
+use the new cache, instead of rebuilding the dependencies.
+
+**Additional details**: The cache `key` is a SHA computed from the most recent commits
+that changed each listed file. If neither file is changed in any commits, the
+fallback key is `default`.
+
+##### `cache:key:prefix`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18986) in GitLab v12.5.
+
+Use `cache:key:prefix` to combine a prefix with the SHA computed for [`cache:key:files`](#cachekeyfiles).
+
+**Keyword type**: Job-specific. You can use it only as part of a job.
+
+**Possible inputs**:
+
+- A string
+- A [predefined variables](../variables/index.md)
+- A combination of both.
+
+**Example of `cache:key:prefix`**:
+
+```yaml
+rspec:
+ script:
+ - echo "This rspec job uses a cache."
+ cache:
+ key:
+ files:
+ - Gemfile.lock
+ prefix: $CI_JOB_NAME
+ paths:
+ - vendor/ruby
+```
+
+For example, adding a `prefix` of `$CI_JOB_NAME` causes the key to look like `rspec-feef9576d21ee9b6a32e30c5c79d0a0ceb68d1e5`.
+If a branch changes `Gemfile.lock`, that branch has a new SHA checksum for `cache:key:files`.
+A new cache key is generated, and a new cache is created for that key. If `Gemfile.lock`
+is not found, the prefix is added to `default`, so the key in the example would be `rspec-default`.
+
+**Additional details**: If no file in `cache:key:files` is changed in any commits,
+the prefix is added to the `default` key.
+
+#### `cache:untracked`
+
+Use `untracked: true` to cache all files that are untracked in your Git repository:
+
+**Keyword type**: Job-specific. You can use it only as part of a job.
+
+**Possible inputs**: `true` or `false` (default).
+
+**Example of `cache:untracked`**:
+
+```yaml
+rspec:
+ script: test
+ cache:
+ untracked: true
+```
+
+**Additional details**:
+
+- You can combine `cache:untracked` with `cache:paths` to cache all untracked files
+ as well as files in the configured paths. For example:
+
+ ```yaml
+ rspec:
+ script: test
+ cache:
+ untracked: true
+ paths:
+ - binaries/
+ ```
+
+#### `cache:when`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18969) in GitLab 13.5 and GitLab Runner v13.5.0.
+
+Use `cache:when` to define when to save the cache, based on the status of the job.
+
+**Keyword type**: Job-specific. You can use it only as part of a job.
+
+**Possible inputs**:
+
+- `on_success` (default): Save the cache only when the job succeeds.
+- `on_failure`: Save the cache only when the job fails.
+- `always`: Always save the cache.
+
+**Example of `cache:when`**:
+
+```yaml
+rspec:
+ script: rspec
+ cache:
+ paths:
+ - rspec/
+ when: 'always'
+```
+
+This example stores the cache whether or not the job fails or succeeds.
+
+#### `cache:policy`
+
+To change the upload and download behavior of a cache, use the `cache:policy` keyword.
+By default, the job downloads the cache when the job starts, and uploads changes
+to the cache when the job ends. This is the `pull-push` policy (default).
+
+To set a job to only download the cache when the job starts, but never upload changes
+when the job finishes, use `cache:policy:pull`.
+
+To set a job to only upload a cache when the job finishes, but never download the
+cache when the job starts, use `cache:policy:push`.
+
+Use the `pull` policy when you have many jobs executing in parallel that use the same cache.
+This policy speeds up job execution and reduces load on the cache server. You can
+use a job with the `push` policy to build the cache.
+
+**Keyword type**: Job-specific. You can use it only as part of a job.
+
+**Possible inputs**:
+
+- `pull`
+- `push`
+- `pull-push` (default)
+
+**Example of `cache:policy`**:
+
+```yaml
+prepare-dependencies-job:
+ stage: build
+ cache:
+ key: gems
+ paths:
+ - vendor/bundle
+ policy: push
+ script:
+ - echo "This job only downloads dependencies and builds the cache."
+ - echo "Downloading dependencies..."
+
+faster-test-job:
+ stage: test
+ cache:
+ key: gems
+ paths:
+ - vendor/bundle
+ policy: pull
+ script:
+ - echo "This job script uses the cache, but does not update it."
+ - echo "Running tests..."
+```
+
+### `artifacts`
+
+Use `artifacts` to specify a list of files and directories that are
+attached to the job when it [succeeds, fails, or always](#artifactswhen).
+
+The artifacts are sent to GitLab after the job finishes. They are
+available for download in the GitLab UI if the size is not
+larger than the [maximum artifact size](../../user/gitlab_com/index.md#gitlab-cicd).
+
+By default, jobs in later stages automatically download all the artifacts created
+by jobs in earlier stages. You can control artifact download behavior in jobs with
+[`dependencies`](#dependencies).
+
+When using the [`needs`](#artifact-downloads-with-needs) keyword, jobs can only download
+artifacts from the jobs defined in the `needs` configuration.
+
+Job artifacts are only collected for successful jobs by default, and
+artifacts are restored after [caches](#cache).
+
+[Read more about artifacts](../pipelines/job_artifacts.md).
+
+#### `dependencies`
+
+By default, all `artifacts` from previous stages
+are passed to each job. However, you can use the `dependencies` keyword to
+define a limited list of jobs to fetch artifacts from. You can also set a job to download no artifacts at all.
+
+To use this feature, define `dependencies` in context of the job and pass
+a list of all previous jobs the artifacts should be downloaded from.
+
+You can define jobs from stages that were executed before the current one.
+An error occurs if you define jobs from the current or an upcoming stage.
+
+To prevent a job from downloading artifacts, define an empty array.
+
+When you use `dependencies`, the status of the previous job is not considered.
+If a job fails or it's a manual job that isn't triggered, no error occurs.
+
+The following example defines two jobs with artifacts: `build:osx` and
+`build:linux`. When the `test:osx` is executed, the artifacts from `build:osx`
+are downloaded and extracted in the context of the build. The same happens
+for `test:linux` and artifacts from `build:linux`.
+
+The job `deploy` downloads artifacts from all previous jobs because of
+the [stage](#stages) precedence:
+
+```yaml
+build:osx:
+ stage: build
+ script: make build:osx
+ artifacts:
+ paths:
+ - binaries/
+
+build:linux:
+ stage: build
+ script: make build:linux
+ artifacts:
+ paths:
+ - binaries/
+
+test:osx:
+ stage: test
+ script: make test:osx
+ dependencies:
+ - build:osx
+
+test:linux:
+ stage: test
+ script: make test:linux
+ dependencies:
+ - build:linux
+
+deploy:
+ stage: deploy
+ script: make deploy
+```
+
+##### When a dependent job fails
+
+> Introduced in GitLab 10.3.
+
+If the artifacts of the job that is set as a dependency are
+[expired](#artifactsexpire_in) or
+[deleted](../pipelines/job_artifacts.md#delete-job-artifacts), then
+the dependent job fails.
+
+#### `artifacts:exclude`
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15122) in GitLab 13.1
+> - Requires GitLab Runner 13.1
+
+`exclude` makes it possible to prevent files from being added to an artifacts
+archive.
+
+Similar to [`artifacts:paths`](#artifactspaths), `exclude` paths are relative
+to the project directory. You can use Wildcards that use
+[glob](https://en.wikipedia.org/wiki/Glob_(programming)) or
+[`doublestar.PathMatch`](https://pkg.go.dev/github.com/bmatcuk/doublestar@v1.2.2?tab=doc#PathMatch) patterns.
+
+For example, to store all files in `binaries/`, but not `*.o` files located in
+subdirectories of `binaries/`:
+
+```yaml
+artifacts:
+ paths:
+ - binaries/
+ exclude:
+ - binaries/**/*.o
+```
+
+Unlike [`artifacts:paths`](#artifactspaths), `exclude` paths are not recursive. To exclude all of the contents of a directory, you can match them explicitly rather than matching the directory itself.
+
+For example, to store all files in `binaries/` but nothing located in the `temp/` subdirectory:
+
+```yaml
+artifacts:
+ paths:
+ - binaries/
+ exclude:
+ - binaries/temp/**/*
+```
+
+Files matched by [`artifacts:untracked`](#artifactsuntracked) can be excluded using
+`artifacts:exclude` too.
+
+#### `artifacts:expire_in`
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16267) in GitLab 13.0 behind a disabled feature flag, the latest job artifacts are kept regardless of expiry time.
+> - [Made default behavior](https://gitlab.com/gitlab-org/gitlab/-/issues/229936) in GitLab 13.4.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/241026) in GitLab 13.8, keeping latest job artifacts can be disabled at the project level.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/276583) in GitLab 13.9, keeping latest job artifacts can be disabled instance-wide.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/321323) in GitLab 13.12, the latest pipeline artifacts are kept regardless of expiry time.
+
+Use `expire_in` to specify how long [job artifacts](../pipelines/job_artifacts.md) are stored before
+they expire and are deleted. The `expire_in` setting does not affect:
+
+- Artifacts from the latest job, unless this keeping the latest job artifacts is:
+ - [Disabled at the project level](../pipelines/job_artifacts.md#keep-artifacts-from-most-recent-successful-jobs).
+ - [Disabled instance-wide](../../user/admin_area/settings/continuous_integration.md#keep-the-latest-artifacts-for-all-jobs-in-the-latest-successful-pipelines).
+- [Pipeline artifacts](../pipelines/pipeline_artifacts.md). It's not possible to specify an
+ expiration date for these:
+ - Pipeline artifacts from the latest pipeline are kept forever.
+ - Other pipeline artifacts are erased after one week.
+
+The value of `expire_in` is an elapsed time in seconds, unless a unit is provided. Valid values
+include:
+
+- `'42'`
+- `42 seconds`
+- `3 mins 4 sec`
+- `2 hrs 20 min`
+- `2h20min`
+- `6 mos 1 day`
+- `47 yrs 6 mos and 4d`
+- `3 weeks and 2 days`
+- `never`
+
+To expire artifacts one week after being uploaded:
+
+```yaml
+job:
+ artifacts:
+ expire_in: 1 week
+```
+
+The expiration time period begins when the artifact is uploaded and stored on GitLab. If the expiry
+time is not defined, it defaults to the
+[instance wide setting](../../user/admin_area/settings/continuous_integration.md#default-artifacts-expiration)
+(30 days by default).
+
+To override the expiration date and protect artifacts from being automatically deleted:
+
+- Use the **Keep** button on the job page.
+- [In GitLab 13.3 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/22761), set the value of
+ `expire_in` to `never`.
+
+After their expiry, artifacts are deleted hourly by default (using a cron job), and are not
+accessible anymore.
+
+#### `artifacts:expose_as`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15018) in GitLab 12.5.
+
+Use the `expose_as` keyword to expose [job artifacts](../pipelines/job_artifacts.md)
+in the [merge request](../../user/project/merge_requests/index.md) UI.
+
+For example, to match a single file:
+
+```yaml
+test:
+ script: ["echo 'test' > file.txt"]
+ artifacts:
+ expose_as: 'artifact 1'
+ paths: ['file.txt']
+```
+
+With this configuration, GitLab adds a link **artifact 1** to the relevant merge request
+that points to `file1.txt`. To access the link, select **View exposed artifact**
+below the pipeline graph in the merge request overview.
+
+An example that matches an entire directory:
+
+```yaml
+test:
+ script: ["mkdir test && echo 'test' > test/file.txt"]
+ artifacts:
+ expose_as: 'artifact 1'
+ paths: ['test/']
+```
+
+Note the following:
+
+- Artifacts do not display in the merge request UI when using variables to define the `artifacts:paths`.
+- A maximum of 10 job artifacts per merge request can be exposed.
+- Glob patterns are unsupported.
+- If a directory is specified, the link is to the job [artifacts browser](../pipelines/job_artifacts.md#download-job-artifacts) if there is more than
+ one file in the directory.
+- For exposed single file artifacts with `.html`, `.htm`, `.txt`, `.json`, `.xml`,
+ and `.log` extensions, if [GitLab Pages](../../administration/pages/index.md) is:
+ - Enabled, GitLab automatically renders the artifact.
+ - Not enabled, the file is displayed in the artifacts browser.
+
+#### `artifacts:name`
+
+Use the `name` directive to define the name of the created artifacts
+archive. You can specify a unique name for every archive. The `artifacts:name`
+variable can make use of any of the [predefined variables](../variables/index.md).
+The default name is `artifacts`, which becomes `artifacts.zip` when you download it.
+
+To create an archive with a name of the current job:
+
+```yaml
+job:
+ artifacts:
+ name: "$CI_JOB_NAME"
+ paths:
+ - binaries/
+```
+
+To create an archive with a name of the current branch or tag including only
+the binaries directory:
+
+```yaml
+job:
+ artifacts:
+ name: "$CI_COMMIT_REF_NAME"
+ paths:
+ - binaries/
+```
+
+If your branch-name contains forward slashes
+(for example `feature/my-feature`) it's advised to use `$CI_COMMIT_REF_SLUG`
+instead of `$CI_COMMIT_REF_NAME` for proper naming of the artifact.
+
+To create an archive with a name of the current job and the current branch or
+tag including only the binaries directory:
+
+```yaml
+job:
+ artifacts:
+ name: "$CI_JOB_NAME-$CI_COMMIT_REF_NAME"
+ paths:
+ - binaries/
+```
+
+To create an archive with a name of the current [stage](#stages) and branch name:
+
+```yaml
+job:
+ artifacts:
+ name: "$CI_JOB_STAGE-$CI_COMMIT_REF_NAME"
+ paths:
+ - binaries/
+```
+
+---
+
+If you use **Windows Batch** to run your shell scripts you need to replace
+`$` with `%`:
+
+```yaml
+job:
+ artifacts:
+ name: "%CI_JOB_STAGE%-%CI_COMMIT_REF_NAME%"
+ paths:
+ - binaries/
+```
+
+If you use **Windows PowerShell** to run your shell scripts you need to replace
+`$` with `$env:`:
+
+```yaml
+job:
+ artifacts:
+ name: "$env:CI_JOB_STAGE-$env:CI_COMMIT_REF_NAME"
+ paths:
+ - binaries/
+```
+
+#### `artifacts:paths`
+
+Paths are relative to the project directory (`$CI_PROJECT_DIR`) and can't directly
+link outside it. You can use Wildcards that use [glob](https://en.wikipedia.org/wiki/Glob_(programming))
+patterns and:
+
+- In [GitLab Runner 13.0](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2620) and later,
+[`doublestar.Glob`](https://pkg.go.dev/github.com/bmatcuk/doublestar@v1.2.2?tab=doc#Match).
+- In GitLab Runner 12.10 and earlier,
+[`filepath.Match`](https://pkg.go.dev/path/filepath#Match).
+
+To restrict which jobs a specific job fetches artifacts from, see [dependencies](#dependencies).
+
+Send all files in `binaries` and `.config`:
+
+```yaml
+artifacts:
+ paths:
+ - binaries/
+ - .config
+```
+
+To disable artifact passing, define the job with empty [dependencies](#dependencies):
+
+```yaml
+job:
+ stage: build
+ script: make build
+ dependencies: []
+```
+
+You may want to create artifacts only for tagged releases to avoid filling the
+build server storage with temporary build artifacts.
+
+Create artifacts only for tags (`default-job` doesn't create artifacts):
+
+```yaml
+default-job:
+ script:
+ - mvn test -U
+ rules:
+ - if: $CI_COMMIT_BRANCH
+
+release-job:
+ script:
+ - mvn package -U
+ artifacts:
+ paths:
+ - target/*.war
+ rules:
+ - if: $CI_COMMIT_TAG
+```
+
+You can use wildcards for directories too. For example, if you want to get all the files inside the directories that end with `xyz`:
+
+```yaml
+job:
+ artifacts:
+ paths:
+ - path/*xyz/*
+```
+
+#### `artifacts:public`
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49775) in GitLab 13.8
+> - It's [deployed behind a feature flag](../../user/feature_flags.md), disabled by default.
+> - It's disabled on GitLab.com.
+> - It's recommended for production use.
+
+Use `artifacts:public` to determine whether the job artifacts should be
+publicly available.
+
+The default for `artifacts:public` is `true` which means that the artifacts in
+public pipelines are available for download by anonymous and guest users:
+
+```yaml
+artifacts:
+ public: true
+```
+
+To deny read access for anonymous and guest users to artifacts in public
+pipelines, set `artifacts:public` to `false`:
+
+```yaml
+artifacts:
+ public: false
+```
+
+#### `artifacts:reports`
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/20390) in GitLab 11.2.
+> - Requires GitLab Runner 11.2 and above.
+
+Use [`artifacts:reports`](#artifactsreports)
+to collect test reports, code quality reports, and security reports from jobs.
+It also exposes these reports in the GitLab UI (merge requests, pipeline views, and security dashboards).
+
+The test reports are collected regardless of the job results (success or failure).
+You can use [`artifacts:expire_in`](#artifactsexpire_in) to set up an expiration
+date for their artifacts.
+
+If you also want the ability to browse the report output files, include the
+[`artifacts:paths`](#artifactspaths) keyword.
+
+##### `artifacts:reports:api_fuzzing` **(ULTIMATE)**
+
+> - Introduced in GitLab 13.4.
+> - Requires GitLab Runner 13.4 or later.
+
+The `api_fuzzing` report collects [API Fuzzing bugs](../../user/application_security/api_fuzzing/index.md)
+as artifacts.
+
+The collected API Fuzzing report uploads to GitLab as an artifact and is summarized in merge
+requests and the pipeline view. It's also used to provide data for security dashboards.
+
+##### `artifacts:reports:cobertura`
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3708) in GitLab 12.9.
+> - Requires [GitLab Runner](https://docs.gitlab.com/runner/) 11.5 and above.
+
+The `cobertura` report collects [Cobertura coverage XML files](../../user/project/merge_requests/test_coverage_visualization.md).
+The collected Cobertura coverage reports upload to GitLab as an artifact
+and display in merge requests.
+
+Cobertura was originally developed for Java, but there are many
+third party ports for other languages like JavaScript, Python, Ruby, and so on.
+
+##### `artifacts:reports:codequality`
+
+> - Introduced in GitLab 11.5.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212499) to GitLab Free in 13.2.
+> - Requires GitLab Runner 11.5 and above.
+
+The `codequality` report collects [Code Quality issues](../../user/project/merge_requests/code_quality.md)
+as artifacts.
+
+The collected Code Quality report uploads to GitLab as an artifact and is summarized in merge requests.
+
+##### `artifacts:reports:container_scanning` **(ULTIMATE)**
+
+> - Introduced in GitLab 11.5.
+> - Requires GitLab Runner 11.5 and above.
+
+The `container_scanning` report collects [Container Scanning vulnerabilities](../../user/application_security/container_scanning/index.md)
+as artifacts.
+
+The collected Container Scanning report uploads to GitLab as an artifact and
+is summarized in merge requests and the pipeline view. It's also used to provide data for security
+dashboards.
+
+##### `artifacts:reports:coverage_fuzzing` **(ULTIMATE)**
+
+> - Introduced in GitLab 13.4.
+> - Requires GitLab Runner 13.4 or later.
+
+The `coverage_fuzzing` report collects [coverage fuzzing bugs](../../user/application_security/coverage_fuzzing/index.md)
+as artifacts.
+
+The collected coverage fuzzing report uploads to GitLab as an artifact and is summarized in merge
+requests and the pipeline view. It's also used to provide data for security dashboards.
+
+##### `artifacts:reports:cluster_image_scanning` **(ULTIMATE)**
+
+> - Introduced in GitLab 14.1.
+> - Requires GitLab Runner 14.1 and above.
+
+The `cluster_image_scanning` report collects `CLUSTER_IMAGE_SCANNING` vulnerabilities
+as artifacts.
+
+The collected `CLUSTER_IMAGE_SCANNING` report uploads to GitLab as an artifact and
+is summarized in the pipeline view. It's also used to provide data for security
+dashboards.
+
+##### `artifacts:reports:dast` **(ULTIMATE)**
+
+> - Introduced in GitLab 11.5.
+> - Requires GitLab Runner 11.5 and above.
+
+The `dast` report collects [DAST vulnerabilities](../../user/application_security/dast/index.md)
+as artifacts.
+
+The collected DAST report uploads to GitLab as an artifact and is summarized in merge requests and the pipeline view. It's also used to provide data for security
+dashboards.
+
+##### `artifacts:reports:dependency_scanning` **(ULTIMATE)**
+
+> - Introduced in GitLab 11.5.
+> - Requires GitLab Runner 11.5 and above.
+
+The `dependency_scanning` report collects [Dependency Scanning vulnerabilities](../../user/application_security/dependency_scanning/index.md)
+as artifacts.
+
+The collected Dependency Scanning report uploads to GitLab as an artifact and is summarized in merge requests and the pipeline view. It's also used to provide data for security
+dashboards.
+
+##### `artifacts:reports:dotenv`
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/17066) in GitLab 12.9.
+> - Requires GitLab Runner 11.5 and later.
+
+The `dotenv` report collects a set of environment variables as artifacts.
+
+The collected variables are registered as runtime-created variables of the job,
+which is useful to [set dynamic environment URLs after a job finishes](../environments/index.md#set-dynamic-environment-urls-after-a-job-finishes).
+
+There are a couple of exceptions to the [original dotenv rules](https://github.com/motdotla/dotenv#rules):
+
+- The variable key can contain only letters, digits, and underscores (`_`).
+- The maximum size of the `.env` file is 5 KB.
+- In GitLab 13.5 and older, the maximum number of inherited variables is 10.
+- In [GitLab 13.6 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/247913),
+ the maximum number of inherited variables is 20.
+- Variable substitution in the `.env` file is not supported.
+- The `.env` file can't have empty lines or comments (starting with `#`).
+- Key values in the `env` file cannot have spaces or newline characters (`\n`), including when using single or double quotes.
+- Quote escaping during parsing (`key = 'value'` -> `{key: "value"}`) is not supported.
+
+##### `artifacts:reports:junit`
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/20390) in GitLab 11.2.
+> - Requires GitLab Runner 11.2 and above.
+
+The `junit` report collects [JUnit report format XML files](https://www.ibm.com/docs/en/adfz/developer-for-zos/14.1.0?topic=formats-junit-xml-format)
+as artifacts. Although JUnit was originally developed in Java, there are many
+third party ports for other
+languages like JavaScript, Python, Ruby, and so on.
+
+See [Unit test reports](../unit_test_reports.md) for more details and examples.
+Below is an example of collecting a JUnit report format XML file from Ruby's RSpec test tool:
+
+```yaml
+rspec:
+ stage: test
+ script:
+ - bundle install
+ - rspec --format RspecJunitFormatter --out rspec.xml
+ artifacts:
+ reports:
+ junit: rspec.xml
+```
+
+The collected Unit test reports upload to GitLab as an artifact and display in merge requests.
+
+If the JUnit tool you use exports to multiple XML files, specify
+multiple test report paths within a single job to
+concatenate them into a single file. Use a filename pattern (`junit: rspec-*.xml`),
+an array of filenames (`junit: [rspec-1.xml, rspec-2.xml, rspec-3.xml]`), or a
+combination thereof (`junit: [rspec.xml, test-results/TEST-*.xml]`).
+
+##### `artifacts:reports:license_scanning` **(ULTIMATE)**
+
+> - Introduced in GitLab 12.8.
+> - Requires GitLab Runner 11.5 and above.
+
+The `license_scanning` report collects [Licenses](../../user/compliance/license_compliance/index.md)
+as artifacts.
+
+The License Compliance report uploads to GitLab as an artifact and displays automatically in merge requests and the pipeline view, and provide data for security
+dashboards.
+
+##### `artifacts:reports:load_performance` **(PREMIUM)**
+
+> - Introduced in [GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35260) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.2.
+> - Requires GitLab Runner 11.5 and above.
+
+The `load_performance` report collects [Load Performance Testing metrics](../../user/project/merge_requests/load_performance_testing.md)
+as artifacts.
+
+The report is uploaded to GitLab as an artifact and is
+shown in merge requests automatically.
+
+##### `artifacts:reports:metrics` **(PREMIUM)**
+
+> Introduced in GitLab 11.10.
+
+The `metrics` report collects [Metrics](../metrics_reports.md)
+as artifacts.
+
+The collected Metrics report uploads to GitLab as an artifact and displays in merge requests.
+
+##### `artifacts:reports:browser_performance` **(PREMIUM)**
+
+> - Introduced in GitLab 11.5.
+> - Requires GitLab Runner 11.5 and above.
+> - [Name changed](https://gitlab.com/gitlab-org/gitlab/-/issues/225914) from `artifacts:reports:performance` in GitLab 14.0.
+
+The `browser_performance` report collects [Browser Performance Testing metrics](../../user/project/merge_requests/browser_performance_testing.md)
+as artifacts.
+
+The collected Browser Performance report uploads to GitLab as an artifact and displays in merge requests.
+
+##### `artifacts:reports:requirements` **(ULTIMATE)**
+
+> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2859) in GitLab 13.1.
+> - Requires GitLab Runner 11.5 and above.
+
+The `requirements` report collects `requirements.json` files as artifacts.
+
+The collected Requirements report uploads to GitLab as an artifact and
+existing [requirements](../../user/project/requirements/index.md) are
+marked as Satisfied.
+
+##### `artifacts:reports:sast`
+
+> - Introduced in GitLab 11.5.
+> - Made [available in all tiers](https://gitlab.com/groups/gitlab-org/-/epics/2098) in GitLab 13.3.
+> - Requires GitLab Runner 11.5 and above.
+
+The `sast` report collects [SAST vulnerabilities](../../user/application_security/sast/index.md)
+as artifacts.
+
+The collected SAST report uploads to GitLab as an artifact and is summarized
+in merge requests and the pipeline view. It's also used to provide data for security
+dashboards.
+
+##### `artifacts:reports:secret_detection`
+
+> - Introduced in GitLab 13.1.
+> - Made [available in all tiers](https://gitlab.com/gitlab-org/gitlab/-/issues/222788) in GitLab
+ 13.3.
+> - Requires GitLab Runner 11.5 and above.
+
+The `secret-detection` report collects [detected secrets](../../user/application_security/secret_detection/index.md)
+as artifacts.
+
+The collected Secret Detection report is uploaded to GitLab as an artifact and summarized
+in the merge requests and pipeline view. It's also used to provide data for security
+dashboards.
+
+##### `artifacts:reports:terraform`
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207528) in GitLab 13.0.
+> - Requires [GitLab Runner](https://docs.gitlab.com/runner/) 11.5 and above.
+
+The `terraform` report obtains a Terraform `tfplan.json` file. [JQ processing required to remove credentials](../../user/infrastructure/mr_integration.md#setup). The collected Terraform
+plan report uploads to GitLab as an artifact and displays
+in merge requests. For more information, see
+[Output `terraform plan` information into a merge request](../../user/infrastructure/mr_integration.md).
+
+#### `artifacts:untracked`
+
+Use `artifacts:untracked` to add all Git untracked files as artifacts (along
+with the paths defined in `artifacts:paths`). `artifacts:untracked` ignores configuration
+in the repository's `.gitignore` file.
+
+Send all Git untracked files:
+
+```yaml
+artifacts:
+ untracked: true
+```
+
+Send all Git untracked files and files in `binaries`:
+
+```yaml
+artifacts:
+ untracked: true
+ paths:
+ - binaries/
+```
+
+Send all untracked files but [exclude](#artifactsexclude) `*.txt`:
+
+```yaml
+artifacts:
+ untracked: true
+ exclude:
+ - "*.txt"
+```
+
+#### `artifacts:when`
+
+Use `artifacts:when` to upload artifacts on job failure or despite the
+failure.
+
+`artifacts:when` can be set to one of the following values:
+
+1. `on_success` (default): Upload artifacts only when the job succeeds.
+1. `on_failure`: Upload artifacts only when the job fails.
+1. `always`: Always upload artifacts. Useful, for example, when
+ [uploading artifacts](../unit_test_reports.md#viewing-junit-screenshots-on-gitlab) required to
+ troubleshoot failing tests.
+
+For example, to upload artifacts only when a job fails:
+
+```yaml
+job:
+ artifacts:
+ when: on_failure
+```
+
+### `coverage`
+
+Use `coverage` to configure how code coverage is extracted from the
+job output.
+
+Regular expressions are the only valid kind of value expected here. So, using
+surrounding `/` is mandatory to consistently and explicitly represent
+a regular expression string. You must escape special characters if you want to
+match them literally.
+
+For example:
+
+```yaml
+job1:
+ script: rspec
+ coverage: '/Code coverage: \d+\.\d+/'
+```
+
+The coverage is shown in the UI if at least one line in the job output matches the regular expression.
+If there is more than one matched line in the job output, the last line is used.
+For the matched line, the first occurrence of `\d+(\.\d+)?` is the code coverage.
+Leading zeros are removed.
+
+Coverage output from [child pipelines](../pipelines/parent_child_pipelines.md) is not recorded
+or displayed. Check [the related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/280818)
+for more details.
+
+### `retry`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/3515) in GitLab 11.5, you can control which failures to retry on.
+
+Use `retry` to configure how many times a job is retried in
+case of a failure.
+
+When a job fails, the job is processed again,
+until the limit specified by the `retry` keyword is reached.
+
+If `retry` is set to `2`, and a job succeeds in a second run (first retry), it is not retried.
+The `retry` value must be a positive integer, from `0` to `2`
+(two retries maximum, three runs in total).
+
+The following example retries all failure cases:
+
+```yaml
+test:
+ script: rspec
+ retry: 2
+```
+
+By default, a job is retried on all failure cases. To have better control
+over which failures to retry, `retry` can be a hash with the following keys:
+
+- `max`: The maximum number of retries.
+- `when`: The failure cases to retry.
+
+To retry only runner system failures at maximum two times:
+
+```yaml
+test:
+ script: rspec
+ retry:
+ max: 2
+ when: runner_system_failure
+```
+
+If there is another failure, other than a runner system failure, the job
+is not retried.
+
+To retry on multiple failure cases, `when` can also be an array of failures:
+
+```yaml
+test:
+ script: rspec
+ retry:
+ max: 2
+ when:
+ - runner_system_failure
+ - stuck_or_timeout_failure
+```
+
+Possible values for `when` are:
+
+<!--
+ If you change any of the values below, make sure to update the `RETRY_WHEN_IN_DOCUMENTATION`
+ array in `spec/lib/gitlab/ci/config/entry/retry_spec.rb`.
+ The test there makes sure that all documented
+ values are valid as a configuration option and therefore should always
+ stay in sync with this documentation.
+-->
+
+- `always`: Retry on any failure (default).
+- `unknown_failure`: Retry when the failure reason is unknown.
+- `script_failure`: Retry when the script failed.
+- `api_failure`: Retry on API failure.
+- `stuck_or_timeout_failure`: Retry when the job got stuck or timed out.
+- `runner_system_failure`: Retry if there is a runner system failure (for example, job setup failed).
+- `missing_dependency_failure`: Retry if a dependency is missing.
+- `runner_unsupported`: Retry if the runner is unsupported.
+- `stale_schedule`: Retry if a delayed job could not be executed.
+- `job_execution_timeout`: Retry if the script exceeded the maximum execution time set for the job.
+- `archived_failure`: Retry if the job is archived and can't be run.
+- `unmet_prerequisites`: Retry if the job failed to complete prerequisite tasks.
+- `scheduler_failure`: Retry if the scheduler failed to assign the job to a runner.
+- `data_integrity_failure`: Retry if there is a structural integrity problem detected.
+
+You can specify the number of [retry attempts for certain stages of job execution](../runners/configure_runners.md#job-stages-attempts) using variables.
+
+### `timeout`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/14887) in GitLab 12.3.
+
+Use `timeout` to configure a timeout for a specific job. For example:
+
+```yaml
+build:
+ script: build.sh
+ timeout: 3 hours 30 minutes
+
+test:
+ script: rspec
+ timeout: 3h 30m
+```
+
+The job-level timeout can exceed the
+[project-level timeout](../pipelines/settings.md#set-a-limit-for-how-long-jobs-can-run) but can't
+exceed the runner-specific timeout.
+
+### `parallel`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/21480) in GitLab 11.5.
+
+Use `parallel` to configure how many instances of a job to run in parallel.
+The value can be from 2 to 50.
+
+The `parallel` keyword creates N instances of the same job that run in parallel.
+They are named sequentially from `job_name 1/N` to `job_name N/N`:
+
+```yaml
+test:
+ script: rspec
+ parallel: 5
+```
+
+Every parallel job has a `CI_NODE_INDEX` and `CI_NODE_TOTAL`
+[predefined CI/CD variable](../variables/index.md#predefined-cicd-variables) set.
+
+Different languages and test suites have different methods to enable parallelization.
+For example, use [Semaphore Test Boosters](https://github.com/renderedtext/test-boosters)
+and RSpec to run Ruby tests in parallel:
+
+```ruby
+# Gemfile
+source 'https://rubygems.org'
+
+gem 'rspec'
+gem 'semaphore_test_boosters'
+```
+
+```yaml
+test:
+ parallel: 3
+ script:
+ - bundle
+ - bundle exec rspec_booster --job $CI_NODE_INDEX/$CI_NODE_TOTAL
+```
+
+WARNING:
+Test Boosters reports usage statistics to the author.
+
+You can then navigate to the **Jobs** tab of a new pipeline build and see your RSpec
+job split into three separate jobs.
+
+#### Parallel `matrix` jobs
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15356) in GitLab 13.3.
+
+Use `matrix:` to run a job multiple times in parallel in a single pipeline,
+but with different variable values for each instance of the job.
+There can be from 2 to 50 jobs.
+
+Jobs can only run in parallel if there are multiple runners, or a single runner is
+[configured to run multiple jobs concurrently](#use-your-own-runners).
+
+Every job gets the same `CI_NODE_TOTAL` [CI/CD variable](../variables/index.md#predefined-cicd-variables) value, and a unique `CI_NODE_INDEX` value.
+
+```yaml
+deploystacks:
+ stage: deploy
+ script:
+ - bin/deploy
+ parallel:
+ matrix:
+ - PROVIDER: aws
+ STACK:
+ - monitoring
+ - app1
+ - app2
+ - PROVIDER: ovh
+ STACK: [monitoring, backup, app]
+ - PROVIDER: [gcp, vultr]
+ STACK: [data, processing]
+```
+
+The following example generates 10 parallel `deploystacks` jobs, each with different values
+for `PROVIDER` and `STACK`:
+
+```plaintext
+deploystacks: [aws, monitoring]
+deploystacks: [aws, app1]
+deploystacks: [aws, app2]
+deploystacks: [ovh, monitoring]
+deploystacks: [ovh, backup]
+deploystacks: [ovh, app]
+deploystacks: [gcp, data]
+deploystacks: [gcp, processing]
+deploystacks: [vultr, data]
+deploystacks: [vultr, processing]
+```
+
+The job naming style was [improved in GitLab 13.4](https://gitlab.com/gitlab-org/gitlab/-/issues/230452).
+
+##### One-dimensional `matrix` jobs
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/26362) in GitLab 13.5.
+
+You can also have one-dimensional matrices with a single job:
+
+```yaml
+deploystacks:
+ stage: deploy
+ script:
+ - bin/deploy
+ parallel:
+ matrix:
+ - PROVIDER: [aws, ovh, gcp, vultr]
+```
+
+##### Parallel `matrix` trigger jobs
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/270957) in GitLab 13.10.
+
+Use `matrix:` to run a [trigger](#trigger) job multiple times in parallel in a single pipeline,
+but with different variable values for each instance of the job.
+
+```yaml
+deploystacks:
+ stage: deploy
+ trigger:
+ include: path/to/child-pipeline.yml
+ parallel:
+ matrix:
+ - PROVIDER: aws
+ STACK: [monitoring, app1]
+ - PROVIDER: ovh
+ STACK: [monitoring, backup]
+ - PROVIDER: [gcp, vultr]
+ STACK: [data]
+```
+
+This example generates 6 parallel `deploystacks` trigger jobs, each with different values
+for `PROVIDER` and `STACK`, and they create 6 different child pipelines with those variables.
+
+```plaintext
+deploystacks: [aws, monitoring]
+deploystacks: [aws, app1]
+deploystacks: [ovh, monitoring]
+deploystacks: [ovh, backup]
+deploystacks: [gcp, data]
+deploystacks: [vultr, data]
+```
+
+### `trigger`
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8997) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.8.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/199224) to GitLab Free in 12.8.
+
+Use `trigger` to define a downstream pipeline trigger. When GitLab starts a `trigger` job,
+a downstream pipeline is created.
+
+Jobs with `trigger` can only use a [limited set of keywords](../pipelines/multi_project_pipelines.md#define-multi-project-pipelines-in-your-gitlab-ciyml-file).
+For example, you can't run commands with [`script`](#script), [`before_script`](#before_script),
+or [`after_script`](#after_script).
+
+You can use this keyword to create two different types of downstream pipelines:
+
+- [Multi-project pipelines](../pipelines/multi_project_pipelines.md#define-multi-project-pipelines-in-your-gitlab-ciyml-file)
+- [Child pipelines](../pipelines/parent_child_pipelines.md)
+
+[In GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/issues/197140/) and later, you can
+view which job triggered a downstream pipeline. In the [pipeline graph](../pipelines/index.md#visualize-pipelines),
+hover over the downstream pipeline job.
+
+In [GitLab 13.5](https://gitlab.com/gitlab-org/gitlab/-/issues/201938) and later, you
+can use [`when:manual`](#whenmanual) in the same job as `trigger`. In GitLab 13.4 and
+earlier, using them together causes the error `jobs:#{job-name} when should be on_success, on_failure or always`.
+You [cannot start `manual` trigger jobs with the API](https://gitlab.com/gitlab-org/gitlab/-/issues/284086).
+
+#### Basic `trigger` syntax for multi-project pipelines
+
+You can configure a downstream trigger by using the `trigger` keyword
+with a full path to a downstream project:
+
+```yaml
+rspec:
+ stage: test
+ script: bundle exec rspec
+
+staging:
+ stage: deploy
+ trigger: my/deployment
+```
+
+#### Complex `trigger` syntax for multi-project pipelines
+
+You can configure a branch name that GitLab uses to create
+a downstream pipeline with:
+
+```yaml
+rspec:
+ stage: test
+ script: bundle exec rspec
+
+staging:
+ stage: deploy
+ trigger:
+ project: my/deployment
+ branch: stable
+```
+
+To mirror the status from a triggered pipeline:
+
+```yaml
+trigger_job:
+ trigger:
+ project: my/project
+ strategy: depend
+```
+
+To mirror the status from an upstream pipeline:
+
+```yaml
+upstream_bridge:
+ stage: test
+ needs:
+ pipeline: other/project
+```
+
+#### `trigger` syntax for child pipeline
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16094) in GitLab 12.7.
+
+To create a [child pipeline](../pipelines/parent_child_pipelines.md), specify the path to the
+YAML file that contains the configuration of the child pipeline:
+
+```yaml
+trigger_job:
+ trigger:
+ include: path/to/child-pipeline.yml
+```
+
+Similar to [multi-project pipelines](../pipelines/multi_project_pipelines.md#mirror-status-of-a-triggered-pipeline-in-the-trigger-job),
+it's possible to mirror the status from a triggered pipeline:
+
+```yaml
+trigger_job:
+ trigger:
+ include:
+ - local: path/to/child-pipeline.yml
+ strategy: depend
+```
+
+##### Trigger child pipeline with generated configuration file
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35632) in GitLab 12.9.
+
+You can also trigger a child pipeline from a [dynamically generated configuration file](../pipelines/parent_child_pipelines.md#dynamic-child-pipelines):
+
+```yaml
+generate-config:
+ stage: build
+ script: generate-ci-config > generated-config.yml
+ artifacts:
+ paths:
+ - generated-config.yml
+
+child-pipeline:
+ stage: test
+ trigger:
+ include:
+ - artifact: generated-config.yml
+ job: generate-config
+```
+
+The `generated-config.yml` is extracted from the artifacts and used as the configuration
+for triggering the child pipeline.
+
+##### Trigger child pipeline with files from another project
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/205157) in GitLab 13.5.
+
+To trigger child pipelines with files from another private project under the same
+GitLab instance, use [`include:file`](#includefile):
+
+```yaml
+child-pipeline:
+ trigger:
+ include:
+ - project: 'my-group/my-pipeline-library'
+ ref: 'main'
+ file: '/path/to/child-pipeline.yml'
+```
+
+#### Linking pipelines with `trigger:strategy`
+
+By default, the `trigger` job completes with the `success` status
+as soon as the downstream pipeline is created.
+
+To force the `trigger` job to wait for the downstream (multi-project or child) pipeline to complete, use
+`strategy: depend`. This setting makes the trigger job wait with a "running" status until the triggered
+pipeline completes. At that point, the `trigger` job completes and displays the same status as
+the downstream job.
+
+This setting can help keep your pipeline execution linear. In the following example, jobs from
+subsequent stages wait for the triggered pipeline to successfully complete before
+starting, which reduces parallelization.
+
+```yaml
+trigger_job:
+ trigger:
+ include: path/to/child-pipeline.yml
+ strategy: depend
+```
+
+#### Trigger a pipeline by API call
+
+To force a rebuild of a specific branch, tag, or commit, you can use an API call
+with a trigger token.
+
+The trigger token is different than the [`trigger`](#trigger) keyword.
+
+[Read more in the triggers documentation.](../triggers/index.md)
+
+### `interruptible`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32022) in GitLab 12.3.
+
+Use `interruptible` to indicate that a running job should be canceled if made redundant by a newer pipeline run.
+Defaults to `false` (uninterruptible). Jobs that have not started yet (pending) are considered interruptible
+and safe to be cancelled.
+This value is used only if the [automatic cancellation of redundant pipelines feature](../pipelines/settings.md#auto-cancel-redundant-pipelines)
+is enabled.
+
+When enabled, a pipeline is immediately canceled when a new pipeline starts on the same branch if either of the following is true:
+
+- All jobs in the pipeline are set as interruptible.
+- Any uninterruptible jobs have not started yet.
+
+Set jobs as interruptible that can be safely canceled once started (for instance, a build job).
+
+In the following example, a new pipeline run causes an existing running pipeline to be:
+
+- Canceled, if only `step-1` is running or pending.
+- Not canceled, once `step-2` starts running.
+
+After an uninterruptible job starts running, the pipeline cannot be canceled.
+
+```yaml
+stages:
+ - stage1
+ - stage2
+ - stage3
+
+step-1:
+ stage: stage1
+ script:
+ - echo "Can be canceled."
+ interruptible: true
+
+step-2:
+ stage: stage2
+ script:
+ - echo "Can not be canceled."
+
+step-3:
+ stage: stage3
+ script:
+ - echo "Because step-2 can not be canceled, this step can never be canceled, even though it's set as interruptible."
+ interruptible: true
+```
+
+### `resource_group`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15536) in GitLab 12.7.
+
+Sometimes running multiple jobs or pipelines at the same time in an environment
+can lead to errors during the deployment.
+
+To avoid these errors, use the `resource_group` attribute to make sure that
+the runner doesn't run certain jobs simultaneously. Resource groups behave similar
+to semaphores in other programming languages.
+
+When the `resource_group` keyword is defined for a job in the `.gitlab-ci.yml` file,
+job executions are mutually exclusive across different pipelines for the same project.
+If multiple jobs belonging to the same resource group are enqueued simultaneously,
+only one of the jobs is picked by the runner. The other jobs wait until the
+`resource_group` is free.
+
+For example:
+
+```yaml
+deploy-to-production:
+ script: deploy
+ resource_group: production
+```
+
+In this case, two `deploy-to-production` jobs in two separate pipelines can never run at the same time. As a result,
+you can ensure that concurrent deployments never happen to the production environment.
+
+You can define multiple resource groups per environment. For example,
+when deploying to physical devices, you may have multiple physical devices. Each device
+can be deployed to, but there can be only one deployment per device at any given time.
+
+The `resource_group` value can only contain letters, digits, `-`, `_`, `/`, `$`, `{`, `}`, `.`, and spaces.
+It can't start or end with `/`.
+
+For more information, see [Deployments Safety](../environments/deployment_safety.md).
+
+#### Pipeline-level concurrency control with Cross-Project/Parent-Child pipelines
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/39057) in GitLab 13.9.
+
+You can define `resource_group` for downstream pipelines that are sensitive to concurrent
+executions. The [`trigger` keyword](#trigger) can trigger downstream pipelines. The
+[`resource_group` keyword](#resource_group) can co-exist with it. This is useful to control the
+concurrency for deployment pipelines, while running non-sensitive jobs concurrently.
+
+The following example has two pipeline configurations in a project. When a pipeline starts running,
+non-sensitive jobs are executed first and aren't affected by concurrent executions in other
+pipelines. However, GitLab ensures that there are no other deployment pipelines running before
+triggering a deployment (child) pipeline. If other deployment pipelines are running, GitLab waits
+until those pipelines finish before running another one.
+
+```yaml
+# .gitlab-ci.yml (parent pipeline)
+
+build:
+ stage: build
+ script: echo "Building..."
+
+test:
+ stage: test
+ script: echo "Testing..."
+
+deploy:
+ stage: deploy
+ trigger:
+ include: deploy.gitlab-ci.yml
+ strategy: depend
+ resource_group: AWS-production
+```
+
+```yaml
+# deploy.gitlab-ci.yml (child pipeline)
+
+stages:
+ - provision
+ - deploy
+
+provision:
+ stage: provision
+ script: echo "Provisioning..."
+
+deployment:
+ stage: deploy
+ script: echo "Deploying..."
+```
+
+You must define [`strategy: depend`](#linking-pipelines-with-triggerstrategy)
+with the `trigger` keyword. This ensures that the lock isn't released until the downstream pipeline
+finishes.
+
+### `release`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/19298) in GitLab 13.2.
+
+Use `release` to create a [release](../../user/project/releases/index.md).
+Requires the [`release-cli`](https://gitlab.com/gitlab-org/release-cli/-/tree/master/docs)
+to be available in your GitLab Runner Docker or shell executor.
+
+These keywords are supported:
+
+- [`tag_name`](#releasetag_name)
+- [`description`](#releasedescription)
+- [`name`](#releasename) (optional)
+- [`ref`](#releaseref) (optional)
+- [`milestones`](#releasemilestones) (optional)
+- [`released_at`](#releasereleased_at) (optional)
+- [`assets:links`](#releaseassetslinks) (optional)
+
+The release is created only if the job processes without error. If the Rails API
+returns an error during release creation, the `release` job fails.
+
+#### `release-cli` Docker image
+
+You must specify the Docker image to use for the `release-cli`:
+
+```yaml
+image: registry.gitlab.com/gitlab-org/release-cli:latest
+```
+
+#### `release-cli` for shell executors
+
+> [Introduced](https://gitlab.com/gitlab-org/release-cli/-/issues/21) in GitLab 13.8.
+
+For GitLab Runner shell executors, you can download and install the `release-cli` manually for your [supported OS and architecture](https://release-cli-downloads.s3.amazonaws.com/latest/index.html).
+Once installed, the `release` keyword should be available to you.
+
+**Install on Unix/Linux**
+
+1. Download the binary for your system, in the following example for amd64 systems:
+
+ ```shell
+ curl --location --output /usr/local/bin/release-cli "https://release-cli-downloads.s3.amazonaws.com/latest/release-cli-linux-amd64"
+ ```
+
+1. Give it permissions to execute:
+
+ ```shell
+ sudo chmod +x /usr/local/bin/release-cli
+ ```
+
+1. Verify `release-cli` is available:
+
+ ```shell
+ $ release-cli -v
+
+ release-cli version 0.6.0
+ ```
+
+**Install on Windows PowerShell**
+
+1. Create a folder somewhere in your system, for example `C:\GitLab\Release-CLI\bin`
+
+ ```shell
+ New-Item -Path 'C:\GitLab\Release-CLI\bin' -ItemType Directory
+ ```
+
+1. Download the executable file:
+
+ ```shell
+ PS C:\> Invoke-WebRequest -Uri "https://release-cli-downloads.s3.amazonaws.com/latest/release-cli-windows-amd64.exe" -OutFile "C:\GitLab\Release-CLI\bin\release-cli.exe"
+
+ Directory: C:\GitLab\Release-CLI
+ Mode LastWriteTime Length Name
+ ---- ------------- ------ ----
+ d----- 3/16/2021 4:17 AM bin
+
+ ```
+
+1. Add the directory to your `$env:PATH`:
+
+ ```shell
+ $env:PATH += ";C:\GitLab\Release-CLI\bin"
+ ```
+
+1. Verify `release-cli` is available:
+
+ ```shell
+ PS C:\> release-cli -v
+
+ release-cli version 0.6.0
+ ```
+
+#### Use a custom SSL CA certificate authority
+
+You can use the `ADDITIONAL_CA_CERT_BUNDLE` CI/CD variable to configure a custom SSL CA certificate authority,
+which is used to verify the peer when the `release-cli` creates a release through the API using HTTPS with custom certificates.
+The `ADDITIONAL_CA_CERT_BUNDLE` value should contain the
+[text representation of the X.509 PEM public-key certificate](https://tools.ietf.org/html/rfc7468#section-5.1)
+or the `path/to/file` containing the certificate authority.
+For example, to configure this value in the `.gitlab-ci.yml` file, use the following:
+
+```yaml
+release:
+ variables:
+ ADDITIONAL_CA_CERT_BUNDLE: |
+ -----BEGIN CERTIFICATE-----
+ MIIGqTCCBJGgAwIBAgIQI7AVxxVwg2kch4d56XNdDjANBgkqhkiG9w0BAQsFADCB
+ ...
+ jWgmPqF3vUbZE0EyScetPJquRFRKIesyJuBFMAs=
+ -----END CERTIFICATE-----
+ script:
+ - echo "Create release"
+ release:
+ name: 'My awesome release'
+ tag_name: '$CI_COMMIT_TAG'
+```
+
+The `ADDITIONAL_CA_CERT_BUNDLE` value can also be configured as a
+[custom variable in the UI](../variables/index.md#custom-cicd-variables),
+either as a `file`, which requires the path to the certificate, or as a variable,
+which requires the text representation of the certificate.
+
+#### `script`
+
+All jobs except [trigger](#trigger) jobs must have the `script` keyword. A `release`
+job can use the output from script commands, but you can use a placeholder script if
+the script is not needed:
+
+```yaml
+script:
+ - echo 'release job'
+```
+
+An [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/223856) exists to remove this requirement in an upcoming version of GitLab.
+
+A pipeline can have multiple `release` jobs, for example:
+
+```yaml
+ios-release:
+ script:
+ - echo 'iOS release job'
+ release:
+ tag_name: v1.0.0-ios
+ description: 'iOS release v1.0.0'
+
+android-release:
+ script:
+ - echo 'Android release job'
+ release:
+ tag_name: v1.0.0-android
+ description: 'Android release v1.0.0'
+```
+
+#### `release:tag_name`
+
+You must specify a `tag_name` for the release. The tag can refer to an existing Git tag or
+you can specify a new tag.
+
+When the specified tag doesn't exist in the repository, a new tag is created from the associated SHA of the pipeline.
+
+For example, when creating a release from a Git tag:
+
+```yaml
+job:
+ release:
+ tag_name: $CI_COMMIT_TAG
+ description: 'Release description'
+```
+
+It is also possible for the release job to automatically create a new unique tag. In that case,
+do not use [`rules`](#rules) or [`only`](#only--except) to configure the job to
+only run for tags.
+
+A semantic versioning example:
+
+```yaml
+job:
+ release:
+ tag_name: ${MAJOR}_${MINOR}_${REVISION}
+ description: 'Release description'
+```
+
+- The release is created only if the job's main script succeeds.
+- If the release already exists, it is not updated and the job with the `release` keyword fails.
+- The `release` section executes after the `script` tag and before the `after_script`.
+
+#### `release:name`
+
+The release name. If omitted, it is populated with the value of `release: tag_name`.
+
+#### `release:description`
+
+Specifies the long description of the release. You can also specify a file that contains the
+description.
+
+##### Read description from a file
+
+> [Introduced](https://gitlab.com/gitlab-org/release-cli/-/merge_requests/67) in GitLab 13.7.
+
+You can specify a file in `$CI_PROJECT_DIR` that contains the description. The file must be relative
+to the project directory (`$CI_PROJECT_DIR`), and if the file is a symbolic link it can't reside
+outside of `$CI_PROJECT_DIR`. The `./path/to/file` and filename can't contain spaces.
+
+```yaml
+job:
+ release:
+ tag_name: ${MAJOR}_${MINOR}_${REVISION}
+ description: './path/to/CHANGELOG.md'
+```
+
+#### `release:ref`
+
+If the `release: tag_name` doesn't exist yet, the release is created from `ref`.
+`ref` can be a commit SHA, another tag name, or a branch name.
+
+#### `release:milestones`
+
+The title of each milestone the release is associated with.
+
+#### `release:released_at`
+
+The date and time when the release is ready. Defaults to the current date and time if not
+defined. Should be enclosed in quotes and expressed in ISO 8601 format.
+
+```json
+released_at: '2021-03-15T08:00:00Z'
+```
+
+#### `release:assets:links`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/271454) in GitLab 13.12.
+
+Include [asset links](../../user/project/releases/index.md#release-assets) in the release.
+
+NOTE:
+Requires `release-cli` version v0.4.0 or higher.
+
+```yaml
+assets:
+ links:
+ - name: 'asset1'
+ url: 'https://example.com/assets/1'
+ - name: 'asset2'
+ url: 'https://example.com/assets/2'
+ filepath: '/pretty/url/1' # optional
+ link_type: 'other' # optional
+```
+
+#### Complete example for `release`
+
+If you combine the previous examples for `release`, you get two options, depending on how you generate the
+tags. You can't use these options together, so choose one:
+
+- To create a release when you push a Git tag, or when you add a Git tag
+ in the UI by going to **Repository > Tags**:
+
+ ```yaml
+ release_job:
+ stage: release
+ image: registry.gitlab.com/gitlab-org/release-cli:latest
+ rules:
+ - if: $CI_COMMIT_TAG # Run this job when a tag is created manually
+ script:
+ - echo 'running release_job'
+ release:
+ name: 'Release $CI_COMMIT_TAG'
+ description: 'Created using the release-cli $EXTRA_DESCRIPTION' # $EXTRA_DESCRIPTION must be defined
+ tag_name: '$CI_COMMIT_TAG' # elsewhere in the pipeline.
+ ref: '$CI_COMMIT_TAG'
+ milestones:
+ - 'm1'
+ - 'm2'
+ - 'm3'
+ released_at: '2020-07-15T08:00:00Z' # Optional, is auto generated if not defined, or can use a variable.
+ assets: # Optional, multiple asset links
+ links:
+ - name: 'asset1'
+ url: 'https://example.com/assets/1'
+ - name: 'asset2'
+ url: 'https://example.com/assets/2'
+ filepath: '/pretty/url/1' # optional
+ link_type: 'other' # optional
+ ```
+
+- To create a release automatically when commits are pushed or merged to the default branch,
+ using a new Git tag that is defined with variables:
+
+ NOTE:
+ Environment variables set in `before_script` or `script` are not available for expanding
+ in the same job. Read more about
+ [potentially making variables available for expanding](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/6400).
+
+ ```yaml
+ prepare_job:
+ stage: prepare # This stage must run before the release stage
+ rules:
+ - if: $CI_COMMIT_TAG
+ when: never # Do not run this job when a tag is created manually
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch
+ script:
+ - echo "EXTRA_DESCRIPTION=some message" >> variables.env # Generate the EXTRA_DESCRIPTION and TAG environment variables
+ - echo "TAG=v$(cat VERSION)" >> variables.env # and append to the variables.env file
+ artifacts:
+ reports:
+ dotenv: variables.env # Use artifacts:reports:dotenv to expose the variables to other jobs
+
+ release_job:
+ stage: release
+ image: registry.gitlab.com/gitlab-org/release-cli:latest
+ needs:
+ - job: prepare_job
+ artifacts: true
+ rules:
+ - if: $CI_COMMIT_TAG
+ when: never # Do not run this job when a tag is created manually
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch
+ script:
+ - echo 'running release_job for $TAG'
+ release:
+ name: 'Release $TAG'
+ description: 'Created using the release-cli $EXTRA_DESCRIPTION' # $EXTRA_DESCRIPTION and the $TAG
+ tag_name: '$TAG' # variables must be defined elsewhere
+ ref: '$CI_COMMIT_SHA' # in the pipeline. For example, in the
+ milestones: # prepare_job
+ - 'm1'
+ - 'm2'
+ - 'm3'
+ released_at: '2020-07-15T08:00:00Z' # Optional, is auto generated if not defined, or can use a variable.
+ assets:
+ links:
+ - name: 'asset1'
+ url: 'https://example.com/assets/1'
+ - name: 'asset2'
+ url: 'https://example.com/assets/2'
+ filepath: '/pretty/url/1' # optional
+ link_type: 'other' # optional
+ ```
+
+#### Release assets as Generic packages
+
+You can use [Generic packages](../../user/packages/generic_packages/) to host your release assets.
+For a complete example, see the [Release assets as Generic packages](https://gitlab.com/gitlab-org/release-cli/-/tree/master/docs/examples/release-assets-as-generic-package/)
+project.
+
+#### `release-cli` command line
+
+The entries under the `release` node are transformed into a `bash` command line and sent
+to the Docker container, which contains the [release-cli](https://gitlab.com/gitlab-org/release-cli).
+You can also call the `release-cli` directly from a `script` entry.
+
+For example, if you use the YAML described previously:
+
+```shell
+release-cli create --name "Release $CI_COMMIT_SHA" --description "Created using the release-cli $EXTRA_DESCRIPTION" --tag-name "v${MAJOR}.${MINOR}.${REVISION}" --ref "$CI_COMMIT_SHA" --released-at "2020-07-15T08:00:00Z" --milestone "m1" --milestone "m2" --milestone "m3" --assets-link "{\"name\":\"asset1\",\"url\":\"https://example.com/assets/1\",\"link_type\":\"other\"}
+```
+
+### `secrets`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33014) in GitLab 13.4.
+
+Use `secrets` to specify the [CI/CD Secrets](../secrets/index.md) the job needs. It should be a hash,
+and the keys should be the names of the variables that are made available to the job.
+The value of each secret is saved in a temporary file. This file's path is stored in these
+variables.
+
+#### `secrets:vault` **(PREMIUM)**
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/28321) in GitLab 13.4 and GitLab Runner 13.4.
+
+Use `vault` to specify secrets provided by [Hashicorp's Vault](https://www.vaultproject.io/).
+
+This syntax has multiple forms. The shortest form assumes the use of the
+[KV-V2](https://www.vaultproject.io/docs/secrets/kv/kv-v2) secrets engine,
+mounted at the default path `kv-v2`. The last part of the secret's path is the
+field to fetch the value for:
+
+```yaml
+job:
+ secrets:
+ DATABASE_PASSWORD:
+ vault: production/db/password # translates to secret `kv-v2/data/production/db`, field `password`
+```
+
+You can specify a custom secrets engine path by adding a suffix starting with `@`:
+
+```yaml
+job:
+ secrets:
+ DATABASE_PASSWORD:
+ vault: production/db/password@ops # translates to secret `ops/data/production/db`, field `password`
+```
+
+In the detailed form of the syntax, you can specify all details explicitly:
+
+```yaml
+job:
+ secrets:
+ DATABASE_PASSWORD: # translates to secret `ops/data/production/db`, field `password`
+ vault:
+ engine:
+ name: kv-v2
+ path: ops
+ path: production/db
+ field: password
+```
+
+#### `secrets:file` **(PREMIUM)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/250695) in GitLab 14.1 and GitLab Runner 14.1.
+
+By default, the secret is passed to the job context as a variable of type
+[`file`](../variables/index.md#cicd-variable-types). The value of the
+secret is stored in a file and the variable `DATABASE_PASSWORD` contains a path to the file.
+
+However, some software does not work with file variables and might require the secret value to be stored
+directly in the environment variable. For that case, define a `file` setting:
+
+```yaml
+job:
+ secrets:
+ DATABASE_PASSWORD:
+ vault: production/db/password@ops
+ file: false
+```
+
+When you set `file: false`, no files are created for that variable. It contains the secret
+itself instead.
+
+The `file` is a setting of the secret, so it belongs directly under the variable
+name level and not in the `vault` section.
+
+### `pages`
+
+Use `pages` to upload static content to GitLab. The content
+is then published as a website. You must:
+
+- Place any static content in a `public/` directory.
+- Define [`artifacts`](#artifacts) with a path to the `public/` directory.
+
+The following example moves all files from the root of the project to the
+`public/` directory. The `.public` workaround is so `cp` does not also copy
+`public/` to itself in an infinite loop:
+
+```yaml
+pages:
+ stage: deploy
+ script:
+ - mkdir .public
+ - cp -r * .public
+ - mv .public public
+ artifacts:
+ paths:
+ - public
+ rules:
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
+```
+
+View the [GitLab Pages user documentation](../../user/project/pages/index.md).
+
+### `inherit`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207484) in GitLab 12.9.
+
+Use `inherit:` to control inheritance of globally-defined defaults
+and variables.
+
+To enable or disable the inheritance of all `default:` or `variables:` keywords, use:
+
+- `default: true` or `default: false`
+- `variables: true` or `variables: false`
+
+To inherit only a subset of `default:` keywords or `variables:`, specify what
+you wish to inherit. Anything not listed is **not** inherited. Use
+one of the following formats:
+
+```yaml
+inherit:
+ default: [keyword1, keyword2]
+ variables: [VARIABLE1, VARIABLE2]
+```
+
+Or:
+
+```yaml
+inherit:
+ default:
+ - keyword1
+ - keyword2
+ variables:
+ - VARIABLE1
+ - VARIABLE2
+```
+
+In the following example:
+
+- `rubocop`:
+ - inherits: Nothing.
+- `rspec`:
+ - inherits: the default `image` and the `WEBHOOK_URL` variable.
+ - does **not** inherit: the default `before_script` and the `DOMAIN` variable.
+- `capybara`:
+ - inherits: the default `before_script` and `image`.
+ - does **not** inherit: the `DOMAIN` and `WEBHOOK_URL` variables.
+- `karma`:
+ - inherits: the default `image` and `before_script`, and the `DOMAIN` variable.
+ - does **not** inherit: `WEBHOOK_URL` variable.
+
+```yaml
+default:
+ image: 'ruby:2.4'
+ before_script:
+ - echo Hello World
+
+variables:
+ DOMAIN: example.com
+ WEBHOOK_URL: https://my-webhook.example.com
+
+rubocop:
+ inherit:
+ default: false
+ variables: false
+ script: bundle exec rubocop
+
+rspec:
+ inherit:
+ default: [image]
+ variables: [WEBHOOK_URL]
+ script: bundle exec rspec
+
+capybara:
+ inherit:
+ variables: false
+ script: bundle exec capybara
+
+karma:
+ inherit:
+ default: true
+ variables: [DOMAIN]
+ script: karma
+```
+
+## `variables`
+
+> Introduced in GitLab Runner v0.5.0.
+
+[CI/CD variables](../variables/index.md) are configurable values that are passed to jobs.
+They can be set globally and per-job.
+
+There are two types of variables.
+
+- [Custom variables](../variables/index.md#custom-cicd-variables):
+ You can define their values in the `.gitlab-ci.yml` file, in the GitLab UI,
+ or by using the API. You can also input variables in the GitLab UI when
+ [running a pipeline manually](../pipelines/index.md#run-a-pipeline-manually).
+- [Predefined variables](../variables/predefined_variables.md):
+ These values are set by the runner itself.
+ One example is `CI_COMMIT_REF_NAME`, which is the branch or tag the project is built for.
+
+After you define a variable, you can use it in all executed commands and scripts.
+
+Variables are meant for non-sensitive project configuration, for example:
+
+```yaml
+variables:
+ DEPLOY_SITE: "https://example.com/"
+
+deploy_job:
+ stage: deploy
+ script:
+ - deploy-script --url $DEPLOY_SITE --path "/"
+
+deploy_review_job:
+ stage: deploy
+ variables:
+ REVIEW_PATH: "/review"
+ script:
+ - deploy-review-script --url $DEPLOY_SITE --path $REVIEW_PATH
+```
+
+You can use only integers and strings for the variable's name and value.
+
+If you define a variable at the top level of the `gitlab-ci.yml` file, it is global,
+meaning it applies to all jobs. If you define a variable in a job, it's available
+to that job only.
+
+If a variable of the same name is defined globally and for a specific job, the
+[job-specific variable overrides the global variable](../variables/index.md#cicd-variable-precedence).
+
+All YAML-defined variables are also set to any linked
+[Docker service containers](../services/index.md).
+
+You can use [YAML anchors for variables](#yaml-anchors-for-variables).
+
+### Prefill variables in manual pipelines
+
+> [Introduced in](https://gitlab.com/gitlab-org/gitlab/-/issues/30101) GitLab 13.7.
+
+Use the `value` and `description` keywords to define [pipeline-level (global) variables that are prefilled](../pipelines/index.md#prefill-variables-in-manual-pipelines)
+when [running a pipeline manually](../pipelines/index.md#run-a-pipeline-manually):
+
+```yaml
+variables:
+ DEPLOY_ENVIRONMENT:
+ value: "staging" # Deploy to staging by default
+ description: "The deployment target. Change this variable to 'canary' or 'production' if needed."
+```
+
+You cannot set job-level variables to be pre-filled when you run a pipeline manually.
+
+### Configure runner behavior with variables
+
+You can use [CI/CD variables](../variables/index.md) to configure how the runner processes Git requests:
+
+- [`GIT_STRATEGY`](../runners/configure_runners.md#git-strategy)
+- [`GIT_SUBMODULE_STRATEGY`](../runners/configure_runners.md#git-submodule-strategy)
+- [`GIT_CHECKOUT`](../runners/configure_runners.md#git-checkout)
+- [`GIT_CLEAN_FLAGS`](../runners/configure_runners.md#git-clean-flags)
+- [`GIT_FETCH_EXTRA_FLAGS`](../runners/configure_runners.md#git-fetch-extra-flags)
+- [`GIT_DEPTH`](../runners/configure_runners.md#shallow-cloning) (shallow cloning)
+- [`GIT_CLONE_PATH`](../runners/configure_runners.md#custom-build-directories) (custom build directories)
+- [`TRANSFER_METER_FREQUENCY`](../runners/configure_runners.md#artifact-and-cache-settings) (artifact/cache meter update frequency)
+- [`ARTIFACT_COMPRESSION_LEVEL`](../runners/configure_runners.md#artifact-and-cache-settings) (artifact archiver compression level)
+- [`CACHE_COMPRESSION_LEVEL`](../runners/configure_runners.md#artifact-and-cache-settings) (cache archiver compression level)
+
+You can also use variables to configure how many times a runner
+[attempts certain stages of job execution](../runners/configure_runners.md#job-stages-attempts).
+
+## `dast_configuration` **(ULTIMATE)**
+
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5981) in GitLab 14.1.
+
+Use the `dast_configuration` keyword to specify a site profile and scanner profile to be used in a
+CI/CD configuration. Both profiles must first have been created in the project. The job's stage must
+be `dast`.
+
+**Keyword type**: Job keyword. You can use only as part of a job.
+
+**Possible inputs**: One each of `site_profile` and `scanner_profile`.
+
+- Use `site_profile` to specify the site profile to be used in the job.
+- Use `scanner_profile` to specify the scanner profile to be used in the job.
+
+**Example of `dast_configuration`**:
+
+```yaml
+stages:
+ - build
+ - dast
+
+include:
+ - template: DAST.gitlab-ci.yml
+
+dast:
+ dast_configuration:
+ site_profile: "Example Co"
+ scanner_profile: "Quick Passive Test"
+```
+
+In this example, the `dast` job extends the `dast` configuration added with the `include:` keyword
+to select a specific site profile and scanner profile.
+
+**Additional details**:
+
+- Settings contained in either a site profile or scanner profile take precedence over those
+ contained in the DAST template.
+
+**Related topics**:
+
+- [Site profile](../../user/application_security/dast/index.md#site-profile).
+- [Scanner profile](../../user/application_security/dast/index.md#scanner-profile).
+
+## YAML-specific features
+
+In your `.gitlab-ci.yml` file, you can use YAML-specific features like anchors (`&`), aliases (`*`),
+and map merging (`<<`). Use these features to reduce the complexity
+of the code in the `.gitlab-ci.yml` file.
+
+Read more about the various [YAML features](https://learnxinyminutes.com/docs/yaml/).
+
+In most cases, the [`extends` keyword](#extends) is more user friendly and you should
+use it when possible.
+
+You can use YAML anchors to merge YAML arrays.
+
+### Anchors
+
+YAML has a feature called 'anchors' that you can use to duplicate
+content across your document.
+
+Use anchors to duplicate or inherit properties. Use anchors with [hidden jobs](#hide-jobs)
+to provide templates for your jobs. When there are duplicate keys, GitLab
+performs a reverse deep merge based on the keys.
+
+You can't use YAML anchors across multiple files when using the [`include`](#include)
+keyword. Anchors are only valid in the file they were defined in. To reuse configuration
+from different YAML files, use [`!reference` tags](#reference-tags) or the
+[`extends` keyword](#extends).
+
+The following example uses anchors and map merging. It creates two jobs,
+`test1` and `test2`, that inherit the `.job_template` configuration, each
+with their own custom `script` defined:
+
+```yaml
+.job_template: &job_configuration # Hidden yaml configuration that defines an anchor named 'job_configuration'
+ image: ruby:2.6
+ services:
+ - postgres
+ - redis
+
+test1:
+ <<: *job_configuration # Merge the contents of the 'job_configuration' alias
+ script:
+ - test1 project
+
+test2:
+ <<: *job_configuration # Merge the contents of the 'job_configuration' alias
+ script:
+ - test2 project
+```
+
+`&` sets up the name of the anchor (`job_configuration`), `<<` means "merge the
+given hash into the current one," and `*` includes the named anchor
+(`job_configuration` again). The expanded version of this example is:
+
+```yaml
+.job_template:
+ image: ruby:2.6
+ services:
+ - postgres
+ - redis
+
+test1:
+ image: ruby:2.6
+ services:
+ - postgres
+ - redis
+ script:
+ - test1 project
+
+test2:
+ image: ruby:2.6
+ services:
+ - postgres
+ - redis
+ script:
+ - test2 project
+```
+
+You can use anchors to define two sets of services. For example, `test:postgres`
+and `test:mysql` share the `script` defined in `.job_template`, but use different
+`services`, defined in `.postgres_services` and `.mysql_services`:
+
+```yaml
+.job_template: &job_configuration
+ script:
+ - test project
+ tags:
+ - dev
+
+.postgres_services:
+ services: &postgres_configuration
+ - postgres
+ - ruby
+
+.mysql_services:
+ services: &mysql_configuration
+ - mysql
+ - ruby
+
+test:postgres:
+ <<: *job_configuration
+ services: *postgres_configuration
+ tags:
+ - postgres
+
+test:mysql:
+ <<: *job_configuration
+ services: *mysql_configuration
+```
+
+The expanded version is:
+
+```yaml
+.job_template:
+ script:
+ - test project
+ tags:
+ - dev
+
+.postgres_services:
+ services:
+ - postgres
+ - ruby
+
+.mysql_services:
+ services:
+ - mysql
+ - ruby
+
+test:postgres:
+ script:
+ - test project
+ services:
+ - postgres
+ - ruby
+ tags:
+ - postgres
+
+test:mysql:
+ script:
+ - test project
+ services:
+ - mysql
+ - ruby
+ tags:
+ - dev
+```
+
+You can see that the hidden jobs are conveniently used as templates, and
+`tags: [postgres]` overwrites `tags: [dev]`.
+
+#### YAML anchors for scripts
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23005) in GitLab 12.5.
+
+You can use [YAML anchors](#anchors) with [script](#script), [`before_script`](#before_script),
+and [`after_script`](#after_script) to use predefined commands in multiple jobs:
+
+```yaml
+.some-script-before: &some-script-before
+ - echo "Execute this script first"
+
+.some-script: &some-script
+ - echo "Execute this script second"
+ - echo "Execute this script too"
+
+.some-script-after: &some-script-after
+ - echo "Execute this script last"
+
+job1:
+ before_script:
+ - *some-script-before
+ script:
+ - *some-script
+ - echo "Execute something, for this job only"
+ after_script:
+ - *some-script-after
+
+job2:
+ script:
+ - *some-script-before
+ - *some-script
+ - echo "Execute something else, for this job only"
+ - *some-script-after
+```
+
+#### YAML anchors for variables
+
+Use [YAML anchors](#anchors) with `variables` to repeat assignment
+of variables across multiple jobs. You can also use YAML anchors when a job
+requires a specific `variables` block that would otherwise override the global variables.
+
+The following example shows how override the `GIT_STRATEGY` variable without affecting
+the use of the `SAMPLE_VARIABLE` variable:
+
+```yaml
+# global variables
+variables: &global-variables
+ SAMPLE_VARIABLE: sample_variable_value
+ ANOTHER_SAMPLE_VARIABLE: another_sample_variable_value
+
+# a job that must set the GIT_STRATEGY variable, yet depend on global variables
+job_no_git_strategy:
+ stage: cleanup
+ variables:
+ <<: *global-variables
+ GIT_STRATEGY: none
+ script: echo $SAMPLE_VARIABLE
+```
+
+### Hide jobs
+
+If you want to temporarily disable a job, rather than commenting out all the
+lines where the job is defined:
+
+```yaml
+# hidden_job:
+# script:
+# - run test
+```
+
+Instead, you can start its name with a dot (`.`) and it is not processed by
+GitLab CI/CD. In the following example, `.hidden_job` is ignored:
+
+```yaml
+.hidden_job:
+ script:
+ - run test
+```
+
+Use this feature to ignore jobs, or use the
+[YAML-specific features](#yaml-specific-features) and transform the hidden jobs
+into templates.
+
+### `!reference` tags
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/266173) in GitLab 13.9.
+
+Use the `!reference` custom YAML tag to select keyword configuration from other job
+sections and reuse it in the current section. Unlike [YAML anchors](#anchors), you can
+use `!reference` tags to reuse configuration from [included](#include) configuration
+files as well.
+
+In the following example, a `script` and an `after_script` from two different locations are
+reused in the `test` job:
+
+- `setup.yml`:
+
+ ```yaml
+ .setup:
+ script:
+ - echo creating environment
+ ```
+
+- `.gitlab-ci.yml`:
+
+ ```yaml
+ include:
+ - local: setup.yml
+
+ .teardown:
+ after_script:
+ - echo deleting environment
+
+ test:
+ script:
+ - !reference [.setup, script]
+ - echo running my own command
+ after_script:
+ - !reference [.teardown, after_script]
+ ```
+
+In the following example, `test-vars-1` reuses all the variables in `.vars`, while `test-vars-2`
+selects a specific variable and reuses it as a new `MY_VAR` variable.
+
+```yaml
+.vars:
+ variables:
+ URL: "http://my-url.internal"
+ IMPORTANT_VAR: "the details"
+
+test-vars-1:
+ variables: !reference [.vars, variables]
+ script:
+ - printenv
+
+test-vars-2:
+ variables:
+ MY_VAR: !reference [.vars, variables, IMPORTANT_VAR]
+ script:
+ - printenv
+```
+
+You can't reuse a section that already includes a `!reference` tag. Only one level
+of nesting is supported.
+
+## Skip Pipeline
+
+To push a commit without triggering a pipeline, add `[ci skip]` or `[skip ci]`, using any
+capitalization, to your commit message.
+
+Alternatively, if you are using Git 2.10 or later, use the `ci.skip` [Git push option](../../user/project/push_options.md#push-options-for-gitlab-cicd).
+The `ci.skip` push option does not skip merge request
+pipelines.
+
+## Processing Git pushes
+
+GitLab creates at most four branch and tag pipelines when
+pushing multiple changes in a single `git push` invocation.
+
+This limitation does not affect any of the updated merge request pipelines.
+All updated merge requests have a pipeline created when using
+[pipelines for merge requests](../pipelines/merge_request_pipelines.md).
+
+## Deprecated keywords
+
+The following keywords are deprecated.
+
+### Globally-defined `types`
+
+WARNING:
+`types` is deprecated, and could be removed in a future release.
+Use [`stages`](#stages) instead.
+
+### Job-defined `type`
+
+WARNING:
+`type` is deprecated, and could be removed in one of the future releases.
+Use [`stage`](#stage) instead.
+
+### Globally-defined `image`, `services`, `cache`, `before_script`, `after_script`
+
+Defining `image`, `services`, `cache`, `before_script`, and
+`after_script` globally is deprecated. Support could be removed
+from a future release.
+
+Use [`default:`](#custom-default-keyword-values) instead. For example:
+
+```yaml
+default:
+ image: ruby:3.0
+ services:
+ - docker:dind
+ cache:
+ paths: [vendor/]
+ before_script:
+ - bundle config set path vendor/bundle
+ - bundle install
+ after_script:
+ - rm -rf tmp/
+```
+
+<!-- ## Troubleshooting
+
+Include any troubleshooting steps that you can foresee. If you know beforehand what issues
+one might have when setting this up, or when something is changed, or on upgrading, it's
+important to describe those, too. Think of things that may go wrong and include them here.
+This is important to minimize requests for support, and to avoid doc comments with
+questions that you know someone might ask.
+
+Each scenario can be a third-level heading, e.g. `### Getting error message X`.
+If you have none to add when creating a doc, leave this section in place
+but commented out to help encourage others to add to it in the future. -->
diff --git a/doc/ci/yaml/script.md b/doc/ci/yaml/script.md
index 2e5517f6190..9e118895d7c 100644
--- a/doc/ci/yaml/script.md
+++ b/doc/ci/yaml/script.md
@@ -5,9 +5,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference
---
-# GitLab CI/CD script syntax
+# GitLab CI/CD script syntax **(FREE)**
-You can use special syntax in [`script`](README.md#script) sections to:
+You can use special syntax in [`script`](index.md#script) sections to:
- [Split long commands](#split-long-commands) into multiline commands.
- [Use color codes](#add-color-codes-to-script-output) to make job logs easier to review.
@@ -121,7 +121,7 @@ job:
- echo -e "\e[31mThis text is red,\e[0m but this text isn't\e[31m however this text is red again."
```
-You can define the color codes in Shell environment variables, or even [custom CI/CD variables](../variables/README.md#custom-cicd-variables),
+You can define the color codes in Shell environment variables, or even [custom CI/CD variables](../variables/index.md#custom-cicd-variables),
which makes the commands easier to read and reusable.
For example, using the same example as above and environment variables defined in a `before_script`: