CI/CDパイプライン

GitLab 8.8で導入されました。

Tip: ウェブキャスト“Mastering continuous software development”で、GitLab CI/CDパイプラインの包括的なデモをご覧ください。

パイプラインは、継続的なインテグレーション、デリバリ、デプロイメントのトップレベルのコンポーネントです。

パイプラインの構成は、以下のとおりです。

  • ジョブとは、をするかを定義するものです。例えば、コードをコンパイルしたり、テストしたりするジョブがあげられます。
  • ステージとは、ジョブを実行するタイミングを定義するものです。例えば、テストを実行するステージは、コードをコンパイルするステージの後に実行するなどです。

ジョブはRunnerによって実行されます。同じステージ内の複数のジョブは、同時に動作可能なRunnerがあれば並列に実行されます。

ステージ内のすべてのジョブが成功すれば、パイプラインは次のステージに進みます。

あるステージのジョブがどこかで失敗すると、一般的に次のステージは実行されず、パイプラインはそこで終了します。

通常パイプラインは自動的に実行され、一度作成されたパイプラインへ介入する必要はありません。しかし、手動でパイプラインとやり取りする場合もあります。

典型的なパイプラインは、以下の順序で実行される4つのステージで構成されています。

  • buildステージは、compileというジョブを持つ。
  • testステージは、test1test2という2つのジョブを持つ。
  • stagingステージは、deploy-to-stageと呼ばれるジョブを持つ。
  • productionステージは、deploy-to-prodと呼ばれるジョブを持つ。
Note: GitLabがプルしているミラーリポジトリがある場合は、プロジェクトの設定>リポジトリ>リモートリポジトリからのプル>ミラー更新のための、パイプラインのトリガーを有効にする必要があります。

パイプラインの種類

パイプラインは様々な方法で設定できます。

  • ベーシックパイプラインは、各ステージのすべてを同時に実行した後、次のステージに進みます。
  • DAGパイプライン(Directed Acyclic Graph Pipeline)は、ジョブ間のリレーションシップに基づいており、ベーシックパイプラインよりも高速に実行できます。
  • マルチプロジェクトパイプライン、は異なるプロジェクトのパイプラインを一緒に結合します。
  • 親子パイプラインは複雑なパイプラインを、複数の子サブパイプラインと、それらをトリガーする1つの親パイプラインに分割します。親子パイプラインはすべて、あるプロジェクトの同一コミットのSHAで実行されます。
  • マージリクエストパイプラインは、すべてのコミットではなく、マージリクエストに対してのみ実行されます。
  • マージ結果パイプラインは、ソースブランチからの変更がすでにターゲットブランチにマージされているかのように動作するマージリクエストパイプラインです。
  • マージトレインは、マージリクエストパイプラインを使用して、次々とマージをキューに入れていきます。

パイプラインの設定

パイプラインとそれを構成するジョブおよびステージは、各プロジェクトのCI/CDパイプライン設定ファイルに定義されています。

  • ジョブは基本構成要素です。
  • ステージはstagesキーワードを使用して定義します。

CIパイプラインファイルの設定オプションの一覧は、GitLab CI/CDパイプライン設定リファレンスを参照してください。

GitLab UIから、パイプラインの特定部分を設定も可能です。

パイプラインの確認

プロジェクトのCI/CD>パイプラインページで、現在および過去のパイプラインの実行状況を確認できます。またマージリクエストのパイプラインタブで、マージリクエストと紐づくパイプラインにアクセスできます。

Pipelines index page

パイプラインをクリックすると、パイプライン詳細ページが表示され、そのパイプラインで実行されたジョブが表示されます。このページでは、実行中のパイプラインのキャンセル、失敗したパイプラインのジョブを再試行、パイプラインを削除できます。

GitLab 12.3では、/project/pipelines/[branch]/latestが指定したbranchの最終コミットでの最新パイプラインへのリンクです。また、/project/pipelines/latestは、プロジェクトのデフォルトブランチでの最終コミットの最新パイプラインへリダイレクトします。

