ダウンストリームパイプライン

ダウンストリームパイプラインとは、他のパイプラインによってトリガーされるGitLab CI/CDパイプラインのことです。ダウンストリームパイプラインは、トリガーとなったアップストリームパイプラインとは独立して、同時に実行されます。

親子パイプラインとマルチプロジェクトパイプラインを同じような目的で使用できる場合がありますが、重要な違いがあります。

親子パイプライン

親パイプラインは、同じプロジェクト内のダウンストリームパイプラインをトリガーするパイプラインです。ダウンストリームパイプラインは子パイプラインと呼ばれます。

子パイプライン:

  • 親パイプラインと同じプロジェクト、ref、コミット SHA で実行します。
  • パイプラインが実行される ref の全体的なステータスに直接影響を与えません。たとえば、パイプラインがメインブランチに対して失敗した場合、「メインが壊れた」と言うのが一般的です。子パイプラインのステータスが ref のステータスに影響するのは、子パイプラインがstrategy:depend でトリガーされた場合だけです。
  • パイプラインがinterruptible で設定されている場合、同じ参照に対して新しいパイプラインが作成されると、自動的にキャンセルされます。
  • プロジェクトのパイプライン リストには表示されません。子パイプラインは、親パイプラインの詳細ページでのみ表示できます。

ネストされた子パイプライン

親パイプラインと子パイプラインの深さは、最大2レベルです。

親パイプラインは多数の子パイプラインをトリガでき、これらの子パイプラインは独自の子パイプラインをトリガできます。別のレベルの子パイプラインをトリガすることはできません。

概要については、入れ子のダイナミックパイプラインを参照してください。

複数プロジェクトのパイプライン

あるプロジェクトのパイプラインは、マルチプロジェクトパイプラインと呼ばれる別のプロジェクトのダウンストリームパイプラインをトリガーすることができます。アップストリーム パイプラインをトリガーするユーザーは、ダウンストリーム プロジェクトのパイプラインを開始できる必要があります。

マルチプロジェクトパイプライン:

  • 他のプロジェクトのパイプラインからトリガーされますが、アップストリーム(トリガーする)パイプラインはダウンストリーム(トリガーされる)パイプラインをあまりコントロールできません。しかし、ダウンストリームパイプラインのrefを選択したり、CI/CD変数を渡すことはできます。
  • strategy:depend でトリガーされた場合を除き、トリガーされたパイプラインの ref の状態には影響しません。
  • interruptible を使用している場合、アップストリームパイプラインの同じ ref に対して新しいパイプラインが実行されても、ダウンストリームプロジェクトで自動的にキャンセルされることはありません。ダウンストリームプロジェクトで同じ ref に対して新しいパイプラインがトリガーされた場合は、自動的にキャンセルされる可能性があります。
  • ダウンストリームプロジェクトのパイプラインリストに表示されます。
  • 独立しているため、入れ子に制限がありません。

詳しくは、GitLab@learnContinuous IntegrationセクションのCross-project Pipeline Triggering and Visualizationdemo をご覧ください。

非公開プロジェクトのダウンストリームパイプラインを公開プロジェクトでトリガーする場合は、機密性の問題がないことを確認してください。アップストリームプロジェクトのパイプラインページは常に表示されます:

  • ダウンストリームプロジェクトの名前。
  • パイプラインのステータス。

.gitlab-ci.yml ファイルのジョブからダウンストリームパイプラインをトリガーします。

.gitlab-ci.yml ファイルでtrigger キーワードを使用して、ダウンストリームパイプラインをトリガするジョブを作成します。このジョブはトリガージョブと呼ばれます。

使用例:

Parent-child pipeline
trigger_job:
  trigger:
    include:
      - local: path/to/child-pipeline.yml
Multi-project pipeline
trigger_job:
  trigger:
    project: project-group/my-downstream-project

トリガージョブの開始後、GitLabがダウンストリームパイプラインの作成を試みる間、ジョブの初期ステータスはpending 。ダウンストリームパイプラインの作成に成功した場合、トリガージョブはpassed を表示し、そうでない場合はfailed を表示します。代わりに、トリガージョブがダウンストリームパイプラインのステータスを表示するように設定することもできます。

