-
ジョブが実行されるタイミングは
rules
-
ジョブの実行時に
only
とexcept
- 手動で実行するジョブの作成
- 遅延後のジョブの実行
- 大規模ジョブの並列化
- 複数の並列ジョブを持つニーズを使用した並列ジョブの指定
- 定義済みの CI/CD 変数を使用して、特定のパイプラインタイプでのみジョブを実行します。
- 正規表現
- CI/CD 変数式
- トラブルシューティング
ジョブを実行するタイミングの選択
新しいパイプラインが開始されると、GitLabはパイプラインの設定をチェックし、そのパイプラインで実行すべきジョブを決定します。変数の状態やパイプラインの種類などに応じて実行するジョブを設定することができます。
特定のパイプラインにジョブを含めるか除外するかを設定するには、rules
を使います。
needs
を使用して、依存する先のジョブが実行を終了したらすぐに実行するようにジョブを設定します。
ジョブが実行されるタイミングはrules
GitLab 12.3 で導入されました。
rules
を使ってパイプラインにジョブを含めたり除外したりできます。
ルールは最初にマッチするまで順番に評価されます。一致するジョブが見つかると、設定に応じてそのジョブはパイプラインに含まれるか除外されます。詳細はrules
リファレンスを参照してください。
今後のキーワードの改良については、誰でも提案や要望を追加できるrules
](https://gitlab.com/groups/gitlab-org/-/epics/2783) の改良のための[エピックで議論されています。
rules
例
以下の例では、if
を使って、特定の2つのケースでのみジョブが実行されることを定義しています:
job:
script: echo "Hello, Rules!"
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: manual
allow_failure: true
- if: $CI_PIPELINE_SOURCE == "schedule"
- パイプラインがマージリクエストのためのものである場合、最初のルールが一致します。そのため、ジョブがマージリクエストパイプラインに追加され、その属性は次のようになります。
-
when: manual
(手動ジョブ) -
allow_failure: true
(手動ジョブが実行されなくてもパイプラインは動き続けます)
-
- パイプラインがマージリクエストのためのものではない場合、最初のルールがマッチせず、2番目のルールが評価されます。
- パイプラインがスケジュールされたパイプラインの場合、2番目のルールはマッチし、ジョブはスケジュールされたパイプラインに追加されます。属性が定義されていないため、追加されます:
-
when: on_success
(デフォルト) -
allow_failure: false
(デフォルト)
-
- それ以外のすべての場合、ルールが一致しないため、ジョブは他のパイプラインに追加されません。
次のように、いくつかのケースではジョブを除外し、それ以外のケースではすべてのジョブを実行するようにルールを定義することもできます。
job:
script: echo "Hello, Rules!"
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: never
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- when: on_success
- パイプラインがマージリクエストの場合、ジョブはパイプラインに追加されません。
- パイプラインがスケジュールされたパイプラインの場合、ジョブはパイプラインに追加されません。
-
それ以外の場合、
when: on_success
により、ジョブはパイプラインに追加されます。
when
節を最終ルールとして使用する場合 (when: never
を含まない)、2 つのパイプラインを同時に開始することができます。プッシュパイプラインとマージリクエストパイプラインの両方が、同じイベント(オープンなマージリクエストのソースブランチへのプッシュ)によってトリガーされる可能性があります。詳細はパイプラインの重複を防ぐ方法を参照してください。スケジュールされたパイプラインのジョブの実行
パイプラインがスケジュールされたときにのみ実行されるジョブを設定するには、rules
キーワードを使用します。
この例では、make world
はスケジュールされたパイプラインで実行され、make build
はブランチおよびタグパイプラインで実行されます:
job:on-schedule:
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
script:
- make world
job:
rules:
- if: $CI_PIPELINE_SOURCE == "push"
script:
- make build
ブランチが空の場合はジョブをスキップします。
rules:changes:compare_to
を使うと、ブランチが空のときにジョブを実行しないようにできます。これにより、CI/CD のリソースを節約できます。ブランチをデフォルトのブランチと比較し、ブランチが空の場合はジョブをスキップします:
- 変更されたファイルがない場合、ジョブは実行されません。
- 変更されたファイルがある場合、ジョブは実行されます。
たとえば、main
をデフォルトブランチとするプロジェクトの場合です:
job:
script:
- echo "This job only runs for branches that are not empty"
rules:
- if: $CI_COMMIT_BRANCH
changes:
compare_to: 'refs/heads/main'
paths:
- '*'
このジョブのルールは、現在のブランチ内のすべてのファイルとパス (*
) をデフォルトブランチmain
と比較します。このルールはブランチ内のファイルに変更があった場合にのみマッチし、ジョブが実行されます。
複雑なルール
if
、changes
、exists
のように、rules
キーワードをすべて同じルールで使用できます。ルールは、含まれるすべてのキーワードがtrueと評価された場合にのみtrueと評価されます。
使用例:
docker build:
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
rules:
- if: $VAR == "string value"
changes: # Include the job and set to when:manual if any of the follow paths match a modified file.
- Dockerfile
- docker/scripts/*
when: manual
allow_failure: true
Dockerfile
ファイルまたは/docker/scripts
内のファイルが変更され、 $VAR
== “文字列値” の場合、ジョブは手動で実行され、失敗してもかまいません。
&&
と||
で括弧を使うと、より複雑な変数式を構築できます。GitLab 13.3 で導入されました:
job1:
script:
- echo This rule uses parentheses.
rules:
- if: ($CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "develop") && $MY_VARIABLE
&&
の両方を使うルールは予期しないオペレーション順序で評価されることがありました。パイプラインの重複を避ける
ジョブがrules
を使用している場合、ブランチへのコミットのプッシュのような単一のアクションが複数のパイプラインをトリガーする可能性があります。複数のタイプのパイプラインのルールを明示的に設定しなくても、誤ってトリガーしてしまうことはありません。
パイプラインの重複を引き起こす可能性のある設定によっては、パイプラインの警告が表示されます。GitLab 13.3 で導入されました。
使用例:
job:
script: echo "This job creates double pipelines!"
rules:
- if: $CUSTOM_VARIABLE == "false"
when: never
- when: always
このジョブは$CUSTOM_VARIABLE
が false のときは実行されませんが、プッシュ (ブランチ) パイプラインとマージリクエストパイプラインの両方を含む、他のすべてのパイプラインでは実行されます。この設定では、マージリクエストのソースブランチにプッシュするたびにパイプラインが重複します。
パイプラインの重複を避けるには、次のようにします:
-
workflow
を使用して、実行できるパイプラインのタイプを指定します。 -
非常に特殊な場合にのみジョブを実行するようにルールを書き直し、最後の
when
ルールは避けてください:job: script: echo "This job does NOT create double pipelines!" rules: - if: $CUSTOM_VARIABLE == "true" && $CI_PIPELINE_SOURCE == "merge_request_event"
プッシュ(ブランチ)パイプラインかマージリクエストパイプラインのどちらかを避けるようにジョブルールを変更することで、パイプラインの重複を避けることもできます。しかし、workflow: rules
を使わずに- when: always
ルールを使うと、GitLab はパイプラインの警告を表示します。
例えば、以下は二重のパイプラインをトリガーしませんが、workflow: rules
なしでは推奨されません:
job:
script: echo "This job does NOT create double pipelines!"
rules:
- if: $CI_PIPELINE_SOURCE == "push"
when: never
- when: always
パイプラインの重複を防ぐworkflow:rules
なしでは、同じジョブにプッシュリクエストパイプラインとマージリクエストパイプラインの両方を含めるべきではありません :
job:
script: echo "This job creates double pipelines!"
rules:
- if: $CI_PIPELINE_SOURCE == "push"
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
また、only/except
のジョブとrules
のジョブを同じパイプラインに混在させないでください。YAMLエラーを引き起こさないかもしれませんが、only/except
とrules
の異なるデフォルトのふるまいはトラブルシューティングが難しいイシューを引き起こす可能性があります:
job-with-no-rules:
script: echo "This job runs in branch pipelines."
job-with-rules:
script: echo "This job runs in merge request pipelines."
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
ブランチにプッシュされたすべての変更に対して、パイプラインが重複して実行されます。ブランチパイプラインは1つのジョブ (job-with-no-rules
) を実行し、マージリクエストパイプラインはもう1つのジョブ (job-with-rules
) を実行します。ルールのないジョブのデフォルトはexcept: merge_requests
で、マージリクエスト以外のすべてのケースでjob-with-no-rules
が実行されます。
の一般的なif
節は次のとおりです。rules
only
/except
キーワード と同様の動作については、$CI_PIPELINE_SOURCE
変数の値をチェックできます:
値 | 説明 |
---|---|
api | パイプラインAPIで起動されたパイプラインの場合。 |
chat | GitLab ChatOps コマンドを使用して作成したパイプラインの場合。 |
external | GitLab以外のCIサービスを利用する場合。 |
external_pull_request_event | GitHub 上の外部プルリクエストが作成または更新されたとき。 詳細は外部プルリクエスト用のパイプラインを参照してください。 |
merge_request_event | マージリクエストが作成または更新されたときに作成されるパイプライン用。 マージリクエストパイプライン、マージ結果パイプライン、マージトレインを有効にするために必要です。 |
parent_pipeline |
rules を持つ親/子パイプラインによってトリガされるパイプライン用。親パイプラインによってトリガされるように、子パイプライン設定でこのパイプラインソースを使用します。 |
pipeline |
CI_JOB_TOKEN ](../pipelines/downstream_pipelines.md#trigger-a-multi-project-pipeline-by-using-the-api)またはtrigger キーワードを使用した API を使用して[で作成されたマルチプロジェクトパイプラインの場合。 |
push | ブランチやタグを含む、git push イベントをトリガーとするパイプラインの場合。 |
schedule | スケジュールパイプラインの場合。 |
trigger | トリガートークンを使用して作成されたパイプラインの場合。 |
web | GitLab UI のパイプライン 実行ボタンで作成したパイプラインの場合。 |
webide | WebIDEを使用して作成したパイプラインの場合。 |
以下の例では、ジョブを手動ジョブとしてスケジュールパイプラインまたはプッシュパイプライン(ブランチまたはタグへ)で、when: on_success
(デフォルト)で実行します。他のパイプラインタイプにはジョブを追加しません。
job:
script: echo "Hello, Rules!"
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: manual
allow_failure: true
- if: $CI_PIPELINE_SOURCE == "push"
次の例は、マージリクエストパイプラインとスケジュールされたパイプラインで、when: on_success
ジョブとして実行します。他のパイプラインタイプでは実行されません。
job:
script: echo "Hello, Rules!"
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_PIPELINE_SOURCE == "schedule"
その他、if
節でよく使われる変数:
-
if: $CI_COMMIT_TAG
:タグに対して変更がプッシュされた場合。 -
if: $CI_COMMIT_BRANCH
:変更が任意のブランチにプッシュされた場合。 -
if: $CI_COMMIT_BRANCH == "main"
:変更がmain
にプッシュされた場合。 -
if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
:変更がデフォルトブランチにプッシュされる場合。デフォルトブランチが異なる複数のプロジェクトで同じ設定をしたい場合に使います。 -
if: $CI_COMMIT_BRANCH =~ /regex-expression/
:コミットブランチが正規表現にマッチした場合。 -
if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_COMMIT_TITLE =~ /Merge branch.*/
:コミットブランチがデフォルトブランチで、コミットメッセージタイトルが正規表現にマッチする場合。たとえば、マージコミットのデフォルトコミットメッセージはMerge branch
で始まります。 -
if: $CUSTOM_VARIABLE !~ /regex-expression/
:カスタム変数のCUSTOM_VARIABLE
が正規表現にマッチしない場合。 -
if: $CUSTOM_VARIABLE == "value1"
:カスタム変数のCUSTOM_VARIABLE
がvalue1
と完全に一致する場合。
変数rules:changes
ジョブをパイプラインに追加するタイミングを決定するために、rules:changes
式で CI/CD 変数を使用できます:
docker build:
variables:
DOCKERFILES_DIR: 'path/to/files'
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
rules:
- changes:
- $DOCKERFILES_DIR/*
変数とパスの両方に$
文字を使用できます。例えば、$DOCKERFILES_DIR
変数が存在する場合、その値が使用されます。存在しない場合、$
はパスの一部として解釈されます。
異なるジョブでのルールの再利用
GitLab 14.3で導入されました。
異なるジョブでルールを再利用するには!reference
タグ を使います。!reference
のルールを通常のジョブ定義のルールと組み合わせることができます:
.default_rules:
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
job1:
rules:
- !reference [.default_rules, rules]
script:
- echo "This job runs for the default branch, but not schedules."
job2:
rules:
- !reference [.default_rules, rules]
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
script:
- echo "This job runs for the default branch, but not schedules."
- echo "It also runs for merge requests."
ジョブの実行時にonly
とexcept
ジョブをパイプラインに追加するタイミングを制御するには、only
とexcept
を使用できます。
-
only
を使用して、ジョブが実行されるタイミングを定義します。 - ジョブが実行されないタイミングを定義するには、
except
を使用します。
only:refs
/except:refs
の例
only
またはexcept
を使用できます:
- 特定のキーワード。完全なリストは
only
/except
構文リファレンス を参照してください。 - ブランチ名。特定のキーワードと全く同じブランチ名は避けてください。例えば、
tags
(タグパイプライン)tags
というキーワードで実行するように設定されたジョブは、tags
.NET という名前のブランチでも実行さtags
れます。 - 正規表現パターンでブランチ名の範囲を指定します。
以下の例ではrefs
を省略していますが、これはonly
またはexcept
をrefs
なしで使用した場合、only:refs
/except/refs
と同じになるためです。
使用例:
job:
# use special keywords
only:
- tags
- triggers
- schedules
この例では、job
:
- Gitタグ
- トリガー
- スケジュールされたパイプライン
親リポジトリに対してのみジョブを実行し、フォークに対しては実行しないようにします:
job:
only:
- branches@gitlab-org/gitlab
except:
- main@gitlab-org/gitlab
- /^release/.*$/@gitlab-org/gitlab
この例では、main
とrelease/
で始まるブランチを除く、gitlab-org/gitlab
上のすべてのブランチに対してjob
を実行します。
only: variables
/except: variables
の例
except:variables
を使って、コミットメッセージに基づいてジョブを除外することができます:
end-to-end:
script: rake test:end-to-end
except:
variables:
- $CI_COMMIT_MESSAGE =~ /skip-end-to-end-tests/
&&
や||
で括弧を使うと、より複雑な変数式を構築できます:
job1:
script:
- echo This rule uses parentheses.
only:
variables:
- ($CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "develop") && $MY_VARIABLE
複数のエントリがonly:variables
で指定されている場合、そのうちの少なくとも 1 つがtrue
と評価されたときにジョブが実行されます。複数の条件を同時に満たす必要がある場合は、1 つのエントリで&&
を使用できます。
only:changes
/except:changes
の例
リポジトリのルートディレクトリにある.md
という拡張子を持つファイルに変更が検出された場合、ジョブをスキップすることができます:
build:
script: npm run build
except:
changes:
- "*.md"
複数のファイルを変更しても、.md
で終わるファイルが 1 つだけの場合、build
ジョブはスキップされます。ジョブはどのファイルに対しても実行されません。
changes
を使用する設定によっては、ジョブやパイプラインが予期せず実行されることがあります。
マージリクエストパイプラインでonly:changes
を使用してください。
マージリクエストパイプラインでは、マージリクエストで変更されたファイルに基づいて作成されるジョブを定義することができます。
GitLabがソースブランチの正しいベースSHAを見つけられるように、このキーワードをonly: [merge_requests]
。ファイルの差分はそれ以降のコミットから正しく計算され、マージリクエストのすべての変更はパイプラインで正しくテストされます。
使用例:
docker build service one:
script: docker build -t my-service-one-image:$CI_COMMIT_REF_SLUG .
only:
refs:
- merge_requests
changes:
- Dockerfile
- service-one/**/*
このシナリオでは、マージリクエストがservice-one
ディレクトリかDockerfile
のファイルを変更した場合、GitLab はdocker build service one
ジョブを作成します。
使用例:
docker build service one:
script: docker build -t my-service-one-image:$CI_COMMIT_REF_SLUG .
only:
changes:
- Dockerfile
- service-one/**/*
この例では、service-one/**/*
のファイルが変更されたため、パイプラインが失敗する可能性があります。
service-one/**/*
に変更はありませんが、.NET ファイルに変更がある場合、後のコミットはDockerfile
パスする Dockerfile
ことができます。Dockerfile
ジョブがテストするのは、. Dockerfile
GitLab はパスした最新のパイプラインをチェックします。マージリクエストがマージ可能であれば、以前のパイプラインが修正されていない変更のために失敗したことは問題ではありません。
この設定を使う場合は、最新のパイプラインが以前のパイプラインの失敗を適切に修正していることを確認してください。
複数のキーワードをonly
またはexcept
複数のキーワードをonly
またはexcept
で使用すると、キーワードは1つの結合式として評価されます。つまり
-
only
は、すべてのキーが少なくとも 1 つの条件に一致する場合、ジョブを含めます。 -
except
は、一致する条件が1つでもあるキーがあれば、そのジョブを除外します。
only
を使用すると、個々のキーはAND
で論理的に結合されます。 以下の条件が真の場合、ジョブはパイプラインに追加されます:
(any listed refs are true) AND (any listed variables are true) AND (any listed changes are true) AND (any chosen Kubernetes status matches)
以下の例では、test
のジョブは、以下のすべてが真の場合にのみ作成されます:
- パイプラインがスケジュールされて いるか、
main
のために実行されています。 -
variables
キーワードがマッチいている。 - プロジェクトの
kubernetes
サービスがアクティビティである。
test:
script: npm run test
only:
refs:
- main
- schedules
variables:
- $CI_COMMIT_MESSAGE =~ /run-end-to-end-tests/
kubernetes: active
except
を使用すると、個々のキーはOR
で論理的に結合されます。 以下の場合、ジョブは追加されません:
(any listed refs are true) OR (any listed variables are true) OR (any listed changes are true) OR (a chosen Kubernetes status matches)
以下の例では、test
のジョブは、以下のいずれかが真の場合は作成されません:
- パイプラインは
main
ブランチで実行されます。 - リポジトリのルートディレクトリにある
README.md
ファイルが変更されている。
test:
script: npm run test
except:
refs:
- main
changes:
- "README.md"
手動で実行するジョブの作成
ユーザーがジョブを開始しない限り、ジョブが実行されないようにすることができます。これは手動ジョブと呼ばれます。本番環境へのデプロイなどのために手動ジョブを使いたいと思うかもしれません。
ジョブを手動として指定するには、.gitlab-ci.yml
ファイルのジョブにwhen: manual
を追加します。
デフォルトでは、手動ジョブはパイプラインの開始時にスキップされたものとして表示されます。
保護されたブランチを使用することで、手動デプロイが権限のないユーザーによって実行されないように、より厳密に保護することができます。
手動ジョブの種類
手動ジョブにはオプションとブロックがあります。
オプションの手動ジョブの場合:
-
allow_failure
はtrue
で、when: manual
があり、rules
がないジョブ、またはrules
の内部でwhen: manual
が定義されているジョブのデフォルト設定です。 - ステータスはパイプライン全体のステータスに貢献しません。パイプラインは、手動ジョブがすべて失敗しても成功することがあります。
手動ジョブのブロックでは:
-
allow_failure
false
これは、rules
の内部でwhen: manual
が定義されているジョブのデフォルト設定です。 - パイプラインはジョブが定義されたステージで停止します。パイプラインの実行を継続させるには、手動ジョブを実行してください。
- を持つプロジェクトのマージリクエストは成功しなければなりません。 パイプラインは成功する必要があります。ブロックされたパイプラインではマージできません。
- パイプラインはブロックされたステータスを表示します。
strategy: depend
を使用してトリガされたパイプラインで手動ジョブを使用する場合、手動ジョブのタイプはパイプラインの実行中にトリガジョブのステータスに影響します。
手動ジョブの実行
手動ジョブを実行するには、割り当てられたブランチにマージする権限が必要です:
- パイプライン、ジョブ、環境、またはデプロイメントビューに移動します。
- 手動ジョブの横で、再生({play}) を選択します。
手動ジョブを実行する際に、カスタムCI/CD変数を追加することもできます。
手動ジョブの保護
保護された環境を使用して、手動ジョブの実行を許可されたユーザーのリストを定義します。保護された環境に関連付けられたユーザーのみに手動ジョブのトリガーを許可することができます:
- 環境にデプロイできるユーザーをより正確に制限します。
- 承認者が「承認」するまでパイプラインをブロックします。
手動ジョブを保護するには:
-
ジョブに
environment
を追加します。使用例:deploy_prod: stage: deploy script: - echo "Deploy to production server" environment: name: production url: https://example.com when: manual rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
-
保護された環境の設定で、環境 ( この例では
production
) を選択し、手動ジョブをトリガーする権限を持つユーザー、ロール、グループをAllowed to Deployリストに追加します。このリストに含まれる人だけがこの手動ジョブをトリガーすることができ、GitLab管理者は常に保護された環境を使用することができます。
手動ジョブをブロックする保護された環境を使用して、後のパイプラインステージを承認することを許可されたユーザーのリストを持つことができます。allow_failure: false
を保護された手動ジョブに追加すると、パイプラインの次のステージは、手動ジョブが作成者によってトリガーされた後にのみ実行されます。
遅延後のジョブの実行
GitLab 11.4で導入されました。
待ち時間の後にスクリプトを実行する場合や、ジョブがすぐにpending
の状態になるのを避けたい場合はwhen: delayed
を使ってください。
start_in
キーワードで start_in
期間を設定できます。start_in
の値は start_in
、単位が指定されていない限り、経過時間を秒単位で表します。最小値は1秒で、最大値は1週間です。有効な値の例を以下に示します:
-
'5'
(単位を指定しない値はシングルクォートで囲む必要があります) 5 seconds
30 minutes
1 day
1 week
ステージに遅延ジョブが含まれる場合、遅延ジョブが終了するまでパイプラインは進行しません。このキーワードを使用して、異なるステージ間に遅延を挿入できます。
遅延ジョブのタイマーは、前のステージが完了した直後に開始します。他のタイプのジョブ同様、遅延ジョブのタイマーは前のステージが通過しない限り開始しません。
次の例では、timed rollout 10%
という名前のジョブを作成し、前のステージが完了した30分後に実行します:
timed rollout 10%:
stage: deploy
script: echo 'Rolling out 10% ...'
when: delayed
start_in: 30 minutes
environment: production
遅延ジョブのアクティブタイマーを停止するには、Unschedule({time-out})を選択します。このジョブは自動的に実行されるようにスケジュールできなくなります。しかし、ジョブを手動で実行することはできます。
遅延ジョブを手動で開始するには、Unschedule({time-out})を選択して遅延タイマーを停止し、Play({play})を選択します。すぐに GitLab Runner がジョブを開始します。
大規模ジョブの並列化
大きなジョブを複数の小さなジョブに分割して並列実行するには、.gitlab-ci.yml
ファイルでparallel
キーワードを使用します。
言語やテストスイートによって、並列化の方法は異なります。たとえば、Ruby のテストを並列実行するにはSemaphore Test Boostersと RSpec を使います:
# Gemfile
source 'https://rubygems.org'
gem 'rspec'
gem 'semaphore_test_boosters'
test:
parallel: 3
script:
- bundle
- bundle exec rspec_booster --job $CI_NODE_INDEX/$CI_NODE_TOTAL
その後、新しいパイプラインビルドのジョブタブに移動すると、RSpecジョブが3つの別々のジョブに分割されていることが確認できます。
並列ジョブの1次元行列を実行
GitLab 13.5 で導入されました。
並列ジョブの一次元マトリックスを作成できます:
deploystacks:
stage: deploy
script:
- bin/deploy
parallel:
matrix:
- PROVIDER: [aws, ovh, gcp, vultr]
environment: production/$PROVIDER
多次元マトリックスを作成することもできます。
並列トリガジョブの行列の実行
GitLab 13.10で導入されました。
一つのパイプラインでトリガージョブを複数回並列に実行することができます。
deploystacks:
stage: deploy
trigger:
include: path/to/child-pipeline.yml
parallel:
matrix:
- PROVIDER: aws
STACK: [monitoring, app1]
- PROVIDER: ovh
STACK: [monitoring, backup]
- PROVIDER: [gcp, vultr]
STACK: [data]
この例では、6つの並列deploystacks
トリガージョブを生成し、それぞれPROVIDER
とSTACK
に異なる値を設定し、これらの変数で6つの異なる子パイプラインを作成します。
deploystacks: [aws, monitoring]
deploystacks: [aws, app1]
deploystacks: [ovh, monitoring]
deploystacks: [ovh, backup]
deploystacks: [gcp, data]
deploystacks: [vultr, data]
それぞれの並列マトリックスジョブに異なる Runner タグを選択します。
GitLab 14.1 で導入されました。
tags
キーワードを使ってparallel: matrix
で定義された変数を動的なランナー選択に使うことができます:
deploystacks:
stage: deploy
parallel:
matrix:
- PROVIDER: aws
STACK: [monitoring, app1]
- PROVIDER: gcp
STACK: [data]
tags:
- ${PROVIDER}-${STACK}
environment: $PROVIDER/$STACK
parallel:matrix
ジョブからアーティファクトをフェッチします。
dependencies
キーワードを使用すると、parallel:matrix
で作成されたジョブからアーティファクトをフェッチできます。dependencies
の値としてジョブ名をフォームの文字列として使用します:
<job_name> [<matrix argument 1>, <matrix argument 2>, ... <matrix argument N>]
たとえば、RUBY_VERSION
が2.7
で、PROVIDER
がaws
のジョブからアーティファクトをフェッチするには、次のようにします:
ruby:
image: ruby:${RUBY_VERSION}
parallel:
matrix:
- RUBY_VERSION: ["2.5", "2.6", "2.7", "3.0", "3.1"]
PROVIDER: [aws, gcp]
script: bundle install
deploy:
image: ruby:2.7
stage: deploy
dependencies:
- "ruby: [2.7, aws]"
script: echo hello
environment: production
dependencies
を囲む引用符が必要です。
複数の並列ジョブを持つニーズを使用した並列ジョブの指定
GitLab 16.3 で導入されました。
needs:parallel:matrix
で定義した変数を複数の並列化ジョブで使用することができます。
使用例:
linux:build:
stage: build
script: echo "Building linux..."
parallel:
matrix:
- PROVIDER: aws
STACK:
- monitoring
- app1
- app2
mac:build:
stage: build
script: echo "Building mac..."
parallel:
matrix:
- PROVIDER: [gcp, vultr]
STACK: [data, processing]
linux:rspec:
stage: test
needs:
- job: linux:build
parallel:
matrix:
- PROVIDER: aws
STACK: app1
script: echo "Running rspec on linux..."
mac:rspec:
stage: test
needs:
- job: mac:build
parallel:
matrix:
- PROVIDER: [gcp, vultr]
STACK: [data]
script: echo "Running rspec on mac..."
production:
stage: deploy
script: echo "Running production..."
environment: production
この例は複数のジョブを生成します。Parallels ジョブはそれぞれPROVIDER
とSTACK
に異なる値を指定します。
- 3 つの並列
linux:build
ジョブ:linux:build: [aws, monitoring]
linux:build: [aws, app1]
linux:build: [aws, app2]
- 4 並列
mac:build
ジョブ:mac:build: [gcp, data]
mac:build: [gcp, processing]
mac:build: [vultr, data]
mac:build: [vultr, processing]
-
linux:rspec
ジョブ。 -
production
ジョブ。
ジョブには3つの実行経路があります:
- Linux パス:
mac:build
の終了を待たずに、linux:build: [aws, app1]
の終了と同時にlinux:rspec
のジョブが実行されます。 - MacOSパス:
mac:rspec
ジョブは、mac:build: [gcp, data]
とmac:build: [vultr, data]
のジョブが終了すると、linux:build
の終了を待たずにすぐに実行されます。 -
production
のジョブは、前のジョブがすべて終了するとすぐに実行されます。
定義済みの CI/CD 変数を使用して、特定のパイプラインタイプでのみジョブを実行します。
定義済みの CI/CD 変数を使用して、どのパイプラインタイプでジョブを実行するかを選択できます:
次の表は、使用できる変数と、変数が制御できるパイプラインタイプの一覧です:
- ブランチパイプラインは、Git
push
のイベント(新規コミットやタグなど)に対して実行されます。 - タグパイプライン。新しい Git タグがブランチにプッシュされたときにのみ実行されます。
- マージリクエストパイプラインは、マージリクエストに対する変更 (新しいコミットやマージリクエストのパイプラインタブでパイプラインの実行ボタンを選択したときなど) に対して実行されます。
- スケジュールされたパイプライン。
変数 | ブランチ | タグ | マージリクエスト | 予定 |
---|---|---|---|---|
CI_COMMIT_BRANCH | はい | はい | ||
CI_COMMIT_TAG | はい | はい、スケジュールされたパイプラインがタグ上で実行されるように設定されている場合。 | ||
CI_PIPELINE_SOURCE = push | はい | はい | ||
CI_PIPELINE_SOURCE = scheduled | はい | |||
CI_PIPELINE_SOURCE = merge_request_event | はい | |||
CI_MERGE_REQUEST_IID | はい |
例えば、マージリクエストパイプラインとスケジュールされたパイプラインに対してジョブを実行し、ブランチまたはタグパイプラインに対しては実行しないように設定します:
job1:
script:
- echo
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_PIPELINE_SOURCE == "schedule"
- if: $CI_PIPELINE_SOURCE == "push"
when: never
正規表現
@
記号は ref のリポジトリパスの先頭を @
表します。正規表現に@
含ま @
れる文字を含む参照名に@
マッチさ @
せるには、16進数の文字コード match\x40
を使用する必要があります。
タグやブランチ名だけが正規表現でマッチできます。リポジトリのパスが与えられている場合は、文字列としてのみマッチします。
タグ名やブランチ名にマッチさせるには、パターンの ref 名部分全体が/
で囲まれた正規表現でなければなりません。たとえば、issue-
で始まるタグ名やブランチ名をすべてマッチさせるためにissue-/.*/
を使うことはできませんが、/issue-.*/
を使うことはできます。
正規表現のフラグは、/
を閉じた後に付加する必要があります。パターン・マッチはデフォルトで大文字と小文字を区別します。パターンを大文字小文字を区別しないようにするには、/pattern/i
のようにi
フラグ修飾子を使用します:
job:
# use regexp
only:
- /^issue-.*$/i
# use special keyword
except:
- branches
正規表現がタグ名またはブランチ名の部分文字列のみにマッチするのを避けるには、アンカー^
と$
を使用します。たとえば、/^issue-.*$/
は/^issue-/
と同じですが、/issue/
だけはsevere-issues
というブランチにもマッチします。
only
/except
正規表現の構文
GitLab 11.9.4で、GitLabはonly
とexcept
キーワードで使われている正規表現を内部でRE2に変換するようになりました。
RE2では計算の複雑さのために利用できる機能が制限され、負のルックヘッドのようないくつかの機能が利用できなくなりました。Ruby Regexpが提供する機能のサブセットのみがサポートされるようになりました。
GitLab 11.9.7からGitLab 14.9まで、GitLabは安全でない正規表現構文を使えるようにする機能フラグを提供していました。現在はRE2に完全にマイグレーションしており、この機能フラグは使えなくなりました。
CI/CD 変数式
- GitLab 10.7 で
only
とexcept
CI キーワード が導入されました。- GitLab 12.3 で
rules
キーワードが拡張されました。
変数式を使って、変更がGitLabにプッシュされた後にパイプラインに作成されるジョブを制御します。変数式は次のように使えます:
例えば、rules:if
:
job1:
variables:
VAR1: "variable1"
script:
- echo "Test variable comparison
rules:
- if: $VAR1 == "variable1"
変数と文字列の比較
等号演算子==
と!=
を使って変数と文字列を比較することができます。一重引用符でも二重引用符でもかまいません。順番は関係ないので、変数が先でも文字列が先でもかまいません。例えば
if: $VARIABLE == "some value"
if: $VARIABLE != "some value"
if: "some value" == $VARIABLE
つの変数の比較
2つの変数の値を比較することができます。例えば
if: $VARIABLE_1 == $VARIABLE_2
if: $VARIABLE_1 != $VARIABLE_2
変数が未定義かどうかのチェック
変数が定義されているかどうかを調べるには、null
キーワードと比較します。例えば
if: $VARIABLE == null
if: $VARIABLE != null
変数が空かどうかのチェック
変数が定義されているが空かどうかをチェックすることができます。例えば
if: $VARIABLE == ""
if: $VARIABLE != ""
変数が存在するかチェック
変数が存在するかどうかをチェックするには、式の中で変数名だけを使用します。変数は空であってはいけません。例えば
if: $VARIABLE
変数と正規表現パターンの比較
=~
および!~
演算子を使用すると、変数の正規表現パターンマッチングを行うことができます。正規表現による変数のパターンマッチングはRE2 正規表現構文を使います。
式はtrue
if として評価されます:
-
=~
を使用して、マッチする場合。 -
!~
を使用して、マッチしない場合。
使用例:
if: $VARIABLE =~ /^content.*/
if: $VARIABLE !~ /^content.*/
/./
のような1文字の正規表現はサポートされておらず、invalid expression syntax
エラーが発生します。
パターン・マッチはデフォルトでは大文字小文字を区別します。パターンの大文字小文字を区別しないようにするには、i
フラグ修飾子を使用します。例:/pattern/i
.
正規表現パターンを変数に格納します。
=~
と!~
の右辺の変数は正規表現として評価されます。正規表現はスラッシュ (/
) で内部を囲む必要があります。例えば
variables:
pattern: '/^ab.*/'
regex-job1:
variables:
teststring: 'abcde'
script: echo "This job will run, because 'abcde' matches the /^ab.*/ pattern."
rules:
- if: '$teststring =~ $pattern'
regex-job2:
variables:
teststring: 'fghij'
script: echo "This job will not run, because 'fghi' does not match the /^ab.*/ pattern."
rules:
- if: '$teststring =~ $pattern'
変数式を&&
または||
GitLab 12.0 で導入されました。
例えば、&&
(and) や||
(or) を使って複数の式を結合することができます:
$VARIABLE1 =~ /^content.*/ && $VARIABLE2 == "something"
$VARIABLE1 =~ /^content.*/ && $VARIABLE2 =~ /thing$/ && $VARIABLE3
$VARIABLE1 =~ /^content.*/ || $VARIABLE2 =~ /thing$/ && $VARIABLE3
演算子の優先順位はRuby 2.5の標準に従っているので、&&
は||
の前に評価されます。
変数式を括弧でグループ化します。
括弧を使って式をグループにまとめることができます。括弧は&&
や||
よりも優先されるので、括弧で囲まれた式は最初に評価され、その結果が残りの式に使われます。
複雑な条件を作成するために括弧を入れ子にすることができ、括弧内の最も内側の式が最初に評価されます。
使用例:
($VARIABLE1 =~ /^content.*/ || $VARIABLE2) && ($VARIABLE3 =~ /thing$/ || $VARIABLE4)
($VARIABLE1 =~ /^content.*/ || $VARIABLE2 =~ /thing$/) && $VARIABLE3
$CI_COMMIT_BRANCH == "my-branch" || (($VARIABLE1 == "thing" || $VARIABLE2 == "thing") && $VARIABLE3)
トラブルシューティング
を使用しているときにジョブやパイプラインが予期せず実行されます。changes:
rules: changes
やonly: changes
をマージリクエストパイプラインなしで使用しているときに、ジョブやパイプラインが予期せず実行されることがあります。
マージリクエストとの関連付けが明示されていないブランチやタグのパイプラインは、差分を計算するために以前の SHA を使用します。この計算はgit diff HEAD~
と同等であり、以下のような予期せぬ動作を引き起こす可能性があります:
- 新しいブランチや新しいタグを GitLab にプッシュするとき、
changes
ルールは常に true と評価されます。 - 新しいコミットをプッシュするとき、変更されたファイルは直前のコミットをベース SHA として計算されます。
さらに、changes
のルールは、スケジュールされたパイプラインでは常に真として評価されます。スケジュールされたパイプラインが実行されるとすべてのファイルが変更されたとみなされるため、changes
を使用するスケジュールされたパイプラインには常にジョブが追加される可能性があります。
CI/CD変数のファイルパス
CI/CD変数でファイルパスを使用する場合は注意が必要です。末尾のスラッシュは変数定義では正しく見えますが、script:
、changes:
、または他のキーワードで展開すると無効になることがあります。例えば
docker_build:
variables:
DOCKERFILES_DIR: 'path/to/files/' # This variable should not have a trailing '/' character
script: echo "A docker job"
rules:
- changes:
- $DOCKERFILES_DIR/*
DOCKERFILES_DIR
変数がchanges:
セクションで展開されると、フルパスはpath/to/files//*
になります。二重スラッシュは、使用されているキーワードやランナーのシェルやOSなどの要因によって、予期しない動作を引き起こす可能性があります。
You are not allowed to download code from this project.
エラーメッセージ
GitLab 管理者が非公開プロジェクトで保護された手動ジョブを実行すると、パイプラインが失敗することがあります。
CI/CD ジョブは通常、ジョブの開始時にプロジェクトをクローンしますが、これはジョブを実行するユーザーの権限を使います。管理者を含むすべてのユーザーは、非公開プロジェクトのソースをクローンするための直接のメンバーでなければなりません。この動作を変更するイシューが存在します。
保護された手動ジョブを実行するには
- 非公開プロジェクトの直接メンバーとして管理者を追加(ロールは問いません)
- プロジェクトの直接メンバーであるユーザーになりすます。