GitLab 13.0からは、パイプラインリストを次のようにフィルタリングできるようになりました。

パイプラインを手動で実行

パイプラインは、事前に定義された変数または手動で指定する変数を使用して、手動で実行できます。

パイプラインの結果(例えば、コードビルド)が、パイプラインの通常の操作以外で必要とされる場合に実行します。

パイプラインを手動で実行するには、以下手順のしたがって行います。

  1. プロジェクトのCI/CD>パイプラインに移動します。
  2. パイプライン実行ボタンをクリックします。
  3. パイプラインを実行ページで、パイプラインを実行を選択します。
    1. 実行対象フィールドで、パイプラインを実行するブランチを選択します。
    2. パイプラインの実行に必要な環境変数を入力します。
    3. パイプラインを作成ボタンをクリックします。

これで、パイプラインは設定通りにジョブを実行します。

URLクエリ文字列を使用してパイプラインを実行する

GitLab 12.5で導入されました

クエリ文字列を使用して、パイプラインを実行ページに事前に入力できます。例えば、クエリ文字列.../pipelines/new?ref=my_branch&var[foo]=bar&file_var[file_foo]=file_barとすると、パイプラインを実行ページに事前に入力されるクエリ文字列は次のようになります。

  • Run forフィールド: my_branch.
  • Variablesセクション:
    • Variable:
      • Key: foo
      • Value: bar
    • File:
      • Key: file_foo
      • Value: file_bar

pipelines/newURLの形式は、以下の通りです。

.../pipelines/new?ref=<branch>&var[<variable_key>]=<value>&file_var[<file_key>]=<value>

以下のパラメータがサポートされています。

  • ref:Run forフィールドに入力するブランチを指定します。
  • var:Variableを指定します。
  • file_var:File変数を指定します。

varまたはfile_varには、キーと値が必要です。

パイプラインへ手動アクションの追加

GitLab 8.15で導入されました

when:manualパラメータを使用して構成された手動アクションでは、パイプラインを進行させる前に手動アクションを要求できます。

これはパイプライングラフから直接行うことができ、再生ボタンをクリックするだけで特定のジョブを実行できます。

例えば、パイプラインは自動的に開始されますが、プロダクションにデプロイするには手動アクションが必要です。以下の例では、productionstageには手動アクションを持つジョブがあります。

Pipelines example

ステージ内で複数の手動アクションを開始

GitLab 11.11で導入されました

1つのステージ内の複数の手動アクションは、”Play all manual”ボタンを使用して同時に開始できます。ユーザーがこのボタンをクリックすると、個々の手動アクションがトリガーされ、更新された状態にリフレッシュされます。

この機能は、次の場合にのみ使用できます。

  • Devloper以上のアクセス権を持つユーザーの場合。
  • ステージに手動アクションを含む場合。

パイプラインを削除

GitLab 12.7で導入されました

プロジェクトのOwner権限を持つユーザーは、CI/CD>パイプラインでパイプラインをクリックしてパイプラインの詳細ページに移動し、削除ボタンを押すとパイプラインを削除できます。

Pipeline Delete Button

Warning: パイプラインを削除すると、すべてのパイプラインキャッシュが破棄されます。ビルド、ログ、アーティファクト、トリガーなどの関連するすべてのオブジェクトが削除されます。この削除を元に戻すことはできません

パイプラインクォータ

各ユーザーは、すべての個人プロジェクトの共有Runnerの使用時間を追跡する、個人パイプラインクォータを持っています。各グループには、グループ内で作成されたすべてのプロジェクトの共有Runnerの使用時間を追跡する使用量クォータがあります。

パイプラインがトリガーされると、誰がトリガーしたかに関係なく、プロジェクト所有者のネームスペースのパイプラインクォータが使用されます。この場合、ネームスペースはプロジェクトを所有するユーザーまたはグループになります。

パイプラインの実行時間の計算方法

指定されたパイプラインの総実行時間は、リトライとペンディング(キューイング)時間を除いたものです。