rules を使用してダウンストリームパイプラインジョブを制御します。

CI/CD 変数またはrules キーワードを使用して、ダウンストリームパイプラインのジョブの動作を制御します。

trigger キーワードを使用してダウンストリームパイプラインをトリガすると、すべてのジョブの$CI_PIPELINE_SOURCE 定義済み変数 の値が次のようになります:

  • pipeline マルチプロジェクトパイプラインの場合。
  • parent_pipeline 親子パイプライン用。

例えば、マージリクエストパイプラインも実行するプロジェクトで、マルチプロジェクトパイプラインのジョブを制御する場合などです:

job1:
  rules:
    - if: $CI_PIPELINE_SOURCE == "pipeline"
  script: echo "This job runs in multi-project pipelines only"

job2:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  script: echo "This job runs in merge request pipelines only"

job3:
  rules:
    - if: $CI_PIPELINE_SOURCE == "pipeline"
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  script: echo "This job runs in both multi-project and merge request pipelines"

別のプロジェクトの子パイプライン設定ファイルを使用します。

GitLab 13.5 で導入されました

トリガージョブでinclude:project を使うと、別のプロジェクトにある設定ファイルで子パイプラインをトリガすることができます:

microservice_a:
  trigger:
    include:
      - project: 'my-group/my-pipeline-library'
        ref: 'main'
        file: '/path/to/child-pipeline.yml'

複数の子パイプライン設定ファイルの結合

子パイプラインを定義するときに、最大3つの設定ファイルを含めることができます。子パイプラインの設定は、すべての設定ファイルをマージして構成されます:

microservice_a:
  trigger:
    include:
      - local: path/to/microservice_a.yml
      - template: Security/SAST.gitlab-ci.yml
      - project: 'my-group/my-pipeline-library'
        ref: 'main'
        file: '/path/to/child-pipeline.yml'

動的な子パイプライン

プロジェクトに保存された静的なファイルではなく、ジョブで生成された YAML ファイルから子パイプラインをトリガーできます。このテクニックは、変更されたコンテンツをターゲットにパイプラインを生成したり、ターゲットとアーキテクチャのマトリックスを構築したりするのにとても強力です。

生成されたYAMLファイルを含むアーティファクトは5MB以下でなければなりません。

概要については、動的に生成された設定を使用して子パイプラインを作成するを参照してください。

動的な子パイプラインを生成するサンプルプロジェクトについては、「Jsonnetを使用した動的な子パイプライン」を参照してください。このプロジェクトでは、データテンプレート言語を使用して実行時に.gitlab-ci.yml を生成する方法を示します。Dhallyttのような他のテンプレート言語でも、同様のプロセスを使用できます。

動的な子パイプラインのトリガー

動的に生成された設定ファイルから子パイプラインをトリガーするには、以下の手順に従います:

  1. ジョブで設定ファイルを生成し、アーティファクトとして保存します:

    generate-config:
      stage: build
      script: generate-ci-config > generated-config.yml
      artifacts:
        paths:
          - generated-config.yml
    
  2. 設定ファイルを生成したジョブの後に実行するように、トリガ・ジョブを設定します。生成されたアーティファクトにinclude: artifact を設定し、アーティファクトを作成したジョブにinclude: job を設定します:

    child-pipeline:
      stage: test
      trigger:
        include:
          - artifact: generated-config.yml
            job: generate-config
    

この例では、GitLab はgenerated-config.yml を取得し、そのファイルの CI/CD 設定を使って子パイプラインをトリガーします。

アーティファクトのパスは GitLab が解析するのであって Runner が解析するわけではないので、パスは GitLab が動いている OS の構文に合わせる必要があります。GitLab が Linux 上で動作しているがテスト用に Windows Runner を使用している場合、トリガジョブのパスセパレータは/ になります。スクリプトのような Windows Runner を使うジョブのその他の CI/CD 設定は、 \を使います。

マージリクエストパイプラインと子パイプラインの実行

