マージトレイン
- プラン: Premium、Ultimate
- 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated
デフォルトブランチへのマージが頻繁に行われるプロジェクトでは、異なるマージリクエストの変更が互いに競合する可能性があります。マージトレインを使用して、マージリクエストをキューに入れます。各マージリクエストが、それ以前にキューに入れられた他のマージリクエストと比較され、すべてが整合して動作することを確認できます。
1つのマージリクエストの変更とターゲットブランチを組み合わせてテストするマージ結果パイプライン。マージ結果パイプラインは、ほぼ同時にマージされる他のマージリクエストを考慮しません。2つのマージリクエストはそれぞれ独自のパイプラインに合格できますが、それらの結合された変更はまだ競合する可能性があります。両方がマージされた場合、すべてのパイプラインが成功しても、ターゲットブランチが壊れる可能性があります。
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: Two merge requests that pass individually but conflict together
accDescr: Merge request A and merge request B each pass a pipeline that tests their changes combined with the target branch alone. When both merge, the combined changes break the target branch.
subgraph Without merge trains
target[Target branch] --> pipeline_a[Pipeline for A: passes]
target --> pipeline_b[Pipeline for B: passes]
pipeline_a --> merge_both[Both merge]
pipeline_b --> merge_both
merge_both -.-> broken[Target branch breaks]
end
マージトレインは、各マージリクエストをキュー内のその前にあるすべてのマージリクエストの結合された変更に対してテストすることで、これを防ぎます。これにより、ターゲットブランチに到達する前に競合を捕捉します。
プロジェクトが次のいずれかの場合は、マージトレインを使用します:
- デフォルトブランチへの頻繁なマージ
- ほぼ同時にマージする準備ができている複数のマージリクエスト
- 常にデフォルトブランチでパイプラインをパスし続ける要件
マージトレインワークフロー
マージを待機しているマージリクエストがなく、マージまたは自動マージに設定を選択すると、マージトレインが開始されます。GitLabは、変更がデフォルトブランチにマージできることを確認するマージトレインパイプラインを開始します。この最初のパイプラインはマージ結果パイプラインと同じで、ソースブランチとターゲットブランチを組み合わせた変更に対して実行されます。内部マージ結果コミットの作成者は、マージを開始したユーザーです。
最初のパイプラインが完了した直後にマージする2番目のマージリクエストをキューに入れるには、マージまたは自動マージに設定を選択して、トレインに追加します。この2番目のマージトレインパイプラインは、ターゲットブランチと組み合わせた_両方_のマージリクエストの変更に対して実行されます。同様に、3番目のマージリクエストを追加すると、そのパイプラインは、ターゲットブランチとマージされた3つのマージリクエストすべての変更に対して実行されます。パイプラインはすべて並行して実行されます。
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: Merge train pipelines test combined changes
accDescr: Pipeline 1 tests merge request A against the target branch. Pipeline 2 tests merge request A and B together against the target branch. Pipeline 3 tests merge request A, B, and C together against the target branch. The three pipelines run in parallel.
subgraph Merge train
target[Target branch] --> pipeline_1[Pipeline 1: A]
target --> pipeline_2[Pipeline 2: A + B]
target --> pipeline_3[Pipeline 3: A + B + C]
end
各マージリクエストは、以下の場合にのみターゲットブランチにマージされます。
- マージリクエストのパイプラインが正常に完了した場合。
- その前にキューに入れられた他のすべてのマージリクエストがマージされた場合。
マージトレインパイプラインが失敗した場合、マージリクエストはマージされません。GitLabはそのマージリクエストをマージトレインから削除し、その後にキューに入れられたすべてのマージリクエストに対して新しいパイプラインを開始します。
例:
3つのマージリクエスト(A、B、およびC)が順番にマージトレインに追加され、並行して実行される3つのマージ結果パイプラインが作成されます。
- 最初のパイプラインは、
Aからの変更とターゲットブランチを組み合わせて実行されます。 - 2番目のパイプラインは、
AとBからの変更とターゲットブランチを組み合わせて実行されます。 - 3番目のパイプラインは、
A、B、およびCからの変更とターゲットブランチを組み合わせて実行されます。
Bのパイプラインが失敗した場合:
- 最初のパイプライン(
A)は引き続き実行されます。 Bがトレインから削除されます。Cのパイプラインはキャンセルされ、AとCからの変更とターゲットブランチを組み合わせた新しいパイプラインが(Bの変更なしで)開始されます。
次に、Aが正常に完了すると、ターゲットブランチにマージされ、Cの実行が継続されます。トレインに追加された新しいマージリクエストには、ターゲットブランチにあるAの変更と、マージトレインからのCの変更が含まれます。
マージトレインの並列実行によってコミットがデフォルトブランチを破損するのを防ぐ方法のデモについては、このビデオをご覧ください。
自動パイプラインキャンセル
GitLab CI/CDは、冗長なパイプラインを検出し、リソースを節約するためにそれらをキャンセルします。
冗長なマージトレインパイプラインは、以下の場合に発生します。
- マージトレイン内のいずれかのマージリクエストでパイプラインが失敗した場合。
- マージトレインをスキップしてすぐにマージする場合。
- マージトレインからマージリクエストを削除する場合。
これらの場合、GitLabはトレイン上の一部のまたはすべてのマージリクエストに対して新しいマージトレインパイプラインを作成する必要があります。古いパイプラインは、マージトレイン内の以前の結合された変更と比較していましたが、これはもはや有効ではないため、これらの古いパイプラインはキャンセルされます。
マージトレインを有効にする
前提条件:
- メンテナーのロールを持っている必要があります。
- リポジトリは、外部リポジトリではなく、GitLabリポジトリである必要があります。
- パイプラインがマージリクエストパイプラインを使用するように設定されている必要があります。そうでない場合、マージリクエストが未解決の状態でスタックしたり、パイプラインがドロップされたりする可能性があります。
- マージ結果パイプラインが有効になっている必要があります。
マージトレインを有効にするには:
- 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
- 左側のサイドバーで、設定 > マージリクエストを選択します。
- マージオプションセクションで、マージ結果パイプラインを有効にするが有効になっていることを確認し、マージトレインを有効にするを選択します。
- 変更を保存を選択します。
マージトレインを開始する
前提条件:
- ターゲットブランチにマージまたはプッシュする権限が必要です。
マージトレインを開始するには:
- マージリクエストに移動します。
- 次を選択します:
- パイプラインが実行されていない場合は、マージ。
- パイプラインが実行されている場合は、自動マージに設定。
マージリクエストのマージトレイン状態が、A new merge train has started and this merge request is the first of the queue. View merge train details.のようなメッセージとともにパイプラインウィジェットの下に表示されます。リンクを選択して、マージトレインを表示できます。
他のマージリクエストをトレインに追加できるようになりました。
マージトレインを表示する
マージトレインを表示して、キュー内のマージリクエストの順序と状態をより詳細に把握できます。マージトレインの詳細ページには、キュー内のアクティブなマージリクエストと、トレインの一部であったマージ済みのマージリクエストが表示されます。
マージリクエストのリストからマージトレインの詳細にアクセスするには:
- 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
- 左側のサイドバーで、コード > マージリクエストを選択します。
- マージリクエストのリストの上にあるマージトレインを選択します。
- オプション。ターゲットブランチでマージトレインをフィルタリングします。
次の場所からマージトレインの詳細を表示を選択して、このビューにアクセスすることもできます。
- マージトレインに追加されたマージリクエストのパイプラインウィジェットとシステムノート。
- マージトレインパイプラインのパイプライン詳細ページ。
マージトレインの詳細ビューからマージリクエストを削除( )することもできます。
マージリクエストをマージトレインに追加する
前提条件:
- ターゲットブランチにマージまたはプッシュする権限が必要です。
マージリクエストをマージトレインに追加するには:
- マージリクエストにアクセスします。
- 次を選択します:
- パイプラインが実行されていない場合は、マージ。
- パイプラインが実行されている場合は、自動マージに設定。
マージリクエストのマージトレイン状態が、This merge request is 2 of 3 in queue.のようなメッセージとともにパイプラインウィジェットの下に表示されます
各マージトレインは、最大数のパイプラインを並行して実行できます。デフォルトの制限は20です。制限を超えてマージトレインにマージリクエストを追加した場合、追加のマージリクエストはパイプラインが完了するまでキューに入れられます。キューに入れられるマージリクエストの数に制限はありません。
マージリクエストがマージトレインに参加した後、新しい会話スレッドは、すべてのスレッドが解決する必要があるが有効になっている場合でも、それをトレインから削除したり、マージを妨げたりすることはありません。この動作は意図的なものです。詳細については、イシュー220916を参照してください。
マージトレインからマージリクエストを削除する
マージリクエストをマージトレインから削除すると:
- 削除されたマージリクエストの後にキューに入れられたマージリクエストのすべてのパイプラインが再起動します。
- 冗長なパイプラインはキャンセルされます。
後でマージリクエストをマージトレインに再度追加できます。
マージリクエストをマージトレインから削除するには:
- マージリクエストから自動マージをキャンセルを選択します。
- マージトレインの詳細から、マージリクエストの横にある を選択します。
マージトレインをスキップして、今すぐマージする
緊急にマージする必要がある重要なパッチのような優先度の高いマージリクエストがある場合は、すぐにマージを選択できます。
今すぐマージすると、多くのCI/CDリソースを消費する可能性があります。このオプションは、重大な状況でのみ使用してください。
マージリクエストをすぐにマージすると:
- マージリクエストからのコミットが、マージトレインの状態を無視してマージされます。
- トレイン上の他のすべてのマージリクエストのマージトレインパイプラインはキャンセルされます。
- 新しいマージトレインが開始され、元のマージトレインからのすべてのマージリクエストがこの新しいマージトレインに追加され、それぞれに新しいマージトレインパイプラインが追加されます。これらの新しいマージトレインパイプラインには、すぐにマージされたマージリクエストによって追加されたコミットが含まれるようになりました。
merge immediatelyオプションは、プロジェクトが早送りマージメソッドを使用しており、ソースブランチがターゲットブランチよりも遅れている場合、利用できない場合があります。詳細については、イシュー434070を参照してください。
マージトレインのパイプラインを再起動せずにマージする
- ステータス: 実験的機能
GitLab Self-Managedでは、デフォルトでこの機能が利用可能です。この機能を非表示にするために、管理者はmerge_trains_skip_trainという名前の機能フラグを無効にできます。GitLab.comおよびGitLab Dedicatedでは、この機能を使用できます。
実行中のマージトレインを完全に再起動せずに、マージリクエストをマージできます。この機能を使用すると、パイプラインを安全にスキップできる変更(たとえば、マイナーなドキュメントの更新)をすばやくマージできます。
早送りまたは半線形のマージ方法では、マージトレインをスキップできません。詳細については、イシュー429009を参照してください。
マージトレインのスキップは実験的な機能です。今後のリリースで変更または完全に削除される可能性があります。
この機能を使用してセキュリティ修正またはバグ修正を迅速にマージできますが、トレインをスキップしたマージリクエストの変更は、トレイン内の他のどのマージリクエストに対しても検証されません。これらの他のマージトレインパイプラインが正常に完了してマージされた場合、結合された変更に互換性がないリスクがあります。その後、ターゲットブランチで新しい不具合を解決するために追加の作業が必要になる可能性があります。
前提条件:
- メンテナーのロールを持っている必要があります。
- マージトレインが有効になっている必要があります。
パイプラインを再起動せずにトレインのスキップを有効にするには:
- 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
- 左側のサイドバーで、設定 > マージリクエストを選択します。
- マージオプションセクションで、マージ結果パイプラインを有効にするオプションとマージトレインを有効にするオプションが有効になっていることを確認します。
- マージトレインを再起動せずに即時マージするを選択します。
- 変更を保存を選択します。
マージトレインをスキップしてマージリクエストをマージするには、属性skip_merge_trainをtrueに設定してマージするマージリクエストマージAPIエンドポイントを使用します。
マージリクエストがマージされ、既存のマージトレインパイプラインはキャンセルまたは再起動されません。
マージトレインの並列パイプライン制限
デフォルトでは、各マージトレインは最大20のパイプラインを並行して実行できます。この制限に達すると、パイプラインが完了するまで追加のマージリクエストがキューに入れられます。
プロジェクトのこの制限を変更するには:
- 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
- 左側のサイドバーで、設定 > マージリクエストを選択します。
- マージオプションセクションで、マージトレインごとの最大並列パイプライン数の値を設定します。最小値は
1です。1の値は、並列処理なしでマージリクエストを順次処理します。 - 変更を保存を選択します。
プロジェクトの制限は、インスタンスの制限を超えることはできません。
プロジェクトAPI、またはGraphQL APIを使用することもできます。
マージトレインを適用する
デフォルトでは、マージする権限がある場合、マージトレインをバイパスすることができます。適用には、すべてのマージリクエストがトレインを経由する必要があります。
適用が有効な場合:
- GitLabは、今すぐマージして、続きを再開しないを含む今すぐマージするオプションを非表示にします。
- REST APIとGraphQL APIは、直接的なマージを拒否します。
- 自動マージは、すべてのマージをトレインにルーティングします。
マージトレインの適用には3つのレベルがあります:
- バイパスを許可 (デフォルト): マージ権限を持つユーザーは、UIまたはAPIを介してマージトレインをバイパスすることができます。
- すべてのユーザーに適用: すべてのマージリクエストはマージトレインを経由する必要があります。オーナーや管理者を含め、誰もマージトレインをバイパスすることはできません。
- オーナーによる上書きを許可して適用: すべてのマージリクエストはマージトレインを経由する必要がありますが、オーナーと管理者は個々のマージリクエストに対してマージトレインをバイパスすることができます。
前提条件:
- メンテナーのロールを持っている必要があります。
- プロジェクトのマージトレインを有効にする必要があります。
プロジェクトのこの制限を変更するには:
- 上部のバーで、検索または移動先を選択して、プロジェクトを見つけます。
- 左側のサイドバーで、設定 > マージリクエストを選択します。
- マージオプションセクションのマージトレインの適用で、適用レベルを選択します。
- 変更を保存を選択します。
トラブルシューティング
マージトレインから削除されたマージリクエスト
マージトレインパイプラインの実行中にマージリクエストがマージできなくなった場合、マージトレインはマージリクエストを自動的にドロップします。一般的な原因は次のとおりです:
- マージリクエストをドラフトに変更する。
- マージの競合。
マージリクエストがマージトレインから削除された理由は、システムノートで確認できます。概要タブのアクティビティセクションで、User removed this merge request from the merge train because ...のようなメッセージを確認してください
自動マージを使用できません
マージトレインが有効になっている場合、マージトレインをスキップするために自動マージ(以前のパイプラインが成功したらマージ)を使用できません。詳細については、イシュー12267を参照してください。
マージトレインのパイプラインを再試行できません
マージトレインパイプラインが失敗すると、マージリクエストがトレインから削除され、パイプラインが失敗した後に再試行できなくなります。マージトレインパイプラインは、マージリクエストの変更と、すでにトレイン上にある他のマージリクエストからの変更のマージされた結果に対して実行されます。マージリクエストがトレインから削除されると、マージされた結果が古くなり、パイプラインを再試行できなくなります。
次のことができます:
- マージリクエストをトレインに再度追加します。これにより、新しいパイプラインがトリガーされます。
- ジョブが断続的に失敗する場合は、ジョブに
retryキーワードを追加します。再試行後に成功した場合、マージリクエストはマージトレインから削除されません。
マージトレインにマージリクエストを追加できません
パイプラインが成功する必要があるが有効になっているが、最新のパイプラインが失敗した場合:
- 自動マージに設定またはマージオプションは使用できません。
- マージリクエストには
The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure.が表示されます
マージリクエストをマージトレインに再度追加する前に、次のことを試すことができます:
- 失敗したジョブを再試行します。合格し、他のジョブが失敗しなかった場合、パイプラインは成功としてマークされます。
- パイプライン全体を再実行します。パイプラインタブで、パイプラインの実行を選択します。
- イシューを修正する新しいコミットをプッシュします。これにより、新しいパイプラインもトリガーされます。
詳細については、イシュー35135を参照してください。
自動化ツールが405エラーでマージに失敗する
マージトレインの適用が有効な場合、auto_merge=trueなしでマージリクエストAPIを呼び出すツールは、405 Method Not Allowed応答を受け取ります。これには、スクリプト、CI/CDジョブ、およびボットが含まれます。
これを解決するには、ツールを更新してauto_merge=trueを渡すようにします。これにより、マージリクエストが直接マージされるのではなく、マージトレインに追加されます。例えば、Renovateを使用している場合は、platformAutomerge設定オプションを有効にします。