皆様こんにちは。SEの小池と申します。
以前、GitLabのCI/CDパイプラインのキーワード解説で stages
を取り上げました。(こちら)
ほぼ筆者の自習メモと化しているキーワード解説記事の第4弾をお送りいたします。
今回はキーワード rules の概要と具体例を用いた説明をします。
- 本記事の対象の方
- 今回のブログのゴール
- このブログをお読みいただくにあたっての事前ご連絡事項
- キーワード rules の概要
- 【補足】rules:when の設定値に関して
- rules の超簡単な使い方の例
- 最後に
本記事の対象の方
- GitLabのCI/CDパイプラインのジョブに、"if" のような実行条件を設定したい方。
- GitLabのCI/CDパイプラインのキーワード
rules
について情報収集中の方。
今回のブログのゴール
このブログのゴールはこちらです。
- GitLabのCI/CDパイプラインのキーワード rules の概要を把握する。
このブログをお読みいただくにあたっての事前ご連絡事項
- 本記事はSaaS版 (GitLab.com) の Enterprise Edition 15.10.0-pre における仕様をベースに記載しております。それ以外のエディションやバージョンではこの記事に記載の通りではない可能性がございます。
- 本記事はGitやCI/CDに関する知識ゼロのSEによるなんちゃって記事です。GitLabのディープな使用法についてはGitLabの公式オンラインドキュメント (こちら) をご参照ください。
キーワード rules の概要
rules
は、CI/CDパイプラインにそのジョブを含めるか除外するかを設定する、ジョブレベルのキーワードです。
参考 : '.gitlab-ci.yml' keyword reference | GitLab
例えば、コミット先のブランチが "main" の時のみ実行したい ジョブB があるとします。
こんなときに使用できるのがrules
です。
ジョブBにrules
を使って、「コミット先のブランチが "main" だった場合」という条件を設定します。
具体的な.gitlab-ci.yml
ファイルの書き方は後述致します。
これによりこのCI/CDパイプラインは、コミット先ブランチが "main" のときは ジョブA, B, C を実行し、コミット先ブランチが "main" 以外の場合は ジョブA, C を実行します。
(rules
はパイプライン作成時に評価され、該当しない場合はそもそもそのジョブ自体が作成されません。)
この様に、CI/CDパイプラインにそのジョブを含めるか除外するかを設定できるのがrules
です。
あくまでジョブを作成するか否かを判定するキーワードなので、1つのジョブの中で実行する処理に条件分岐を付けることはできません。
例えば以下の図のように、ジョブBで 「コミット先が "main" だった場合は処理●●、コミット先が "develop" だったら処理□□をする。」というような条件は設定できません。
仮に「コミット先が "main" だった場合は処理●●、コミット先が "develop" だったら処理□□をする。」を実現したい場合は、ジョブを2個に分けることで実装できます。
rules
は単体ではなく、以下のキーワードの内の1つ もしくは 複数と併せて使用します。
キーワード | 概要 |
---|---|
if | 変数の値について真偽を判定し、ジョブを作成する (真) or しない (偽) を制御します。 |
changes | 特定のファイルに変更があったかを判定し、ジョブを作成する (真) or しない (偽) を制御します。 |
exists | リポジトリにあるファイルの存在を判定し、ジョブを作成する (真) or しない (偽) を制御します。 |
allow_failure | 前のステージで失敗するジョブがあっても、このジョブを実行させます。true (実行させる) または false (実行しない)で指定します。本キーワードを設定していない場合は、デフォルト値 false が適用されます。本キーワードの設定はCI/CDパイプライン作成時点で真偽を判定できないため、実行される/実行されないを問わず、ジョブ自体は作成されます。 |
variables | 変数を定義します。 単独でも利用可能ですが、 if などと併用して、「条件Aを満たす場合は、変数 $ABC の値を true にする。」といった風に使うことが想定されます。 |
when | ジョブがいつ実行されるかの条件を設定します。on_success , manual , always , on_failure , delayed または never を指定します。(それぞれの詳細は後述致します。) 本キーワードを設定していない場合は、デフォルト値 on_success が適用されます。本キーワードは never を設定している場合を除き、CI/CDパイプライン作成時点で真偽を判定できないため、実行される/実行されないを問わずジョブ自体は作成されます。
|
上記のサブキーワードを複数設定することで、より複雑な条件を設定することもできます。
複数指定の例は本記事でも紹介いたしますが、GitLab Docs (こちら) にたくさんのサンプルが載っているので、参考になるかと存じます。
参考:Choose when to run jobs - Complex rules | GitLab
以上がキーワードrules
の概要でした。
【補足】rules:when の設定値に関して
前章の表1で記載致しました、rules:when
の設定値について少しだけ補足いたします。
というか補足として書いておかないと筆者はすぐ忘れるので、書きます。
そもそもGitLabのCI/CDパイプライン (デフォルト設定) は、前のステージのジョブが全て成功で終了してから、次のステージのジョブが開始される、という仕様になっています。
この仕様を無視することができるキーワードはいくつか存在しますが、そのうちの1つがrules:when
です。
rules:when
で指定できる値は、on_success
(デフォルト値) , manual
, always
, on_failure
, delayed
または never
です。多い…。
それぞれの概要は以下の通りです。
参考:'.gitlab-ci.yml' keyword reference - when | GitLab
設定値 | 概要 |
---|---|
on_success | この値を指定したジョブは、以下のどちらか1つ以上を満たすと実行されます。
明示的に rules:when を設定していない場合、この値が暗黙的に適用されます。
|
manual | この値を設定したジョブは、自動では実行されず、手動でトリガーされたときのみ実行されます。 |
always | この値を設定したジョブは、前のステージのジョブの終了ステータス (成功/失敗) に関係なく実行されます。 |
on_failure | この値を指定したジョブは、以下のどちらか1つ以上を満たすと実行されます。
|
delayed | この値を指定したジョブは、指定した時間 (1秒~1週間) だけ遅延して実行されます。 |
never | この値を指定したジョブは、CI/CDパイプライン開始時に作成されません。 |
rules の超簡単な使い方の例
ここからは実際にキーワードrules
の使い方を、サブキーワード毎に紹介してまいります。
いつものごとく、ここで紹介する例は入門者 (筆者) レベルです!
特定の変数の値によって、ジョブを作成する or しない (rules:if
)
rules:if
を使って特定の変数の値をチェックし、真であればジョブを作成・実行し、偽であればジョブを作成しないCI/CDパイプラインの例を紹介いたします。
例として、既定の変数CI_COMMIT_REF_NAME
を用いて、「コミット先ブランチが "main" だった場合のみジョブAを実行する」ようなCI/CDパイプライン (下図) を作成します。
上の図のCI/CDパイプラインの.gitlab-ci.yml
はこうなります。
stages: - stage_1 - stage_2 job_A: stage: stage_1 rules: - if: $CI_COMMIT_REF_NAME == "main" script: echo "ジョブAです。コミット先が main だった時のみ実行されます。" job_B: stage: stage_2 script: echo "ジョブBです。"
上記のCI/CDパイプラインを実行させます。
まず、コミット先のブランチが "main" だった場合、上記のCI/CDパイプラインは以下の通りとなります。
ジョブAが作成・実行されていることがわかります。
コミット先のブランチが "main" 以外だった場合、上記のCI/CDパイプラインは以下の通りとなります。
ジョブAは作成されていないことがわかります。
rules:if
を使って特定の変数の値をチェックし、ジョブを作成する or しない例は以上です。
特定のファイルに対する変更の有無によって、ジョブを作成する or しない (rules:changes
)
rules:changes
を使って特定のファイルに対する変更の有無をチェックし、変更があれば (真であれば) ジョブを作成・実行し、変更が無ければ (偽であれば) ジョブを作成しないCI/CDパイプラインの例を紹介いたします。
例として、「リポジトリのルートにあるREADME.md
に変更があった場合のみジョブAを実行する」ようなCI/CDパイプライン (下図) を作成します。
上の図のCI/CDパイプラインの.gitlab-ci.yml
はこうなります。
stages: - stage_1 - stage_2 job_A: stage: stage_1 rules: - changes: - README.md script: echo "ジョブAです。README.mdが変更されたときのみ実行されます。" job_B: stage: stage_2 script: echo "ジョブBです。"
上記のCI/CDパイプラインを実行させます。
まず、README.md
に変更があった場合、上記のCI/CDパイプラインは以下の通りとなります。
ジョブAが作成・実行されていることがわかります。
README.md
に変更がなかった場合、上記のCI/CDパイプラインは以下の通りとなります。
ジョブAは作成されていないことがわかります。
rules:changes
を使って特定のファイルに対する変更の有無をチェックし、ジョブを作成する or しない例は以上です。
特定のファイルの存在有無によって、ジョブを作成する or しない (rules:exists
)
rules:exists
を使って特定のファイルの存在有無をチェックし、有れば (真であれば) ジョブを作成・実行し、無ければ (偽であれば) ジョブを作成しないCI/CDパイプラインの例を紹介いたします。
例として、「リポジトリのルートにREADME.md
が存在する場合のみジョブAを実行する」ようなCI/CDパイプライン (下図) を作成します。
上の図のCI/CDパイプラインの.gitlab-ci.yml
はこうなります。
stages: - stage_1 - stage_2 job_A: stage: stage_1 rules: - exists: - README.md script: echo "ジョブAです。README.mdが存在するときのみ実行されます。" job_B: stage: stage_2 script: echo "ジョブBです。"
上記のCI/CDパイプラインを実行させます。
まず、リポジトリのルートのREADME.md
に変更があった場合、上記のCI/CDパイプラインは以下の通りとなります。
ジョブAが作成・実行されていることがわかります。
リポジトリのルートのREADME.md
に変更がなかった場合、上記のCI/CDパイプラインは以下の通りとなります。
ジョブAは作成されていないことがわかります。
rules:exists
を使って特定のファイルの存在有無をチェックし、ジョブを作成する or しない例は以上です。
前のステージのジョブが失敗しても、ジョブを実行させる (rules:allow_failure
)
rules:allow_failure
を使って、前のステージのジョブが失敗しても、ジョブを実行させる例を紹介いたします。
例として、「ステージ1で失敗したジョブがあっても、ステージ2のジョブBは実行させる」というCI/CDパイプライン (下図) を作成します。
上の図のCI/CDパイプラインの.gitlab-ci.yml
はこうなります。
なお、今回はrules:allow_failure
のテストをしたいので、意図的にジョブAを失敗させます。
11行目にあるコマンドo-na-ka-su-i-ta
は存在しないコマンドなので、ここが原因でジョブAは失敗します。
stages: - stage_1 - stage_2 job_A: stage: stage_1 rules: - allow_failure: true script: - echo "ジョブAです。このジョブが失敗しても、ジョブBは実行されます。" - o-na-ka-su-i-ta job_B: stage: stage_2 script: echo "ジョブBです。"
上記をそのまま (11行目をコメントアウトせず) CI/CDパイプラインを実行させます。
すると、ステージ1のジョブAは失敗しているにもかかわらず、ステージ2のジョブBが実行されていることがわかります。
通常、GitLabのCI/CDパイプラインは、前のステージのジョブが全て成功して終了しないと、次のステージのジョブは実行されません。
なお、前のステージのジョブが全て成功で終了した場合、alllow_failure:true
が設定されたジョブは通常通り作成・実行されます。
したがって、先述の.gitlab-ci.yml
の11行目をコメントアウトして実行した場合、下図の通りジョブBは通常通り作成・実行されます。
rules:allow_failure
を使って、前のステージのジョブが失敗しても、ジョブを実行させる例は以上です。
特定の条件を満たす場合に、変数を設定する (rules:variables
)
rules:if
とrules:variables
を使って、rules:if
の判定が真であれば、特定の変数の値を変更し 且つ ジョブを作成・実行する例を紹介いたします。
例として、既定の変数CI_COMMIT_REF_NAME
を用いてコミット先ブランチを判定し、「コミット先のブランチが "main" だった場合、変数SAMPLE_ENV
の値をo-ya-tsu
に変更し 且つ ジョブAを実行する」というCI/CDパイプライン (下図) を作成します。
上の図のCI/CDパイプラインの.gitlab-ci.yml
はこうなります。
ジョブAに設定したrules:valiables
の効果を確認するために、6行目でグローバル変数SAMPLE_ENV
の値をgo-ha-n
に設定しています。
stages: - stage_1 - stage_2 variables: SAMPLE_ENV: "go-ha-n" job_A: stage: stage_1 rules: - if: $CI_COMMIT_REF_NAME == "main" variables: SAMPLE_ENV: "o-ya-tsu" script: - echo "ジョブAです。" - echo $SAMPLE_ENV job_B: stage: stage_2 script: - echo "ジョブBです。" - echo $SAMPLE_ENV
上記のCI/CDパイプラインを実行させます。
まず、コミット先ブランチが "main" だった場合、上記のCI/CDパイプラインは以下の通りとなります。
ジョブAのログをみると、変数SAMPLE_ENV
のecho
の出力がo-ya-tsu
になっていることがわかります。
この.gitlab-ci.yml
の場合、6行目で変数SAMPLE_ENV
の値をgo-ha-n
にしていますが、ジョブA内ではrules:valiables
の効果で値が変更されたことが確認できます。
rules:if
の判定が真であれば、特定の変数の値を変更し 且つ ジョブを作成・実行する例は以上です。
特定の条件を満たす場合に、手動実行でジョブを作成する (rules:when
)
rules:if
とrules:when
を使って、rules:if
の判定が真であれば、手動実行でジョブを作成する例を紹介いたします。
なおこの例ではrules:if
の判定が偽であれば、rules:when
を設定したジョブは作成されません。
既定の変数CI_COMMIT_REF_NAME
を用いてコミット先ブランチを判定し、「コミット先ブランチが "main" だった場合は、ジョブBをトリガーを手動実行にして作成する」ようなCI/CDパイプライン (下図) を作成します。
上の図のCI/CDパイプラインの.gitlab-ci.yml
はこうなります。
stages: - stage_1 - stage_2 job_A: stage: stage_1 script: - echo "ジョブAです。" job_B: stage: stage_2 rules: - if: $CI_COMMIT_REF_NAME == "main" when: manual script: - echo "ジョブBです。コミット先ブランチがmainなら、手動実行で作成されます。コミット先ブランチがmain以外なら、作成されません。"
上記のCI/CDパイプラインを実行させます。
まず、コミット先のブランチが "main" だった場合、上記のCI/CDパイプラインは以下の通りとなります。
ステージ2のジョブBが自動実行されず、手動による実行待ちになっていることがわかります。
コミット先のブランチが "main" 以外だった場合、上記のCI/CDパイプラインは以下の通りとなります。
ジョブBが作成されていないことがわかります。
rules:if
とrules:when
を使って、rules:if
の判定が真であれば、手動実行でジョブを作成する例は以上です。
最後に
この度はGitもCI/CDもよくわかっていないど素人SEによるGitLab検証ブログをお読みいただき、誠にありがとうございます。
このブログの目標は以下のとおりでしたが、皆さまはいかがでしたでしょうか。
- GitLabのCI/CDパイプラインのキーワード rules の概要を把握する。
CI/CDパイプラインで条件分岐のようなことをしたい場合、rules は避けて通れないキーワードです。
とはいえ、rulesでどんな条件分岐も作成できる!・・・というわけではないので、最初はサブキーワードをご確認いただき、実装可能な方向性を模索いただければと存じます。
この記事がGitLabを触り始めた方の一助となれば幸いにございます。
GitLabに関するお問い合わせは、以下のフォームからお願い致します。
GitLab製品 お問い合わせ
GitLab操作デモ動画 (基本編) を作ってみました。(音声の録音は自宅でiPhoneのボイスメモ使うという超低クオリティですが…。)
つたない内容ではありますが、ご興味がおありでしたら是非ご視聴いただければと存じます。