子パイプラインを含むパイプラインは、rules またはworkflow:rulesを使用していない場合、デフォルトでブランチパイプラインとして実行されます。マージリクエスト (親) パイプラインからトリガーされたときに子パイプラインが実行されるように設定するには、rules またはworkflow:rulesを使用します。たとえば、rulesを使用します:

  1. 親パイプラインのトリガージョブをマージリクエストで実行するように設定します:

    trigger-child-pipeline-job:
      trigger:
        include: path/to/child-pipeline-configuration.yml
      rules:
        - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    
  2. rules を使用して、親パイプラインによってトリガーされたときに実行する子パイプライン ジョブを設定します:

    job1:
      script: echo "This child pipeline job runs any time the parent pipeline triggers it."
      rules:
        - if: $CI_PIPELINE_SOURCE == "parent_pipeline"
       
    job2:
      script: echo "This child pipeline job runs only when the parent pipeline is a merge request pipeline"
      rules:
        - if: $CI_MERGE_REQUEST_ID
    

子パイプラインでは、$CI_PIPELINE_SOURCE の値は常にparent_pipeline になります:

  • 子パイプラインのジョブが常に実行されるようにするには、if: $CI_PIPELINE_SOURCE == "parent_pipeline" を使用します。
  • if: $CI_PIPELINE_SOURCE == "merge_request_event" を使用して、マージリクエストパイプラインに対して実行する子パイプラインジョブを設定することは_できません_。代わりに、if: $CI_MERGE_REQUEST_ID を使用して、親パイプラインがマージリクエストパイプラインの場合にのみ子パイプラインジョブが実行されるように設定します。親パイプラインのCI_MERGE_REQUEST_* 定義済み変数 が子パイプラインジョブに渡されます。

マルチプロジェクトパイプラインのブランチの指定

マルチプロジェクトパイプラインをトリガーする際に使用するブランチを指定することができます。GitLab はブランチの先頭のコミットを使用してダウンストリームパイプラインを作成します。例えば

staging:
  stage: deploy
  trigger:
    project: my/deployment
    branch: stable-11-2

使用方法。

  • project キーワードでダウンストリームプロジェクトへのフルパスを指定します。GitLab 15.3以降では 変数展開が使えます。
  • branch キーワードで、project で指定したプロジェクト内のブランチ名やタグ名を指定します。変数展開を使用できます。

API を使用してマルチプロジェクトパイプラインをトリガーします。

CI/CD ジョブの内部からマルチプロジェクトパイプラインをトリガーするために、CI/CD ジョブトークン (CI_JOB_TOKEN)パイプライントリガー API エンドポイントと一緒に使うことができます。GitLab は、ジョブトークンでトリガーされたパイプラインを、API 呼び出しを行ったジョブを含むパイプラインのダウンストリームパイプラインとして設定します。

使用例:

trigger_pipeline:
  stage: deploy
  script:
    - curl --request POST --form "token=$CI_JOB_TOKEN" --form ref=main "https://gitlab.example.com/api/v4/projects/9/trigger/pipeline"
  rules:
    - if: $CI_COMMIT_TAG
  environment: production

ダウンストリームパイプラインの表示

GitLab 13.2で導入されたパイプラインカードのホバー動作。

パイプライングラフビューでは、ダウンストリームパイプラインがグラフの右側にカードのリストとして表示されます。このビューでは、以下のことができます:

  • トリガージョブを選択すると、トリガされたダウンストリームパイプラインのジョブが表示されます。
  • パイプラインカードのExpand jobs を選択すると、ダウンストリームパイプラインのジョブが表示されます。一度に表示できるダウンストリームパイプラインは1つです。
  • パイプラインカードにカーソルを合わせると、ダウンストリームパイプラインのトリガーとなったジョブがハイライトされます。

ダウンストリームパイプラインで失敗したジョブやキャンセルされたジョブの再試行

失敗したジョブやキャンセルされたジョブを再試行するには、再試行({retry}) を選択してください:

  • ダウンストリームパイプラインの詳細ページから、[Retry ({retry})] を選択します。
  • パイプライングラフビューのパイプラインカード。

ダウンストリームパイプラインの再作成

  • GitLab15.10で導入されたグラフビューからのトリガージョブの再試行(ci_recreate_downstream_pipeline というフラグ付き)。デフォルトでは無効。
  • GitLab 15.11で一般的に利用可能に。機能フラグci_recreate_downstream_pipeline を削除しました。