各ジョブはPeriodで表現されており、以下の要素で構成されます。

  • Period#first(ジョブが開始されたとき)。
  • Period#last(ジョブが終了したとき)。

簡単な例。

  • A (1, 3)
  • B (2, 4)
  • C (6, 7)

上記例は、以下のように解釈されます。

  • Aは1で始まり、3で終わる。
  • Bは2で始まり、4で終わる。
  • Cは6で始まり、7で終わる。

視覚的に表すと、以下のようになります。

0  1  2  3  4  5  6  7
   AAAAAAA
      BBBBBBB
                  CCCC

A/B/Cの和は(1,4)と(6,7)なので、総実行時間は以下のようになります。

(4 - 1) + (7 - 6) => 4

保護ブランチのパイプラインセキュリティ

パイプラインが保護ブランチ上で実行される際には、厳格なセキュリティモデルが適用されます。

保護ブランチに対して以下のアクションを許可されるのは、ユーザが対象のブランチをマージしたりプッシュしたりすることが許可されている場合のみです。

  • 手動パイプラインを実行する(Web UIまたはパイプラインAPIを使用)。
  • スケジュールされたパイプラインを実行する。
  • トリガーを使用してパイプラインを実行する。
  • 既存のパイプラインの手動アクションをトリガーする。
  • 既存のジョブを再試行またはキャンセルする(Web UIまたはパイプラインAPIを使用)。

保護変数は、保護ブランチ上で実行されるジョブでしかアクセスできません。このため信頼されていないユーザーが、デプロイの認証情報やトークンなどの機密情報へ意図せずにアクセスすることを防ぎます。

保護Runnerは、保護ブランチ上でのみジョブを実行できます。これにより、信頼されないコードが保護Runner上で実行されること、デプロイキーやその他のクレデンシャルが意図せずにアクセスされることを防ぎます。保護Runner上で実行されることを意図したジョブが通常のRunnerを使用しないようにするためには、それに応じたタグを付ける必要があります。

パイプライン内のジョブを確認

パイプラインにアクセスすると、そのパイプラインに関連するジョブが表示されます。

個々のジョブをクリックすると、そのジョブのログが表示され、次の操作が可能です。

  • ジョブをキャンセルする。
  • ジョブをやり直す。
  • ジョブのログを消去。

ジョブが失敗した理由を確認する。

GitLab 10.7で導入されました

パイプラインが失敗したり、失敗が許されたりした場合、その理由が分かる箇所がいくつかあります。

  • パイプラインの詳細ビューのパイプライングラフ
  • パイプラインウィジェット、マージリクエスト、コミットページ。
  • ジョブビュー(ジョブのグローバルビューと詳細ビュー)。

それぞれの箇所で、失敗したジョブにカーソルを合わせると、失敗した理由を見ることができます。

Pipeline detail

GitLab 10.8以降では、ジョブの詳細ページで失敗した理由も確認できます。

パイプライン内でのジョブの順番

パイプライン内のジョブの順番は、パイプライングラフの種類によって異なります。

重大度の高い順です。

  • failed
  • warning
  • pending
  • running
  • manual
  • scheduled
  • canceled
  • success
  • skipped
  • created

使用例。

Pipeline mini graph sorting

パイプラインでのグループジョブ

GitLab 8.12で導入されました

類似したジョブが多いと、パイプライングラフが長くなって読みにくくなります。

類似したジョブを自動的にグループ化できます。ジョブ名が特定の形式になっている場合、(ミニグラフではない)通常のパイプライングラフで、1つのグループにまとめて表示されます。

パイプライン内にリトライボタンやキャンセルボタンが表示されていなければ、ジョブがグループ化されているかどうかが分かります。それらの上にカーソルを置くと、グループ化されたジョブの数が表示されます。クリックして拡大します。

Grouped pipelines

ジョブのグループを作成するにはCI/CDパイプライン設定ファイルで、各ジョブ名に以下のどれかで区切った数字を設定します。

  • スラッシュ(/)。例えばtest 1/3test 2/3test 3/3など。
  • コロン(:)。例えば、test 1:3test 2:3test 3:3
  • スペース。例えばtest 0 3test 1 3test 2 3

