マージリクエストパイプライン
GitLab 11.6で導入されました。
基本的な設定では、GitLabは変更がブランチにプッシュされるたびにパイプラインを実行します。
マージリクエストの作成時や更新時にのみジョブを実行させたい場合は、マージリクエストパイプラインを使用できます。
UIでは、これらのパイプラインはdetached
状態で表示され、それ以外の場合は他のパイプラインと同じように表示されます。
開発者権限を持つユーザは誰でも、マージリクエストパイプラインを実行できます。
前提条件
マージリクエストのパイプラインを有効にする。
- リポジトリはGitLabリポジトリでなければならず、外部リポジトリは使用できません。
- GitLab 11.10以降を使用し、GitLab Runner 11.9以降を使用する必要があります。
マージリクエストパイプラインを設定する
マージリクエストパイプラインを設定するには、CI/CD設定ファイルを設定する必要があります。この設定をするためには、いくつかの方法があります。
rules
を使用して、マージリクエストパイプラインを実行する
rules
を使用する場合は、基本的な設定が正しいことを確認するために、workflow:rule
のテンプレートから始めることをお勧めします。ルールの使用方法やカスタマイズ方法については、リンク先で説明しています。
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/:id/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
を使用しているときにパイプラインが重複している場合は、ruels
とonly
/except
の間の重要な違いを見てみましょう。
only/exceptを
使用しているときに2つのパイプラインが表示されている場合は、上記のonly/except
の使用に関する注意事項を参照してください(または、rules
への移行を検討してください)。
無効なCI設定ファイルをプッシュすると2つのパイプラインが作成されます
無効なCI設定ファイルを持つブランチをプッシュすると、2つの失敗したパイプラインが作成されます。1つは失敗したマージリクエストパイプライン、もう1つは失敗したブランチパイプラインですが、どちらも同じ無効なCI設定によって引き起こされます。
まれに、パイプラインが重複して作成されることがあります。
詳しくはこの課題をご覧ください。