対応するトリガージョブを再試行することで、ダウンストリームパイプラインを再作成できます。新しく作成されたダウンストリームパイプラインは、パイプライングラフ内の現在のダウンストリームパイプラインを置き換えます。

ダウンストリームパイプラインを再作成するには

  • パイプライングラフビューのトリガージョブのカードで [再実行]({retry}) を選択します。

ダウンストリームパイプラインのキャンセル

実行中のダウンストリームパイプラインをキャンセルするには、キャンセル({cancel}) を選択します:

  • ダウンストリームパイプラインの詳細ページから、[Retry ({retry})] を選択します。
  • パイプライングラフビューのパイプラインカード。

トリガジョブのダウンストリームパイプラインのステータスをミラーリングします。

strategy: depend を使用して、トリガジョブ内のダウンストリームパイプラインのステータスをミラーリングできます:

Parent-child pipeline
trigger_job:
  trigger:
    include:
      - local: path/to/child-pipeline.yml
    strategy: depend
Multi-project pipeline
trigger_job:
  trigger:
    project: my/project
    strategy: depend

パイプライングラフで複数プロジェクトのパイプラインを表示

マルチプロジェクトパイプラインをトリガーすると、パイプライングラフの右側にダウンストリームパイプラインが表示されます。

パイプラインのミニグラフでは、ミニグラフの右側にダウンストリーム パイプラインが表示されます。

アップストリームパイプラインからアーティファクトを取得

Parent-child pipeline

アップストリームパイプラインからアーティファクトをフェッチするには、needs:pipeline:job を使用します:

  1. アップストリームパイプラインで、artifacts キーワードを使用してアーティファクトをジョブに保存し、トリガジョブでダウンストリームパイプラインをトリガします:

    build_artifacts:
      stage: build
      script:
        - echo "This is a test artifact!" >> artifact.txt
      artifacts:
        paths:
          - artifact.txt
       
    deploy:
      stage: deploy
      trigger:
        include:
          - local: path/to/child-pipeline.yml
      variables:
        PARENT_PIPELINE_ID: $CI_PIPELINE_ID
    
  2. ダウンストリームパイプラインのジョブでneeds:pipeline:job を使用してアーティファクトをフェッチします。

    test:
      stage: test
      script:
        - cat artifact.txt
      needs:
        - pipeline: $PARENT_PIPELINE_ID
          job: build_artifacts
    

    アーティファクトを作成したアップストリームパイプラインのジョブにjob を設定します。

Multi-project pipeline

アップストリームパイプラインからアーティファクトをフェッチするには、needs:project を使用します:

  1. GitLab 15.9以降では、アップストリームプロジェクトのジョブトークンスコープ許可リストにダウンストリームプロジェクトを追加してください。
  2. アップストリームパイプラインで、artifacts キーワードを使用してアーティファクトをジョブに保存し、トリガジョブでダウンストリームパイプラインをトリガします:

    build_artifacts:
      stage: build
      script:
        - echo "This is a test artifact!" >> artifact.txt
      artifacts:
        paths:
          - artifact.txt
       
    deploy:
      stage: deploy
      trigger: my/downstream_project   # Path to the project to trigger a pipeline in
    
  3. ダウンストリームパイプラインのジョブでneeds:project を使用してアーティファクトをフェッチします。

    test:
      stage: test
      script:
        - cat artifact.txt
      needs:
        - project: my/upstream_project
          job: build_artifacts
          ref: main
          artifacts: true
    

    設定します:

    • job アーティファクトを作成したアップストリームパイプラインのジョブに設定します。
    • ref をブランチに追加します。
    • artifactstrue に設定します。

アップストリームマージリクエストパイプラインからのアーティファクトの取得

needs:project を使用してアーティファクトをダウンストリームパイプラインに渡す場合、ref の値は通常ブランチ名で、maindevelopmentのようになります。

マージリクエストパイプラインの場合、ref の値はrefs/merge-requests/<id>/head のようになります。id はマージリクエストIDです。この参照はCI_MERGE_REQUEST_REF_PATH CI/CD 変数で取得できます。マージリクエストパイプラインでは、ref としてブランチ名を使用しないでください。ダウンストリームパイプラインは、最新のブランチパイプラインからアーティファクトをフェッチしようとするからです。

