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

GitLab 14.8 でpipelines for merge requests からmerge request pipelines名称変更

ブランチに変更をコミットするたびにパイプラインを実行するように設定できます。このようなパイプラインをブランチパイプラインと呼びます。

あるいは、マージリクエストのソースブランチに変更を加えるたびにパイプラインを実行するように設定することもできます。このタイプのパイプラインをマージリクエストパイプラインと呼びます。

ブランチパイプライン:

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

  • デフォルトでは実行されません。CI/CD設定ファイルのジョブはマージリクエストパイプラインで実行するように設定する必要があります
  • 設定されている場合、マージリクエストパイプラインが実行されます:
    • 1つ以上のコミットがあるソースブランチから新しいマージリクエストを作成します。
    • マージリクエストのソースブランチに新しいコミットをプッシュします。
    • マージリクエストのパイプラインタブからパイプラインの実行を選択します。このオプションは、マージリクエストパイプラインがパイプラインに設定されていて、ソースブランチに少なくとも1つのコミットがある場合にのみ使用できます。
  • より多くの定義済み変数にアクセスできます。
  • プロテクトされた変数や プロテクトされたランナーにアクセスできません。

これらのタイプのパイプラインはどちらもマージリクエストのパイプラインタブに表示できます。

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

マージリクエストパイプラインには3つのタイプがあります:

  • マージリクエストパイプラインは、マージリクエストのソースブランチの変更に対して実行されます。GitLab 14.9 で導入されたこれらのパイプラインは、merge request のラベルを表示し、パイプラインがソースブランチの内容のみで実行され、ターゲットブランチは無視されることを示します。GitLab 14.8 以前では、ラベルはdetached でした。
  • マージ結果パイプラインは、ソースブランチの変更とターゲットブランチの変更を組み合わせた結果に対して実行されます。
  • マージトレイン。複数のマージリクエストを同時にマージするときに実行されます。各マージリクエストの変更は、先にエンキューされたマージリクエストの変更と一緒にターゲットブランチに結合されます。

前提条件

マージリクエストパイプラインを使用するため:

  • プロジェクトのCI/CD 設定ファイルにマージリクエストパイプラインで実行するジョブを設定する必要があります。そのためには
  • マージリクエストパイプラインを実行するには、ソースプロジェクトで少なくとも開発者ロールを持っている必要があります。
  • リポジトリは外部リポジトリではなく GitLab リポジトリでなければなりません。

rules を使ってジョブを追加します。

マージリクエストパイプラインで実行するジョブを設定するには、rules キーワードを使用します。例えば

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

workflow: rules キーワードを使用して、マージ・リクエスト・パイプラインで実行するようにパイプライン全体を構成する こともできます。例えば、以下のようになります:

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'

job1:
  script:
    - echo "This job runs in merge request pipelines"

job2:
  script:
    - echo "This job also runs in merge request pipelines"

一般的なworkflow 設定は、マージリクエスト、タグ、デフォルトブランチに対してパイプラインを実行させることです。例えば

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
    - if: $CI_COMMIT_TAG
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

only を使ってジョブを追加します。

rules が望ましい方法ですが、マージリクエストパイプラインで実行するジョブを設定するためにmerge_requests とともにonly キーワードを使うこともできます。例えば

job1:
  script:
    - echo "This job runs in merge request pipelines"
  only:
    - merge_requests

フォークされたプロジェクトでの使用

フォークで作業する外部コントリビューターは、親プロジェクトでパイプラインを作成できません。

親プロジェクトに提出されたフォークからのマージリクエストは、パイプラインをトリガーします:

  • 親プロジェクト(ターゲットプロジェクト)ではなく、フォークプロジェクト(ソースプロジェクト)で作成され、実行されます。
  • フォークプロジェクトのCI/CD設定、リソース、プロジェクトのCI/CD変数を使用します。

フォークのパイプラインは、親プロジェクトのフォークバッジで表示されます:

Pipeline ran in fork

親プロジェクトでパイプラインを実行

親プロジェクトのプロジェクトメンバーは、フォークプロジェクトから送信されたマージリクエストに対してマージリクエストパイプラインをトリガーすることができます。このパイプラインは

  • フォーク(ソース)プロジェクトではなく、親(ターゲット)プロジェクトで作成され、実行されます。
  • フォークプロジェクトのブランチに存在する CI/CD 設定を使用します。
  • 親プロジェクトの CI/CD 設定、リソース、プロジェクトの CI/CD 変数を使用します。
  • パイプラインをトリガーする親プロジェクトメンバーの権限を使用します。

親プロジェクトでマージ後のパイプラインが通過するように、フォークプロジェクトの MR でパイプラインを実行します。さらに、フォークプロジェクトのランナーを信頼しない場合、親プロジェクトでパイプラインを実行すると、親プロジェクトの信頼されたランナーが使用されます。

