From 73bb2548c0d2c6238774d4b4729b349f827c9134 Mon Sep 17 00:00:00 2001 From: Marcel Amirault <mamirault@gitlab.com> Date: Wed, 24 Aug 2022 10:05:15 +0000 Subject: [PATCH] Move information to downstream pipelines page Details that apply to both multi-project and parent-child pipelines can live on the downstream page. A very light copy edit and additional headers included as well, to make the content work a little better in the new place. Part of a larger issue to combine all downstream pipeline together. --- doc/ci/pipelines/downstream_pipelines.md | 163 +++++++++++++++++- .../img/downstream_pipeline_actions.png | Bin 13406 -> 0 bytes doc/ci/pipelines/multi_project_pipelines.md | 142 +-------------- doc/ci/pipelines/parent_child_pipelines.md | 21 +-- doc/ci/variables/index.md | 6 +- doc/ci/yaml/index.md | 2 +- 6 files changed, 170 insertions(+), 164 deletions(-) delete mode 100644 doc/ci/pipelines/img/downstream_pipeline_actions.png diff --git a/doc/ci/pipelines/downstream_pipelines.md b/doc/ci/pipelines/downstream_pipelines.md index 224b171625fc2..d92a632fce3ce 100644 --- a/doc/ci/pipelines/downstream_pipelines.md +++ b/doc/ci/pipelines/downstream_pipelines.md @@ -51,15 +51,162 @@ Multi-project pipelines: In the [pipeline graph view](index.md#view-full-pipeline-graph), downstream pipelines display as a list of cards on the right of the graph. -### Cancel or retry downstream pipelines from the graph view +### Retry a downstream pipeline -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/354974) in GitLab 15.0 [with a flag](../../administration/feature_flags.md) named `downstream_retry_action`. Disabled by default. -> - [Generally available and feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/357406) in GitLab 15.1. +> - Retry from graph view [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/354974) in GitLab 15.0 [with a flag](../../administration/feature_flags.md) named `downstream_retry_action`. Disabled by default. +> - Retry from graph view [generally available and feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/357406) in GitLab 15.1. -To cancel a downstream pipeline that is still running, select **Cancel** (**{cancel}**) -on the pipeline's card. +To retry a completed downstream pipeline, select **Retry** (**{retry}**): -To retry a failed downstream pipeline, select **Retry** (**{retry}**) -on the pipeline's card. +- From the downstream pipeline's details page. +- On the pipeline's card in the [pipeline graph view](index.md#view-full-pipeline-graph). - +### Cancel a downstream pipeline + +> - Retry from graph view [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/354974) in GitLab 15.0 [with a flag](../../administration/feature_flags.md) named `downstream_retry_action`. Disabled by default. +> - Retry from graph view [generally available and feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/357406) in GitLab 15.1. + +To cancel a downstream pipeline that is still running, select **Cancel** (**{cancel}**): + +- From the downstream pipeline's details page. +- On the pipeline's card in the [pipeline graph view](index.md#view-full-pipeline-graph). + +### Mirror the status of a downstream pipeline in the trigger job + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11238) in GitLab Premium 12.3. +> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/199224) to GitLab Free in 12.8. + +You can mirror the pipeline status from the triggered pipeline to the source trigger job +by using [`strategy: depend`](../yaml/index.md#triggerstrategy). For example: + +```yaml +trigger_job: + trigger: + project: my/project + strategy: depend +``` + +## Pass CI/CD variables to a downstream pipeline + +You can pass CI/CD variables to a downstream pipeline with a few different methods, +based on where the variable is created or defined. + +### Pass YAML-defined CI/CD variables + +You can use the `variables` keyword to pass CI/CD variables to a downstream pipeline, +just like you would for any other job. + +For example, in a [multi-project pipeline](multi_project_pipelines.md): + +```yaml +rspec: + stage: test + script: bundle exec rspec + +staging: + variables: + ENVIRONMENT: staging + stage: deploy + trigger: my/deployment +``` + +The `ENVIRONMENT` variable is passed to every job defined in a downstream +pipeline. It is available as a variable when GitLab Runner picks a job. + +In the following configuration, the `MY_VARIABLE` variable is passed to the downstream pipeline +that is created when the `trigger-downstream` job is queued. This is because `trigger-downstream` +job inherits variables declared in global variables blocks, and then we pass these variables to a downstream pipeline. + +```yaml +variables: + MY_VARIABLE: my-value + +trigger-downstream: + variables: + ENVIRONMENT: something + trigger: my/project +``` + +### Prevent global variables from being passed + +You can stop global variables from reaching the downstream pipeline by using the [`inherit:variables` keyword](../yaml/index.md#inheritvariables). +For example, in a [multi-project pipeline](multi_project_pipelines.md): + +```yaml +variables: + MY_GLOBAL_VAR: value + +trigger-downstream: + inherit: + variables: false + variables: + MY_LOCAL_VAR: value + trigger: my/project +``` + +In this example, the `MY_GLOBAL_VAR` variable is not available in the triggered pipeline. + +### Pass a predefined variable + +You might want to pass some information about the upstream pipeline using predefined variables. +To do that, you can use interpolation to pass any variable. For example, +in a [multi-project pipeline](multi_project_pipelines.md): + +```yaml +downstream-job: + variables: + UPSTREAM_BRANCH: $CI_COMMIT_REF_NAME + trigger: my/project +``` + +In this scenario, the `UPSTREAM_BRANCH` variable with the value of the upstream pipeline's +`$CI_COMMIT_REF_NAME` is passed to `downstream-job`. It is available in the +context of all downstream builds. + +You cannot use this method to forward [job-level persisted variables](../variables/where_variables_can_be_used.md#persisted-variables) +to a downstream pipeline, as they are not available in trigger jobs. + +Upstream pipelines take precedence over downstream ones. If there are two +variables with the same name defined in both upstream and downstream projects, +the ones defined in the upstream project take precedence. + +### Pass dotenv variables created in a job **(PREMIUM)** + +You can pass variables to a downstream pipeline with [`dotenv` variable inheritance](../variables/index.md#pass-an-environment-variable-to-another-job) +and [`needs:project`](../yaml/index.md#needsproject). + +For example, in a [multi-project pipeline](multi_project_pipelines.md): + +1. Save the variables in a `.env` file. +1. Save the `.env` file as a `dotenv` report. +1. Trigger the downstream pipeline. + + ```yaml + build_vars: + stage: build + script: + - echo "BUILD_VERSION=hello" >> build.env + artifacts: + reports: + dotenv: build.env + + deploy: + stage: deploy + trigger: my/downstream_project + ``` + +1. Set the `test` job in the downstream pipeline to inherit the variables from the `build_vars` + job in the upstream project with `needs`. The `test` job inherits the variables in the + `dotenv` report and it can access `BUILD_VERSION` in the script: + + ```yaml + test: + stage: test + script: + - echo $BUILD_VERSION + needs: + - project: my/upstream_project + job: build_vars + ref: master + artifacts: true + ``` diff --git a/doc/ci/pipelines/img/downstream_pipeline_actions.png b/doc/ci/pipelines/img/downstream_pipeline_actions.png deleted file mode 100644 index 4c4384bab57b76c79410f7e67350c45ee3a2e45d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13406 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 diff --git a/doc/ci/pipelines/multi_project_pipelines.md b/doc/ci/pipelines/multi_project_pipelines.md index e7d5e3e102a6f..3fb720cfb814e 100644 --- a/doc/ci/pipelines/multi_project_pipelines.md +++ b/doc/ci/pipelines/multi_project_pipelines.md @@ -10,7 +10,7 @@ type: reference > [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/199224) to GitLab Free in 12.8. You can set up [GitLab CI/CD](../index.md) across multiple projects, so that a pipeline -in one project can trigger a pipeline in another project. You can visualize the entire pipeline +in one project can trigger a [downstream](downstream_pipelines.md) pipeline in another project. You can visualize the entire pipeline in one place, including all cross-project interdependencies. For example, you might deploy your web application from three different projects in GitLab. @@ -69,7 +69,7 @@ GitLab then creates a downstream pipeline in the `staging` job succeeds. The full path to the project is `my/deployment`. You can view the status for the pipeline, or you can display -[the downstream pipeline's status instead](#mirror-status-of-a-triggered-pipeline-in-the-trigger-job). +[the downstream pipeline's status instead](downstream_pipelines.md#mirror-the-status-of-a-downstream-pipeline-in-the-trigger-job). The user that creates the upstream pipeline must be able to create pipelines in the downstream project (`my/deployment`) too. If the downstream project is not found, @@ -124,117 +124,6 @@ of the user that ran the trigger job in the upstream project. If the user does n have permission to run CI/CD pipelines against the protected branch, the pipeline fails. See [pipeline security for protected branches](index.md#pipeline-security-on-protected-branches). -#### Pass CI/CD variables to a downstream pipeline by using the `variables` keyword - -Sometimes you might want to pass CI/CD variables to a downstream pipeline. -You can do that by using the `variables` keyword, just like you would for any other job. - -```yaml -rspec: - stage: test - script: bundle exec rspec - -staging: - variables: - ENVIRONMENT: staging - stage: deploy - trigger: my/deployment -``` - -The `ENVIRONMENT` variable is passed to every job defined in a downstream -pipeline. It is available as a variable when GitLab Runner picks a job. - -In the following configuration, the `MY_VARIABLE` variable is passed to the downstream pipeline -that is created when the `trigger-downstream` job is queued. This is because `trigger-downstream` -job inherits variables declared in global variables blocks, and then we pass these variables to a downstream pipeline. - -```yaml -variables: - MY_VARIABLE: my-value - -trigger-downstream: - variables: - ENVIRONMENT: something - trigger: my/project -``` - -You can stop global variables from reaching the downstream pipeline by using the [`inherit:variables` keyword](../yaml/index.md#inheritvariables). -In this example, the `MY_GLOBAL_VAR` variable is not available in the triggered pipeline: - -```yaml -variables: - MY_GLOBAL_VAR: value - -trigger-downstream: - inherit: - variables: false - variables: - MY_LOCAL_VAR: value - trigger: my/project -``` - -You might want to pass some information about the upstream pipeline using, for -example, predefined variables. In order to do that, you can use interpolation -to pass any variable. For example: - -```yaml -downstream-job: - variables: - UPSTREAM_BRANCH: $CI_COMMIT_REF_NAME - trigger: my/project -``` - -In this scenario, the `UPSTREAM_BRANCH` variable with the value of the upstream pipeline's -`$CI_COMMIT_REF_NAME` is passed to `downstream-job`. It is available in the -context of all downstream builds. - -You cannot use this method to forward [job-level persisted variables](../variables/where_variables_can_be_used.md#persisted-variables) -to a downstream pipeline, as they are not available in trigger jobs. - -Upstream pipelines take precedence over downstream ones. If there are two -variables with the same name defined in both upstream and downstream projects, -the ones defined in the upstream project take precedence. - -#### Pass CI/CD variables to a downstream pipeline by using variable inheritance **(PREMIUM)** - -You can pass variables to a downstream pipeline with [`dotenv` variable inheritance](../variables/index.md#pass-an-environment-variable-to-another-job) and [`needs:project`](../yaml/index.md#needsproject). - -In the upstream pipeline: - -1. Save the variables in a `.env` file. -1. Save the `.env` file as a `dotenv` report. -1. Trigger the downstream pipeline. - - ```yaml - build_vars: - stage: build - script: - - echo "BUILD_VERSION=hello" >> build.env - artifacts: - reports: - dotenv: build.env - - deploy: - stage: deploy - trigger: my/downstream_project - ``` - -1. Set the `test` job in the downstream pipeline to inherit the variables from the `build_vars` - job in the upstream project with `needs`. The `test` job inherits the variables in the - `dotenv` report and it can access `BUILD_VERSION` in the script: - - ```yaml - test: - stage: test - script: - - echo $BUILD_VERSION - needs: - - project: my/upstream_project - job: build_vars - ref: master - artifacts: true - ``` - #### Pass artifacts to a downstream pipeline You can pass artifacts to a downstream pipeline by using [`needs:project`](../yaml/index.md#needsproject). @@ -287,7 +176,7 @@ pass this variable to the downstream pipeline using variable inheritance: 1. In a job in the upstream pipeline, save the artifacts using the [`artifacts`](../yaml/index.md#artifacts) keyword. 1. In the job that triggers the downstream pipeline, pass the `$CI_MERGE_REQUEST_REF_PATH` variable by using - [variable inheritance](#pass-cicd-variables-to-a-downstream-pipeline-by-using-the-variables-keyword): + [variable inheritance](downstream_pipelines.md#pass-yaml-defined-cicd-variables): ```yaml build_artifacts: @@ -336,21 +225,6 @@ is `pipeline` for all its jobs. If you use [`only/except`](../yaml/index.md#only--except) to control job behavior, use the [`pipelines`](../yaml/index.md#onlyrefs--exceptrefs) keyword. -#### Mirror status of a triggered pipeline in the trigger job - -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/11238) in GitLab Premium 12.3. -> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/199224) to GitLab Free in 12.8. - -You can mirror the pipeline status from the triggered pipeline to the source trigger job -by using [`strategy: depend`](../yaml/index.md#triggerstrategy). For example: - -```yaml -trigger_job: - trigger: - project: my/project - strategy: depend -``` - ### Create multi-project pipelines by using the API > [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/31573) to GitLab Free in 12.4. @@ -370,7 +244,7 @@ When using: - [`only/except`](../yaml/index.md#only--except) to control job behavior, use the `pipelines` keyword. -## Trigger a pipeline when an upstream project is rebuilt **(PREMIUM)** +### Trigger a pipeline when an upstream project is rebuilt **(PREMIUM)** > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9045) in GitLab 12.8. @@ -409,11 +283,3 @@ In [pipeline mini graphs](index.md#pipeline-mini-graphs), the downstream pipelin displays to the right of the mini graph.  - -## Retry or cancel multi-project pipelines - -If you have permission to trigger pipelines in the downstream project, you can -retry or cancel multi-project pipelines: - -- [In the main graph view](downstream_pipelines.md#view-a-downstream-pipeline). -- From the downstream pipeline's details page. diff --git a/doc/ci/pipelines/parent_child_pipelines.md b/doc/ci/pipelines/parent_child_pipelines.md index 2d36aaac1f761..ede90178a3500 100644 --- a/doc/ci/pipelines/parent_child_pipelines.md +++ b/doc/ci/pipelines/parent_child_pipelines.md @@ -26,7 +26,7 @@ YAML is dynamically generated.  Similarly to [multi-project pipelines](multi_project_pipelines.md), a pipeline can trigger a -set of concurrently running child pipelines, but within the same project: +set of concurrently running [downstream](downstream_pipelines.md) child pipelines, but in the same project: - Child pipelines still execute each of their jobs according to a stage sequence, but would be free to continue forward through their stages without waiting for unrelated @@ -89,8 +89,9 @@ microservice_a: The maximum number of entries that are accepted for `trigger:include` is three. -Similar to [multi-project pipelines](multi_project_pipelines.md#mirror-status-of-a-triggered-pipeline-in-the-trigger-job), -we can set the parent pipeline to depend on the status of the child pipeline upon completion: +Similar to [multi-project pipelines](multi_project_pipelines.md), we can set the +parent pipeline to [depend on the status](downstream_pipelines.md#mirror-the-status-of-a-downstream-pipeline-in-the-trigger-job) +of the child pipeline upon completion: ```yaml microservice_a: @@ -214,15 +215,7 @@ For an overview, see [Nested Dynamic Pipelines](https://youtu.be/C5j3ju9je2M). ## Pass CI/CD variables to a child pipeline -You can pass CI/CD variables to a downstream pipeline using the same methods as -multi-project pipelines: +You can pass variables to a downstream pipeline: -- [By using the `variable` keyword](multi_project_pipelines.md#pass-cicd-variables-to-a-downstream-pipeline-by-using-the-variables-keyword). -- [By using variable inheritance](multi_project_pipelines.md#pass-cicd-variables-to-a-downstream-pipeline-by-using-variable-inheritance). - -## Retry or cancel child pipelines - -You can retry or cancel child pipelines: - -- [In the main graph view](downstream_pipelines.md#view-a-downstream-pipeline). -- In the child pipeline's details page. +- [By using the `variables` keyword](downstream_pipelines.md#pass-yaml-defined-cicd-variables). +- [By using dotenv variable inheritance](downstream_pipelines.md#pass-dotenv-variables-created-in-a-job). diff --git a/doc/ci/variables/index.md b/doc/ci/variables/index.md index 72df8d5681571..e9d4fd8549c1e 100644 --- a/doc/ci/variables/index.md +++ b/doc/ci/variables/index.md @@ -647,7 +647,7 @@ deploy_five: artifacts: false ``` -[Multi-project pipelines](../pipelines/multi_project_pipelines.md#pass-cicd-variables-to-a-downstream-pipeline-by-using-variable-inheritance) +[Multi-project pipelines](../pipelines/downstream_pipelines.md#pass-dotenv-variables-created-in-a-job) can also inherit variables from their upstream pipelines. ## CI/CD variable precedence @@ -695,8 +695,8 @@ You can override the value of a variable when you: 1. Run a job manually in the UI. 1. Use [push options](../../user/project/push_options.md#push-options-for-gitlab-cicd). 1. Trigger a pipeline by using [the API](../triggers/index.md#pass-cicd-variables-in-the-api-call). -1. Pass variables to a downstream pipeline [by using the `variable` keyword](../pipelines/multi_project_pipelines.md#pass-cicd-variables-to-a-downstream-pipeline-by-using-the-variables-keyword) - or [by using variable inheritance](../pipelines/multi_project_pipelines.md#pass-cicd-variables-to-a-downstream-pipeline-by-using-variable-inheritance). +1. Pass variables to a downstream pipeline [by using the `variable` keyword](../pipelines/downstream_pipelines.md#pass-cicd-variables-to-a-downstream-pipeline) + or [by using variable inheritance](../pipelines/downstream_pipelines.md#pass-dotenv-variables-created-in-a-job). The pipeline variables declared in these events take [priority over other variables](#cicd-variable-precedence). diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md index bbd27a3f070ec..32600a73c0a71 100644 --- a/doc/ci/yaml/index.md +++ b/doc/ci/yaml/index.md @@ -3884,7 +3884,7 @@ test: > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8997) in GitLab Premium 11.8. > - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/199224) to GitLab Free in 12.8. -Use `trigger` to start a downstream pipeline that is either: +Use `trigger` to start a [downstream pipeline](../pipelines/downstream_pipelines.md) that is either: - [A multi-project pipeline](../pipelines/multi_project_pipelines.md). - [A child pipeline](../pipelines/parent_child_pipelines.md). -- GitLab