branch パイプラインではなく、アップストリームmerge request パイプラインからアーティファクトをフェッチするには、変数継承を使用してCI_MERGE_REQUEST_REF_PATH をダウンストリームパイプラインに渡します:

  1. GitLab 15.9以降では、アップストリームプロジェクトのジョブトークンスコープ許可リストにダウンストリームプロジェクトを追加してください。
  2. アップストリームパイプラインのジョブで、artifacts キーワードを使用してアーティファクトを保存します。
  3. ダウンストリームパイプラインをトリガーするジョブで、$CI_MERGE_REQUEST_REF_PATH 変数を渡します:

    build_artifacts:
      rules:
        - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
      stage: build
      script:
        - echo "This is a test artifact!" >> artifact.txt
      artifacts:
        paths:
          - artifact.txt
       
    upstream_job:
      rules:
        - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
      variables:
        UPSTREAM_REF: $CI_MERGE_REQUEST_REF_PATH
      trigger:
        project: my/downstream_project
        branch: my-branch
    
  4. ダウンストリームパイプラインのジョブで、needs:project と渡された変数をref として使用して、アップストリームパイプラインからアーティファクトをフェッチします:

    test:
      stage: test
      script:
        - cat artifact.txt
      needs:
        - project: my/upstream_project
          job: build_artifacts
          ref: $UPSTREAM_REF
          artifacts: true
    

このメソッドを使用して、アップストリーム・マージ・リクエスト・パイプラインからアーティファクトをフェッチできますが、マージ結果パイプラインからはフェッチできません。

CI/CD 変数をダウンストリームパイプラインに渡します。

CI/CD変数をダウンストリームパイプラインに渡すには、変数が作成された場所や定義された場所に応じていくつかの方法があります。

YAML で定義された CI/CD 変数を渡す

variables キーワードを使うと、CI/CD 変数をダウンストリームパイプラインに渡すことができます。これらの変数は変数の優先順位のための「トリガー変数」です。

使用例:

Parent-child pipeline
variables:
  VERSION: "1.0.0"

staging:
  variables:
    ENVIRONMENT: staging
  stage: deploy
  trigger:
    include:
      - local: path/to/child-pipeline.yml
Multi-project pipeline
variables:
  VERSION: "1.0.0"

staging:
  variables:
    ENVIRONMENT: staging
  stage: deploy
  trigger: my-group/my-deployment-project

ENVIRONMENT 変数は、ダウンストリームパイプラインで定義されたすべてのジョブで使用できます。

トリガ・ジョブを含むパイプライン内のすべてのジョブはグローバルvariables を継承するため、VERSION グローバル変数もダウンストリーム・パイプラインで使用できます。

グローバル変数が渡されないようにするには

inherit:variables:false を使って、CI/CD のグローバル変数がダウンストリームパイプラインに届かないようにすることができます。

使用例:

Parent-child pipeline
variables:
  GLOBAL_VAR: value

trigger-job:
  inherit:
    variables: false
  variables:
    JOB_VAR: value
  trigger:
    include:
      - local: path/to/child-pipeline.yml
Multi-project pipeline
variables:
  GLOBAL_VAR: value

trigger-job:
  inherit:
    variables: false
  variables:
    JOB_VAR: value
  trigger: my-group/my-project

GLOBAL_VAR 変数はトリガーされたパイプラインでは使用できませんが、JOB_VAR は使用できます。

定義済みの変数を渡します。

定義済みのCI/CD変数を使用してアップストリームパイプラインの情報を渡すには、補間を使用します。定義済みの変数をトリガジョブの新しいジョブ変数として保存し、ダウンストリームパイプラインに渡します。例えば

Parent-child pipeline
trigger-job:
  variables:
    PARENT_BRANCH: $CI_COMMIT_REF_NAME
  trigger:
    include:
      - local: path/to/child-pipeline.yml
Multi-project pipeline
trigger-job:
  variables:
    UPSTREAM_BRANCH: $CI_COMMIT_REF_NAME
  trigger: my-group/my-project

アップストリームパイプラインの$CI_COMMIT_REF_NAME 定義済み CI/CD 変数の値を含むUPSTREAM_BRANCH 変数は、ダウンストリームパイプラインで使用できます。