caution
フォークマージリクエストには、パイプラインが実行されたときに、マージ前であっても親プロジェクトのシークレットを盗もうとする悪意のあるコードが含まれている可能性があります。レビュアーとして、パイプラインを起動する前にマージリクエストの変更点を注意深くチェックしてください。API や/rebase クイックアクションを通してパイプラインをトリガーしない限り、GitLab はパイプラインを実行する前に受け入れなければならない警告を表示します。そうでなければ、警告は表示されません。

前提条件:

  • 親プロジェクトのCI/CD 設定ファイルは、マージリクエストパイプラインでジョブを実行するように設定されている必要があります。
  • CI/CD パイプラインを実行する権限を持つ親プロジェクトのメンバーである必要があります。ブランチが保護されている場合は、さらに権限が必要になるかもしれません。
  • フォークプロジェクトは、パイプラインを実行するユーザーから見えるようにしておく必要があります。そうでない場合、パイプラインタブはマージリクエストに表示されません。

UI を使用して、フォークプロジェクトからのマージリクエストに対して親プロジェクトでパイプラインを実行するには:

  1. マージリクエストでパイプラインタブに移動します。
  2. パイプラインの実行] を選択します。警告を読んで同意しないと、パイプラインは実行されません。

この機能を無効にするには、プロジェクト API を使用してci_allow_fork_pipelines_to_run_in_parent_project 設定を無効にします。デフォルトではenabled に設定されています。

利用可能な定義済み変数

マージリクエストパイプラインを使用する場合、以下の変数を使用できます:

トラブルシューティング

ブランチにプッシュする際の二つのパイプライン

マージリクエストでパイプラインが重複する場合は、パイプラインがブランチとマージリクエストの両方で同時に実行されるように設定されている可能性があります。パイプラインの重複を避けるために、パイプラインの設定を調整してください。

GitLab 13.7 以降ではworkflow:rules を追加してブランチパイプラインからマージリクエストパイプラインに切り替えることができます。ブランチでマージリクエストがオープンされると、パイプラインはマージリクエストパイプラインに切り替わります。

無効なCI/CD設定ファイルをプッシュしたときの2つのパイプライン

無効なCI/CD設定をマージリクエストのブランチにプッシュすると、パイプラインタブに失敗したパイプラインが2つ表示されます。一つは失敗したブランチパイプラインで、もう一つは失敗したマージリクエストパイプラインです。

設定構文が修正されると、失敗したパイプラインは表示されなくなります。設定の問題を見つけて修正するには、次のようにします:

マージリクエストのパイプラインは失敗とマークされましたが、最新のパイプラインは成功しました。

ブランチパイプラインとマージリクエストパイプラインの両方が、ひとつのマージリクエストのパイプラインタブに表示されることがあります。これは設定によるものかもしれませんし、偶然かもしれません。

プロジェクトに パイプラインは成功しなければなりませんが有効で、両方のパイプラインが存在する場合、ブランチパイプラインではなくマージリクエストパイプラインがチェックされます。

したがって、マージ・リクエスト・パイプラインが失敗した場合、ブランチ・パイプラインの結果とは無関係に、MRパイプラインの結果は失敗としてマークされます。

しかし

  • これらの条件は強制されません。
  • レースコンディションは、どのパイプラインの結果がマージリクエストをブロックするかパスするかを決定します。

このバグはイシュー 384927 で追跡されています。

An error occurred while trying to run a new pipeline for this merge request.

このエラーは、マージリクエストでパイプラインの実行を選択したが、プロジェクトでマージリクエストパイプラインが有効になっていない場合に発生します。

このエラーメッセージが表示される原因としては、以下のようなものが考えられます:

  • プロジェクトでマージリクエストパイプラインが有効になっておらず、パイプラインタブにパイプラインが表示されていない状態で、パイプラインの実行を選択します。
  • プロジェクトでマージ リクエスト パイプラインが有効になっていましたが、設定が削除されました。例えば

    1. マージリクエストが作成されたとき、プロジェクトは.gitlab-ci.yml 設定ファイルでマージリクエストパイプラインを有効にしています。
    2. パイプラインの実行オプションはマージリクエストのパイプラインタブで利用可能で、この時点でパイプラインの実行を選択してもエラーは発生しない可能性が高いです。
    3. プロジェクトの.gitlab-ci.yml ファイルが変更され、マージリクエストパイプライン設定が削除されます。
    4. ブランチがリベースされ、更新された設定がマージリクエストに取り込まれます。
    5. これでパイプライン設定はマージリクエストパイプラインをサポートしなくなりましたが、マージリクエストパイプラインを実行するにはパイプラインの実行を選択します。

パイプラインの実行は可能だが、プロジェクトでマージリクエストパイプラインが有効になっていない場合は、このオプションを使用しないでください。新しいブランチパイプラインを実行するには、コミットをプッシュするかブランチをリベースします。