summaryrefslogtreecommitdiff
path: root/doc/ci/yaml
diff options
context:
space:
mode:
Diffstat (limited to 'doc/ci/yaml')
-rw-r--r--doc/ci/yaml/artifacts_reports.md4
-rw-r--r--doc/ci/yaml/includes.md110
-rw-r--r--doc/ci/yaml/index.md97
-rw-r--r--doc/ci/yaml/script.md58
-rw-r--r--doc/ci/yaml/yaml_optimization.md51
5 files changed, 219 insertions, 101 deletions
diff --git a/doc/ci/yaml/artifacts_reports.md b/doc/ci/yaml/artifacts_reports.md
index e12786f06ce..38b0ab1f0a3 100644
--- a/doc/ci/yaml/artifacts_reports.md
+++ b/doc/ci/yaml/artifacts_reports.md
@@ -115,8 +115,8 @@ collected code quality report uploads to GitLab as an artifact.
GitLab can display the results of one or more reports in:
-- The merge request [code quality widget](../testing/code_quality.md#code-quality-widget).
-- The merge request [diff annotations](../testing/code_quality.md#code-quality-in-diff-view).
+- The merge request [code quality widget](../testing/code_quality.md#merge-request-widget).
+- The merge request [diff annotations](../testing/code_quality.md#merge-request-changes-view).
- The [full report](../testing/metrics_reports.md).
## `artifacts:reports:container_scanning` **(ULTIMATE)**
diff --git a/doc/ci/yaml/includes.md b/doc/ci/yaml/includes.md
index daf2e653250..b1f43a4679b 100644
--- a/doc/ci/yaml/includes.md
+++ b/doc/ci/yaml/includes.md
@@ -56,7 +56,7 @@ You can include an array of configuration files:
- template: Auto-DevOps.gitlab-ci.yml
```
-- You can define an array that combines both default and specific `include` type:
+- You can define an array that combines both default and specific `include` types:
```yaml
include:
@@ -290,9 +290,9 @@ smoke-test-job:
In `include` sections in your `.gitlab-ci.yml` file, you can use:
-- [Project variables](../variables/index.md#add-a-cicd-variable-to-a-project).
-- [Group variables](../variables/index.md#add-a-cicd-variable-to-a-group).
-- [Instance variables](../variables/index.md#add-a-cicd-variable-to-an-instance).
+- [Project variables](../variables/index.md#for-a-project).
+- [Group variables](../variables/index.md#for-a-group).
+- [Instance variables](../variables/index.md#for-an-instance).
- Project [predefined variables](../variables/predefined_variables.md).
- In GitLab 14.2 and later, the `$CI_COMMIT_REF_NAME` [predefined variable](../variables/predefined_variables.md).
@@ -333,52 +333,82 @@ see this [CI/CD variable demo](https://youtu.be/4XR8gw3Pkos).
## Use `rules` with `include`
> - Introduced in GitLab 14.2 [with a flag](../../administration/feature_flags.md) named `ci_include_rules`. Disabled by default.
-> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/337507) in GitLab 14.3.
-> - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/337507) GitLab 14.3.
-> - [Feature flag `ci_include_rules` removed](https://gitlab.com/gitlab-org/gitlab/-/issues/337507) in GitLab 14.4.
-> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/337507) in GitLab 14.4.
+> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/337507) in GitLab 14.3.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/337507) in GitLab 14.4. Feature flag `ci_include_rules` removed.
> - [Support for `exists` keyword added](https://gitlab.com/gitlab-org/gitlab/-/issues/341511) in GitLab 14.5.
You can use [`rules`](index.md#rules) with `include` to conditionally include other configuration files.
-You can only use the following rules with `include` (and only with [certain variables](#use-variables-with-include)):
+You can only use `rules` with [certain variables](#use-variables-with-include), and
+these keywords:
-- [`if` rules](index.md#rulesif). For example:
+- [`rules:if`](index.md#rulesif).
+- [`rules:exists`](index.md#rulesexists).
- ```yaml
- include:
- - local: builds.yml
- rules:
- - if: $INCLUDE_BUILDS == "true"
- - local: deploys.yml
- rules:
- - if: $CI_COMMIT_BRANCH == "main"
-
- test:
- stage: test
- script: exit 0
- ```
+You cannot use [`needs:`](index.md#needs) to create a job dependency that points to
+a job added with `include:local:rules`. When the configuration is validated,
+GitLab returns `undefined need: <job-name>`. [Issue 345377](https://gitlab.com/gitlab-org/gitlab/-/issues/345377)
+proposes improving this behavior.
-- [`exists` rules](index.md#rulesexists). For example:
+### `include` with `rules:if`
- ```yaml
- include:
- - local: builds.yml
- rules:
- - exists:
- - file.md
-
- test:
- stage: test
- script: exit 0
- ```
+Use [`rules:if`](index.md#rulesif) to conditionally include other configuration files
+based on the status of CI/CD variables. For example:
-`rules` keyword `changes` is not supported.
+```yaml
+include:
+ - local: builds.yml
+ rules:
+ - if: $INCLUDE_BUILDS == "true"
+ - local: deploys.yml
+ rules:
+ - if: $CI_COMMIT_BRANCH == "main"
+
+test:
+ stage: test
+ script: exit 0
+```
-You cannot use [`needs:`](index.md#needs) to create a job dependency that points to
-a job added with `include:local:rules`. When the configuration is checked for validity,
-GitLab returns `undefined need: <job-name>`. An [issue exists](https://gitlab.com/gitlab-org/gitlab/-/issues/345377)
-to improve this behavior.
+### `include` with `rules:exists`
+
+Use [`rules:exists`](index.md#rulesexists) to conditionally include other configuration files
+based on the existence of files. For example:
+
+```yaml
+include:
+ - local: builds.yml
+ rules:
+ - exists:
+ - file.md
+
+test:
+ stage: test
+ script: exit 0
+```
+
+In this example, GitLab checks for the existence of `file.md` in the current project.
+
+There is a known issue if you configure `include` with `rules:exists` to add a configuration file
+from a different project. GitLab checks for the existence of the file in the _other_ project.
+For example:
+
+```yaml
+include:
+- project: my-group/my-project-2
+ ref: main
+ file: test-file.yml
+ rules:
+ - exists:
+ - file.md
+
+test:
+ stage: test
+ script: exit 0
+```
+
+In this example, GitLab checks for the existence of `test-file.yml` in `my-group/my-project-2`,
+not the current project. Follow [issue 386040](https://gitlab.com/gitlab-org/gitlab/-/issues/386040)
+for information about work to improve this behavior.
## Use `include:local` with wildcard file paths
diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md
index dffe409b193..3796eed54e1 100644
--- a/doc/ci/yaml/index.md
+++ b/doc/ci/yaml/index.md
@@ -171,7 +171,7 @@ the time limit to resolve all files is 30 seconds.
#### `include:local`
-Use `include:local` to include a file that is in the same repository as the `.gitlab-ci.yml` file.
+Use `include:local` to include a file that is in the same repository as the project running the pipeline.
Use `include:local` instead of symbolic links.
**Keyword type**: Global keyword.
@@ -397,10 +397,7 @@ Use [`workflow`](workflow.md) to control pipeline behavior.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/372538) in GitLab 15.5 [with a flag](../../administration/feature_flags.md) named `pipeline_name`. Disabled by default.
> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/376095) in GitLab 15.7.
-
-FLAG:
-On self-managed GitLab, by default this feature is available. To hide the feature,
-ask an administrator to [disable the feature flag](../../administration/feature_flags.md) named `pipeline_name`.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/376095) in GitLab 15.8. Feature flag `pipeline_name` removed.
You can use `name` in `workflow:` to define a name for pipelines.
@@ -669,6 +666,7 @@ In this example, `job1` and `job2` run in parallel:
**Additional details**:
- You can use `allow_failure` as a subkey of [`rules`](#rulesallow_failure).
+- If `allow_failure: true` is set, the job is always considered successful, and later jobs with [`when: on_failure`](#when) don't start if this job fails.
- You can use `allow_failure: false` with a manual job to create a [blocking manual job](../jobs/job_control.md#types-of-manual-jobs).
A blocked pipeline does not run any jobs in later stages until the manual job
is started and completes successfully.
@@ -1003,7 +1001,7 @@ rspec:
- Combining reports in parent pipelines using [artifacts from child pipelines](#needspipelinejob) is
not supported. Track progress on adding support in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/215725).
-- To be able to browse the report output files, include the [`artifacts:paths`](#artifactspaths) keyword. This will upload and store the artifact twice.
+- To be able to browse the report output files, include the [`artifacts:paths`](#artifactspaths) keyword. This uploads and stores the artifact twice.
- 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 artifacts reports.
@@ -1103,10 +1101,16 @@ job:
### `cache`
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/330047) in GitLab 15.0, caches are not shared between protected and unprotected branches.
+
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).
+Caches are:
+
+- Shared between pipelines and jobs.
+- By default, not shared between [protected](../../user/project/protected_branches.md) and unprotected branches.
+- Restored before [artifacts](#artifacts).
Learn more about caches in [Caching in GitLab CI/CD](../caching/index.md).
@@ -1142,6 +1146,10 @@ rspec:
- .config
```
+**Additional details**:
+
+- The `cache:paths` keyword includes files even if they are untracked or in your `.gitignore` file.
+
**Related topics**:
- See the [common `cache` use cases](../caching/index.md#common-use-cases-for-caches) for more
@@ -1289,6 +1297,11 @@ Untracked files include files that are:
- Ignored due to [`.gitignore` configuration](https://git-scm.com/docs/gitignore).
- Created, but not added to the checkout with [`git add`](https://git-scm.com/docs/git-add).
+Caching untracked files can create unexpectedly large caches if the job downloads:
+
+- Dependencies, like gems or node modules, which are usually untracked.
+- [Artifacts](#artifacts) from a different job. Files extracted from the artifacts are untracked by default.
+
**Keyword type**: Job keyword. You can use it only as part of a job or in the
[`default` section](#default).
@@ -1307,8 +1320,9 @@ rspec:
**Additional details**:
-- You can combine `cache:untracked` with `cache:paths` to cache all untracked files
- as well as files in the configured paths. This is useful for including files that are not tracked because of a `.gitignore` configuration. For example:
+- You can combine `cache:untracked` with `cache:paths` to cache all untracked files, as well as files in the configured paths.
+ Use `cache:paths` to cache any specific files, including tracked files, or files that are outside of the working directory,
+ and use `cache: untracked` to also cache all untracked files. For example:
```yaml
rspec:
@@ -1319,6 +1333,36 @@ rspec:
- binaries/
```
+ In this example, the job caches all untracked files in the repository, as well as all the files in `binaries/`.
+ If there are untracked files in `binaries/`, they are covered by both keywords.
+
+#### `cache:unprotect`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/362114) in GitLab 15.8.
+
+Use `cache:unprotect` to set a cache to be shared between [protected](../../user/project/protected_branches.md)
+and unprotected branches.
+
+WARNING:
+When set to `true`, users without access to protected branches can read and write to
+cache keys used by protected branches.
+
+**Keyword type**: Job keyword. You can use it only as part of a job or in the
+[`default` section](#default).
+
+**Possible inputs**:
+
+- `true` or `false` (default).
+
+**Example of `cache:untracked`**:
+
+```yaml
+rspec:
+ script: test
+ cache:
+ unprotect: true
+```
+
#### `cache:when`
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18969) in GitLab 13.5 and GitLab Runner v13.5.0.
@@ -2820,6 +2864,8 @@ You must:
### `parallel`
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/336576) in GitLab 15.9, the maximum value for `parallel` is increased from 50 to 200.
+
Use `parallel` to run a job multiple times in parallel in a single pipeline.
Multiple runners must exist, or a single runner must be configured to run multiple jobs concurrently.
@@ -2830,7 +2876,7 @@ Parallel jobs are named sequentially from `job_name 1/N` to `job_name N/N`.
**Possible inputs**:
-- A numeric value from `2` to `50`.
+- A numeric value from `2` to `200`.
**Example of `parallel`**:
@@ -2855,6 +2901,7 @@ This example creates 5 jobs that run in parallel, named `test 1/5` to `test 5/5`
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15356) in GitLab 13.3.
> - The job naming style was [improved in GitLab 13.4](https://gitlab.com/gitlab-org/gitlab/-/issues/230452).
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/336576) in GitLab 15.9, the maximum number of permutations is increased from 50 to 200.
Use `parallel:matrix` to run a job multiple times in parallel in a single pipeline,
but with different variable values for each instance of the job.
@@ -2867,7 +2914,7 @@ Multiple runners must exist, or a single runner must be configured to run multip
- The variable names can use only numbers, letters, and underscores (`_`).
- The values must be either a string, or an array of strings.
-- The number of permutations cannot exceed 50.
+- The number of permutations cannot exceed 200.
**Example of `parallel:matrix`**:
@@ -3242,7 +3289,9 @@ Use `retry:when` with `retry:max` to retry jobs for only specific failure cases.
- `always`: Retry on any failure (default).
- `unknown_failure`: Retry when the failure reason is unknown.
-- `script_failure`: Retry when the script failed.
+- `script_failure`: Retry when:
+ - The script failed.
+ - The runner failed to pull the Docker image. For `docker`, `docker+machine`, `kubernetes` [executors](https://docs.gitlab.com/runner/executors/).
- `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).
@@ -3332,8 +3381,8 @@ Use `rules:if` clauses to specify when to add a job to a 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), with
+`if` clauses are evaluated based on the values of [CI/CD variables](../variables/index.md)
+or [predefined CI/CD variables](../variables/predefined_variables.md), with
[some exceptions](../variables/where_variables_can_be_used.md#gitlab-ciyml-file).
**Keyword type**: Job-specific and pipeline-specific. You can use it as part of a job
@@ -3451,7 +3500,7 @@ any subkeys. All additional details and related topics are the same.
**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).
+- An array of file paths. [File paths can include variables](../jobs/job_control.md#variables-in-ruleschanges).
**Example of `rules:changes:paths`**:
@@ -3657,7 +3706,7 @@ Use `secrets` to specify [CI/CD secrets](../secrets/index.md) to:
- Retrieve from an external secrets provider.
- Make available in the job as [CI/CD variables](../variables/index.md)
- ([`file` type](../variables/index.md#cicd-variable-types) by default).
+ ([`file` type](../variables/index.md#use-file-type-cicd-variables) by default).
This keyword must be used with `secrets:vault`.
@@ -3716,7 +3765,7 @@ job:
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/250695) in GitLab 14.1 and GitLab Runner 14.1.
Use `secrets:file` to configure the secret to be stored as either a
-[`file` or `variable` type CI/CD variable](../variables/index.md#cicd-variable-types)
+[`file` or `variable` type CI/CD variable](../variables/index.md#use-file-type-cicd-variables)
By default, the secret is passed to the job as a `file` type CI/CD variable. The value
of the secret is stored in the file and the variable contains the path to the file.
@@ -4252,8 +4301,8 @@ child3:
### `variables`
-[CI/CD variables](../variables/index.md) are configurable values that are passed to jobs.
-Use `variables` to create [custom variables](../variables/index.md#custom-cicd-variables).
+Use `variables` to define [CI/CD variables](../variables/index.md#define-a-cicd-variable-in-the-gitlab-ciyml-file),
+which are configurable values that are passed to jobs.
Variables are always available in `script`, `before_script`, and `after_script` commands.
You can also use variables as inputs in some job keywords.
@@ -4298,7 +4347,7 @@ deploy_review_job:
- All YAML-defined variables are also set to any linked [Docker service containers](../services/index.md).
- YAML-defined variables are meant for non-sensitive project configuration. Store sensitive information
- in [protected variables](../variables/index.md#protected-cicd-variables) or [CI/CD secrets](../secrets/index.md).
+ in [protected variables](../variables/index.md#protect-a-cicd-variable) or [CI/CD secrets](../secrets/index.md).
- [Manual pipeline variables](../variables/index.md#override-a-defined-cicd-variable)
and [scheduled pipeline variables](../pipelines/schedules.md#add-a-pipeline-schedule)
are not passed to downstream pipelines by default. Use [trigger:forward](#triggerforward)
@@ -4306,7 +4355,6 @@ deploy_review_job:
**Related topics**:
-- You can use [YAML anchors for variables](yaml_optimization.md#yaml-anchors-for-variables).
- [Predefined variables](../variables/predefined_variables.md) are variables the runner
automatically creates and makes available in the job.
- You can [configure runner behavior with variables](../runners/configure_runners.md#configure-runner-behavior-with-variables).
@@ -4348,10 +4396,7 @@ variables:
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/353991) in GitLab 15.6 [with a flag](../../administration/feature_flags.md) named `ci_raw_variables_in_yaml_config`. Disabled by default.
> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/375034) in GitLab 15.6.
> - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/375034) in GitLab 15.7.
-
-FLAG:
-On self-managed GitLab, by default this feature is available. To hide the feature per project,
-ask an administrator to [disable the feature flag](../../administration/feature_flags.md) named `ci_raw_variables_in_yaml_config`.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/375034) in GitLab 15.8. Feature flag `ci_raw_variables_in_yaml_config` removed.
Use the `expand` keyword to configure a variable to be expandable or not.
@@ -4394,7 +4439,7 @@ the default value is `when: on_success`.
or have `allow_failure: true`.
- `manual`: Run the job only when [triggered manually](../jobs/job_control.md#create-a-job-that-must-be-run-manually).
- `always`: Run the job regardless of the status of jobs in earlier stages. Can also be used in `workflow:rules`.
-- `on_failure`: Run the job only when at least one job in an earlier stage fails.
+- `on_failure`: Run the job only when at least one job in an earlier stage fails. A job with `allow_failure: true` is always considered successful.
- `delayed`: [Delay the execution of a job](../jobs/job_control.md#run-a-job-after-a-delay)
for a specified duration.
- `never`: Don't run the job. Can only be used in a [`rules`](#rules) section or `workflow: rules`.
diff --git a/doc/ci/yaml/script.md b/doc/ci/yaml/script.md
index 1d3186a4047..1c31191c2f4 100644
--- a/doc/ci/yaml/script.md
+++ b/doc/ci/yaml/script.md
@@ -203,7 +203,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/index.md#custom-cicd-variables),
+You can define the color codes in Shell environment variables, or even [CI/CD variables](../variables/index.md#define-a-cicd-variable-in-the-gitlab-ciyml-file),
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`:
@@ -284,3 +284,59 @@ job-fails:
- (invalid-command xyz && invalid-command abc)
- echo "The job failed already, and this is not executed."
```
+
+### Multiline commands not preserved by folded YAML multiline block scalar
+
+If you use the `- >` folded YAML multiline block scalar to split long commands,
+additional indentation causes the lines to be processed as individual commands.
+
+For example:
+
+```yaml
+script:
+ - >
+ RESULT=$(curl --silent
+ --header
+ "Authorization: Bearer $CI_JOB_TOKEN"
+ "${CI_API_V4_URL}/job"
+ )
+```
+
+This fails as the indentation causes the line breaks to be preserved:
+
+<!-- vale gitlab.CurlStringsQuoted = NO -->
+
+```plaintext
+$ RESULT=$(curl --silent # collapsed multi-line command
+curl: no URL specified!
+curl: try 'curl --help' or 'curl --manual' for more information
+/bin/bash: line 149: --header: command not found
+/bin/bash: line 150: https://gitlab.example.com/api/v4/job: No such file or directory
+```
+
+<!-- vale gitlab.CurlStringsQuoted = YES -->
+
+Resolve this by either:
+
+- Removing the extra indentation:
+
+ ```yaml
+ script:
+ - >
+ RESULT=$(curl --silent
+ --header
+ "Authorization: Bearer $CI_JOB_TOKEN"
+ "${CI_API_V4_URL}/job"
+ )
+ ```
+
+- Modifying the script so the extra line breaks are handled, for example using shell line continuation:
+
+ ```yaml
+ script:
+ - >
+ RESULT=$(curl --silent \
+ --header \
+ "Authorization: Bearer $CI_JOB_TOKEN" \
+ "${CI_API_V4_URL}/job")
+ ```
diff --git a/doc/ci/yaml/yaml_optimization.md b/doc/ci/yaml/yaml_optimization.md
index 5344a999b95..07019a2776f 100644
--- a/doc/ci/yaml/yaml_optimization.md
+++ b/doc/ci/yaml/yaml_optimization.md
@@ -13,7 +13,7 @@ files by using:
- YAML-specific features like [anchors (`&`)](#anchors), aliases (`*`), and map merging (`<<`).
Read more about the various [YAML features](https://learnxinyminutes.com/docs/yaml/).
- The [`extends` keyword](#use-extends-to-reuse-configuration-sections),
- which is more flexible and readable. We recommend you use `extends` where possible.
+ which is more flexible and readable. You should use `extends` where possible.
## Anchors
@@ -21,10 +21,20 @@ 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](../jobs/index.md#hide-jobs)
-to provide templates for your jobs. When there are duplicate keys, GitLab
-performs a reverse deep merge based on the keys.
+to provide templates for your jobs. When there are duplicate keys, the latest included key wins, overriding the other keys.
-You can use YAML anchors to merge YAML arrays.
+In certain cases (see [YAML anchors for scripts](#yaml-anchors-for-scripts)), you can use YAML anchors to build arrays with multiple components defined elsewhere. For example:
+
+```yaml
+.default_scripts: &default_scripts
+ - ./default-script1.sh
+ - ./default-script2.sh
+
+job1:
+ script:
+ - *default_scripts
+ - ./job-script.sh
+```
You can't use YAML anchors across multiple files when using the [`include`](index.md#include)
keyword. Anchors are only valid in the file they were defined in. To reuse configuration
@@ -43,12 +53,12 @@ with their own custom `script` defined:
- redis
test1:
- <<: *job_configuration # Merge the contents of the 'job_configuration' alias
+ <<: *job_configuration # Add the contents of the 'job_configuration' alias
script:
- test1 project
test2:
- <<: *job_configuration # Merge the contents of the 'job_configuration' alias
+ <<: *job_configuration # Add the contents of the 'job_configuration' alias
script:
- test2 project
```
@@ -189,30 +199,6 @@ job2:
- *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
-```
-
## Use `extends` to reuse configuration sections
You can use the [`extends` keyword](index.md#extends) to reuse configuration in
@@ -331,8 +317,9 @@ to the contents of the `script`:
### 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
+The algorithm used for merge is "closest scope wins". When there are
+duplicate keys, GitLab performs a reverse deep merge based on the keys.
+Keys from the last member always override anything defined on other
levels. For example:
```yaml