マスクされた変数をマルチプロジェクトパイプラインに渡すためにこのメソッドを使用しないでください。CI/CD マスキングの設定はダウンストリームパイプラインに渡されず、ダウンストリームプロジェクトのジョブログで変数がマスク解除される可能性があります。

このメソッドを使用して、ジョブレベルの永続化された変数をダウンストリームパイプラインに転送することはできません。

アップストリーム・パイプラインはダウンストリーム・パイプラインよりも優先されます。アップストリームプロジェクトとダウンストリームプロジェクトの両方で同じ名前の変数が定義されている場合は、アップストリームプロジェクトで定義されている変数が優先されます。

ジョブで作成されたdotenv変数を渡します。

dotenv 変数継承needs:projectでダウンストリームジョブに変数を渡すことができます。これらの変数はジョブのスクリプトでのみ使用可能で、例えばrulesartifact:paths を使用してジョブを設定することはできません。

例えば、マルチプロジェクトパイプラインの場合:

  1. 変数を.env ファイルに保存します。
  2. .env ファイルをdotenv レポートとして保存します。
  3. ダウンストリームパイプラインを起動します。

    build_vars:
      stage: build
      script:
        - echo "BUILD_VERSION=hello" >> build.env
      artifacts:
        reports:
          dotenv: build.env
       
    deploy:
      stage: deploy
      trigger: my/downstream_project
    
  4. ダウンストリームパイプラインのtest ジョブに、アップストリームプロジェクトのbuild_vars ジョブの変数をneeds で継承するように設定します。test ジョブはdotenv レポートの変数を継承し、スクリプトでBUILD_VERSION にアクセスできます:

    test:
      stage: test
      script:
        - echo $BUILD_VERSION
      needs:
        - project: my/upstream_project
          job: build_vars
          ref: master
          artifacts: true
    

ダウンストリームパイプラインに転送する変数のタイプを制御します。

trigger:forward キーワード を使用して、ダウンストリームパイプラインに転送する変数のタイプを指定します。転送された変数はトリガ変数と見なされ、最も優先順位が高くなります。

トラブルシューティング

トリガージョブが失敗し、マルチプロジェクトパイプラインが作成されません。

マルチプロジェクトパイプラインでは、以下の場合、トリガージョブは失敗し、ダウンストリームパイプラインは作成されません:

  • ダウンストリームプロジェクトが見つからない場合。
  • アップストリーム・パイプラインを作成したユーザーに、ダウンストリーム・プロジェクトでパイプラインを作成する権限がありません。
  • ダウンストリームパイプラインが保護されたブランチを対象としており、ユーザーには保護されたブランチに対してパイプラインを実行する権限がありません。詳細は、保護されたブランチのパイプラインセキュリティを参照してください。

パイプラインの実行時に子パイプラインのジョブが作成されない

親パイプラインがマージリクエストパイプラインの場合、子パイプラインはworkflow:rules またはrules を使用して、ジョブがを実行するようにする必要があります。

rules 設定がない、または正しくないために子パイプラインのジョブが実行できない場合:

  • 子パイプラインの起動に失敗します。
  • 親パイプラインのトリガージョブが失敗しました:downstream pipeline can not be created, Pipeline will not run for the selected trigger. The rules configuration prevented any jobs from being added to the pipeline.

Ref is ambiguous

同じ名前のブランチが存在する場合、タグを使用してマルチプロジェクトパイプラインをトリガすることはできません。ダウンストリームパイプラインがエラーで作成に失敗しました:downstream pipeline can not be created, Ref is ambiguous.

ブランチ名と一致しないタグ名でのみ、マルチプロジェクトパイプラインをトリガーしてください。

403 Forbidden アップストリームパイプラインからジョブアーティファクトをダウンロードする際のエラー

GitLab 15.9 以降では、CI/CD ジョブトークンはパイプラインが実行されるプロジェクトにスコープされます。そのため、ダウンストリームパイプラインのジョブトークンを使ってアップストリームプロジェクトにアクセスすることはデフォルトではできません。

これを解決するには、ジョブトークンスコープの許可リストにダウンストリームプロジェクトを追加します。