マージリクエストパイプライン

GitLab 11.6から導入されました

基本的な設定では、GitLabは変更がブランチにプッシュされるたびにパイプラインを実行します。

マージリクエストの作成時や更新時にのみジョブを実行させたい場合は、マージリクエストパイプラインを使用できます。

UIでは、これらのパイプラインはdetachedと表示されます。それ以外は、他のパイプラインと同じように表示されます。

開発者権限を持つユーザは誰でも、マージリクエストパイプラインを実行できます。

Merge request page

注意:パイプラインが成功したときにマージでこの機能を使用すると、マージリクエスト用のパイプラインが他の通常のパイプラインよりも優先されます。

前提条件

マージリクエストのパイプラインを有効にする。

マージリクエストパイプラインを設定する

マージリクエストパイプラインを設定するには、CI/CD設定ファイルを設定する必要があります。この設定をするためには、いくつかの方法があります。

rules を使用して、マージリクエストのパイプラインを実行します。

rulesを使用する場合は、workflow:rules テンプレート のいずれかを使用して、基本的な設定が正しいことを確認することから始めることをお勧めします。この方法とカスタマイズ方法については、このリンクを参照してください。

only またはexcept を使ってマージリクエスト用のパイプラインを実行します。

only/exceptを使い続けたい場合は可能ですが、以下の欠点をご確認ください。

この方法を使用する場合、各ジョブにonly: - merge_requests を指定する必要があります。この例では、パイプラインにマージリクエストで実行するように設定されたtest ジョブが含まれています。

build およびdeploy ジョブはonly: - merge_requests パラメータを持たないため、マージリクエストでは実行されません。

build:
  stage: build
  script: ./build
  only:
    - master

test:
  stage: test
  script: ./test
  only:
    - merge_requests

deploy:
  stage: deploy
  script: ./deploy
  only:
    - master

特定のジョブを除外する

only: [merge_requests] パラメータの動作は、そのパラメータを持つ_ジョブのみが_マージリクエストのコンテキストで実行されるようになっています。

しかし、この動作を反転させて、1つか2つを_除いた_すべてのジョブを実行させることができます。

ABCのジョブを持つ、以下のパイプラインを考えてみましょう:

  • すべてのパイプラインは常にAB
  • C をマージリクエストに対してのみ実行するようにしました。

そのためには、.gitlab-ci.yml ファイルを次のように設定します:

.only-default: &only-default
  only:
    - master
    - merge_requests
    - tags

A:
  <<: *only-default
  script:
    - ...

B:
  <<: *only-default
  script:
    - ...

C:
  script:
    - ...
  only:
    - merge_requests

上記の設定では、以下のように動作します。

  • AB は、すべてのケースでonly: ルールの実行を取得しているので、常に実行されます。
  • C はマージリクエストに対してのみ実行するように指定されているため、マージリクエストパイプライン以外のパイプラインに対しては実行されません。

これにより、常にジョブを実行させるために、すべてのジョブにonly: ルールを追加する必要がなくなります。 このフォーマットを使用してレビューアプリを設定することができ、リソースの節約に役立ちます。

特定のブランチを除外する

マージリクエスト用のパイプラインは、only/exceptを使う場合には特別な扱いが必要です。通常のブランチ参照 (たとえばrefs/heads/my-feature-branch) とは異なり、マージリクエスト参照はrefs/merge-requests/:iid/headのような特別な Git 参照を使います。このため、以下の設定は期待通りに動作しません

# Does not exclude a branch named "docs-my-fix"!
test:
  only: [merge_requests]
  except: [/^docs-/]

代わりに、$CI_COMMIT_REF_NAME 定義済み環境変数only:variables と組み合わせて使用することで、この動作を実現できます:

test:
  only: [merge_requests]
  except:
    variables:
      - $CI_COMMIT_REF_NAME =~ /^docs-/

マージ結果のパイプライン

マージ結果パイプラインに関するドキュメントを参照してください。

マージトレイン

マージトレインのドキュメントを参照してください。

フォークされたプロジェクトからのマージリクエストに関する重要な注意事項

現在の動作は変更される可能性があることに注意してください。通常のコントリビューションフローでは、外部コントリビューターは以下の手順に従います。

  1. 親プロジェクトをフォークします。
  2. フォークしたプロジェクトから、親プロジェクトのmaster ブランチを対象としたマージリクエストを作成します。
  3. マージリクエストに対してパイプラインが実行されます。
  4. 親プロジェクトの管理者がパイプラインの結果をチェックし、最新のパイプラインが成功していればターゲットブランチにマージします。

現在、これらのパイプラインは親プロジェクトではなく、フォークされたプロジェクトで作成されています。これは、パイプラインの結果が完全には信頼できないことを意味します。外部のコントリビューターがフォークしたプロジェクトのGitLab Runnerを使用するため、パイプラインの結果を技術的には偽装できるためです。

GitLab がこれらのパイプラインを親プロジェクトに作成させない理由は複数ありますが、最大の理由のひとつはセキュリティ上の懸念です。 外部ユーザーが.gitlab-ci.ymlを変更することで、親プロジェクトから秘密の変数を盗む可能性があります。 このようなことは起こるべきではありません。

私たちは、フォークされたプロジェクトから作成されたマージリクエストパイプラインを実行する安全な解決策を議論しています。詳しくはパーミッション拡張に関する課題を参照してください。

追加された定義済み変数

マージリクエストパイプラインを使用することで、GitLabはパイプラインジョブに追加の定義済み変数を公開します。これらの変数には関連するマージリクエストの情報が含まれているので、GitLabのマージリクエストAPIとジョブを統合するのに便利です。

使用可能な変数のリストはリファレンス・シートにあります。変数名はCI_MERGE_REQUEST_ のプレフィックスで始まります。

トラブルシューティング

マージリクエストにプッシュすると2つのパイプラインが作成されます

rulesを使用した際にパイプラインが重複してしまう場合は、rulesonly/exceptの重要な違いをご覧ください。

only/exceptonly/except使用しているときに2つのパイプラインが表示される場合は、上記のonly/except使用に関する注意事項を参照してください only/except(または、rules)への移行を検討してください。

無効なCI設定ファイルをプッシュすると2つのパイプラインが作成されます

無効なCI設定ファイルを持つブランチをプッシュすると、2つの失敗したパイプラインが作成されます。1つは失敗したマージリクエストパイプライン、もう1つは失敗したブランチパイプラインですが、どちらも同じ無効なCI設定によって引き起こされます。

まれに、パイプラインが重複して作成されることがあります。

詳しくはこの課題をご覧ください。