これらの記号は互換性を持って使用できます。

例えば、これらの3つのジョブは、build rubyという名前のグループになります。

build ruby 1/3:
  stage: build
  script:
    - echo "ruby1"

build ruby 2/3:
  stage: build
  script:
    - echo "ruby2"

build ruby 3/3:
  stage: build
  script:
    - echo "ruby3"

パイプラインでは、結果は3つのジョブを持つbuild rubyというグループになります。

Job group

このジョブは左から右へ番号を比較して、順序付けされます。通常、最初の番号をインデックス、2番目の番号を合計とします。

正規表現\d+[\s:\/\\]+\d+\s*は、ジョブ名を評価します。

手動ジョブ実行時の変数の指定

GitLab 12.2で導入されました

手動ジョブを実行する際には、ジョブ固有の変数を追加で指定できます。

実行したい手動ジョブのジョブページから、変数を追加設定できます。このページにアクセスするには、パイプラインビューで手動ジョブの名前をクリックします。

また、カスタム環境変数を使用するジョブの実行を変更したい場合に便利です。 ここに変数名(キー)と値を追加すると、この手動ジョブ実行に対してUIまたは.gitlab-ci.ymlで定義されている値が上書きされます。

Manual job variables

ジョブを遅延させる

GitLab 11.4で導入されました

すぐにジョブを実行したくない場合、when:delayedパラメータでジョブの実行を一定期間遅延できます。

これは新しいコードが徐々にロールアウトされていくような、時間指定したインクリメンタルロールアウトで特に有用です。

例えば、新しいコードのロールアウトを開始したとします。

  • ユーザーにトラブルを感じさせず、GitLabは0%から100%まで自動的にデプロイを完了させることができます。
  • 新しいコードでトラブルが発生した場合は、パイプラインをキャンセルすることでローリングが最後の安定版に戻り、時間指定したインクリメンタルロールアウトを停止できます。

Pipelines example

ジョブログセクションの展開と折りたたみ

GitLab 12.0で導入されました

ジョブログは、折りたたみと展開可能なセクションに分けられており、各セクションでの実行時間が表示されます。

以下の例をご覧くだい。

  • 2つのセクションが折りたたまれていて、展開できます。
  • 3つのセクションが展開され、折りたためます。

Collapsible sections

折りたたみ可能セクションのカスタマイズ

ジョブログに折りたたみ可能なセクションを作成するには、GitLabがどのセクションを折りたたむかを決定する特別なコードを追記します。

  • セクション開始マーカー: section_start:UNIX_TIMESTAMP:SECTION_NAME_ HEADER
  • セクションエンドマーカー: section_end:UNIX_TIMESTAMP:SECTION_NAME

これらのコードをCI設定のスクリプトセクションに追加する必要があります。以下例では、echoを使用します。

job1:
  script:
    - echo -e "section_start:`date +%s`:my_first_section\r\e[0KHeader of the 1st collapsible section"
    - echo 'this line should be hidden when collapsed'
    - echo -e "section_end:`date +%s`:my_first_section\r\e[0K"

