マージリクエストパイプライン
GitLab 11.6から導入されました。
基本的な設定では、GitLabは変更がブランチにプッシュされるたびにパイプラインを実行します。
マージリクエストの作成時や更新時にのみジョブを実行させたい場合は、マージリクエストパイプラインを使用できます。
UIでは、これらのパイプラインはdetached
と表示されます。それ以外は、他のパイプラインと同じように表示されます。
開発者権限を持つユーザは誰でも、マージリクエストパイプラインを実行できます。
前提条件
マージリクエストのパイプラインを有効にする。
- リポジトリはGitLabリポジトリでなければならず、外部リポジトリは使用できません。
- GitLab 11.10以降を使用し、GitLab Runner 11.9以降を使用する必要があります。
マージリクエストパイプラインを設定する
マージリクエストパイプラインを設定するには、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つを_除いた_すべてのジョブを実行させることができます。
A
、B
、C
のジョブを持つ、以下のパイプラインを考えてみましょう:
- すべてのパイプラインは常に
A
、B
。 -
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
上記の設定では、以下のように動作します。
-
A
とB
は、すべてのケースで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-/
マージ結果のパイプライン
マージ結果パイプラインに関するドキュメントを参照してください。
マージトレイン
マージトレインのドキュメントを参照してください。
フォークされたプロジェクトからのマージリクエストに関する重要な注意事項
現在の動作は変更される可能性があることに注意してください。通常のコントリビューションフローでは、外部コントリビューターは以下の手順に従います。
- 親プロジェクトをフォークします。
- フォークしたプロジェクトから、親プロジェクトの
master
ブランチを対象としたマージリクエストを作成します。 - マージリクエストに対してパイプラインが実行されます。
- 親プロジェクトの管理者がパイプラインの結果をチェックし、最新のパイプラインが成功していればターゲットブランチにマージします。
現在、これらのパイプラインは親プロジェクトではなく、フォークされたプロジェクトで作成されています。これは、パイプラインの結果が完全には信頼できないことを意味します。外部のコントリビューターがフォークしたプロジェクトのGitLab Runnerを使用するため、パイプラインの結果を技術的には偽装できるためです。
GitLab がこれらのパイプラインを親プロジェクトに作成させない理由は複数ありますが、最大の理由のひとつはセキュリティ上の懸念です。 外部ユーザーが.gitlab-ci.yml
を変更することで、親プロジェクトから秘密の変数を盗む可能性があります。 このようなことは起こるべきではありません。
私たちは、フォークされたプロジェクトから作成されたマージリクエストパイプラインを実行する安全な解決策を議論しています。詳しくはパーミッション拡張に関する課題を参照してください。
追加された定義済み変数
マージリクエストパイプラインを使用することで、GitLabはパイプラインジョブに追加の定義済み変数を公開します。これらの変数には関連するマージリクエストの情報が含まれているので、GitLabのマージリクエストAPIとジョブを統合するのに便利です。
使用可能な変数のリストはリファレンス・シートにあります。変数名はCI_MERGE_REQUEST_
のプレフィックスで始まります。
トラブルシューティング
マージリクエストにプッシュすると2つのパイプラインが作成されます
rules
を使用した際にパイプラインが重複してしまう場合は、rules
とonly
/except
の重要な違いをご覧ください。
only/except
を only/except
使用しているときに2つのパイプラインが表示される場合は、上記のonly/except
使用に関する注意事項を参照してください only/except
(または、rules
)への移行を検討してください。
無効なCI設定ファイルをプッシュすると2つのパイプラインが作成されます
無効なCI設定ファイルを持つブランチをプッシュすると、2つの失敗したパイプラインが作成されます。1つは失敗したマージリクエストパイプライン、もう1つは失敗したブランチパイプラインですが、どちらも同じ無効なCI設定によって引き起こされます。
まれに、パイプラインが重複して作成されることがあります。
詳しくはこの課題をご覧ください。