上記の例では、以下の項目を出力します。

  • date +%s: Unixのタイムスタンプ(例1560896352)。
  • my_first_section: セクションに与えられた名前。
  • \r\e[0K: レンダリングされた(色付き)ジョブログでは、セクションマーカーが表示されませんが、生のジョブログでは表示されます。表示するには、ジョブログ右上の (Show complete raw)をクリックします。
    • \r: 改行。
    • \e[0K: 行消去ANSIエスケープコード

ジョブログの生データサンプルを、以下に示します。

section_start:1560896352:my_first_section\r\e[0KHeader of the 1st collapsible section
this line should be hidden when collapsed
section_end:1560896353:my_first_section\r\e[0K

パイプラインの可視化

GitLab 8.11で導入されました

パイプラインは、多くの順次実行ジョブや並列実行ジョブを含む複雑な構造になりえます。

パイプラインの流れをよりわかりやすくするために、GitLabにはパイプラインとその状態を見るためのパイプライングラフがあります。

パイプライングラフは、アクセスしたページによって2種類の表示方法があります。

Note: GitLabはパイプライングラフのステージ名を大文字にしています。

通常のパイプライングラフ

通常のパイプライングラフには、各ステージのジョブ名が表示されます。通常のパイプライン グラフは、単一のパイプラインページで表示されます。例えば、次のように表示されます。

Pipelines example

マルチプロジェクトパイプライングラフは、すべてのプロジェクト間の相互依存関係を含むパイプライン全体を視覚化するのに役立ちます。

パイプラインミニグラフ

パイプラインミニグラフは場所を取らず、すべてのジョブが成功したのか失敗したのかが一目でわかるようになっています。パイプラインミニグラフは、以下の場所に移動すると表示されます。

  • パイプラインの一覧画面。
  • コミットの詳細画面。
  • マージリクエストの詳細画面。

パイプラインのミニグラフでは、1つのコミットに関連するすべてのジョブと、パイプラインの各ステージの最終結果を表示できます。これにより、何が失敗したのかを素早く確認し、修正できます。

パイプラインのミニグラフのステージは折りたたむことができ、マウスを重ねてクリックするとジョブが展開されます。

ミニグラフ 展開したミニグラフ
Pipelines mini graph Pipelines mini graph extended

パイプラインの成功と実行時間のチャート

  • GitLab 3.1.1.1でコミット統計として導入され、後にパイプラインチャートに改名されました。
  • GitLab 12.8でCI/CD分析に改名されました。

GitLabは、パイプラインの成功・失敗の履歴と、各パイプラインの実行時間を追跡できます。この情報を表示するには、分析 > CI/CD分析を選択します。

成功したパイプラインの表示。

Successful pipelines

パイプライン実行期間の履歴表示。

Pipeline duration

パイプラインバッジ

パイプラインステータスとテストカバレッジレポートバッジは、プロジェクトごとに利用と設定が可能です。プロジェクトへのパイプラインバッジの追加については、パイプラインバッジを参照してください。

パイプラインAPI

GitLabはAPIエンドポイントを提供しています。

トラブルシューティングfatal: reference is not a tree:

GitLab 12.4で導入されました

以前はブランチをリモートリポジトリに強制的にプッシュすると、予期せぬパイプラインの障害が発生することがありました。次のようなワークフローで、問題を説明します。

  1. ユーザーがexampleという名前のフィーチャーブランチを作成し、それをリモートリポジトリにプッシュします。
  2. exampleブランチで、新しいパイプラインの実行を開始します。
  3. ユーザーはexampleブランチを最新のmasterブランチにリベースし、リモートリポジトリに強制的にプッシュします。
  4. 新しいパイプラインが再びexampleブランチ上で実行を開始しますが、前のパイプライン(2)はfatal: reference is not a tree:エラーのために失敗します。

これは、前のパイプラインが(パイプラインレコードに関連付けられている)チェックアウトSHAを見つけることができないためです。ブランチから、コミット履歴がすでに強制プッシュで上書きされていることをexampleブランチから確認してください。同様に、マージ結果パイプラインが、同じ理由で断続的に失敗する可能性があります。

GitLab 12.4では、パイプラインの参照を排他的に保持することで、この動作を改善しました。

  1. exampleという名前のフィーチャブランチにパイプラインが作成されます。
  2. 永続的なパイプライン参照がrefs/pipelines/<pipeline-id>として作成され、関連するパイプラインレコードのチェックアウトSHAを保持します。この永続的な参照は、exampleブランチのコミット履歴が強制プッシュによって上書きされた場合でも、パイプライン実行中はそのままの状態で維持されます。
  3. GitLab Runnerは永続的なパイプライン参照を取得し、チェックアウトSHAからソースコードを取得します。
  4. パイプラインが終了すると、その永続的な参照はバックグラウンドプロセスでクリーンアップされます。