今回はGitLab CI/CDで利用できるキーワードの中から、.gitlab-ci.yml
から同じProject上の別のファイル、別Project上のファイルを呼び出せる include
について検証しました。
docs.gitlab.com
docs.gitlab.com
背景
ワークフローの定義ファイルを再利用することは、CI/CDをプロジェクトで運用する場合に重要です。パブリックに公開されたワークフローやプロジェクト共通のテンプレートを再利用することで、CI/CDの定義ファイルの記述量を削減したり、何度も同じ記述をコピーペーストしないことで、管理しやすいCI/CD定義ファイルの運用や人的ミスの削減を見込めます。
GitLabではCI/CDの実行を .gitlab-ci.yml
で制御するのがデフォルトの設定です。例えば1つのGitLabプロジェクトで実行する全ての処理を .gitlab-ci.yml
にスクリプトで記述すると、膨大な記述量となる場合もあります。GitLabでは include
というキーワードを使うことで、同じProject上にある .gitlab-ci.yml
以外のファイルや、別Projectの定義ファイルを呼び出すことができます。
GitLabは現在6つの形式で include
を利用できます。 components
inputs
は別の機会に触れるとして、ここでは他4つの利用方法を紹介します。
local
: 同じProject上にある別ファイルを呼び出します。
project
: 同じGitLabインスタンス上のプライベートな別Projectのファイルを呼び出します。
remote
: 別のGitLabインスタンス上のファイルを呼び出します。
template
: GitLabが公式に提供するテンプレートを呼び出します。
components
: CI/CD componentという再利用可能なパイプラインのユニットを呼び出します。
inputs
: 各 include
を利用するときに変数を上書きするのに使用します。
なお、 include
を利用するには、いくつかの制限事項があります。
include
という名前のJobから呼び出す形でないと利用できません。
- 呼び出すファイルの拡張子は
yaml
でないといけません。
project
/ remote
/ template
/ components
の場合、呼び出し元のファイルが修正されてもCIは実行されません。
include
を含むJobまたはパイプラインを再実行した場合、挙動が変化します。
- Jobの場合:
include
で指定したファイルに修正を加えた後に再実行しても、その内容はJobに反映されません。
- パイプラインの場合:
include
で指定したファイルに修正を加えた後に再実行すると、その内容はパイプラインに反映されます。
- パイプラインあたりの
include
の最大数はデフォルトで150までです。
検証
ここから各手法を検証します。
include:local
docs.gitlab.com
include:local
は同じProject上のファイルを呼び出す形です。1つのGitLab Projectで管理するような小規模プロジェクト、またはCI/CDの導入初期に利用するのがユースケースかと思います。
include:local
を利用する場合は、 .gitlab-ci.yml
に以下のように定義します。
include:
- local: '<呼び出すファイルパスを指定>'
include:local
を利用するうえでの注意事項は以下の通りです。
.gitlab-ci.yml
と同じブランチ上のファイルしか対象にできません。
- GIt submodule (ある Git リポジトリを別の Git リポジトリのサブディレクトリとして扱う) のパスでファイルを使用することはできません。
ここでは include-local-test
というProject上に以下のようなファイルを配置しました。
.gitlab-ci.yml
build:
stage: build
script:
- echo "Start include:local jobs."
include:
- local: '.gitlab-ci.local.yml'
- local: '/include/.gitlab-ci.local.yml'
.gitlab-ci.local.yml
test-from-include:
stage: test
script:
- echo "This is from .gitlab-ci.local.yml."
include/.gitlab-ci.local.yml
deploy:
stage: deploy
script:
- echo "This is from include/.gitlab-ci.local.yml."
include:local
は .gitlab-ci.yml
と別のディレクトリ上のファイルも呼び出し可能です。ここでは .gitlab-ci.local.yml
include/.gitlab-ci.local.yml
という2つのファイルを呼び出しています。
このProjectでCI/CDを実行すると、以下のように3つのStageに分かれて実行されます。
.gitlab-ci.local.yml
を呼び出す test
Jobを見ると、 This is from .gitlab-ci.yml.local
(テキストを間違っておりました。。。) と表示されており、 .gitlab-ci.local.yml
を呼び出しているのを確認できます。
include/gitlab-ci.local.yml
を呼び出す deploy
Jobも同様に確認できます。
include:project
docs.gitlab.com
include:project
は同じインスタンス上の別Projectからファイルを参照します。複数のGitLab Projectにまたがって進むような大規模プロジェクトにおいて、include:project
専用のProjectを用意し、各Projectから利用することでプロジェクト内のCI/CDを利用しやすくする、などのケースが考えられます。
include:project
は対象のプロジェクトとファイル名に加え、 ref
というキーワードを使ってファイルの参照先 (デフォルトは HEAD
を参照) を変更できます。
include:project
は以下のように指定します。
include:
- project: '<Project名を指定>'
file: '<使用するファイル名を指定>'
ref: '<ブランチ名、タグなどを指定 (オプション)>'
include:project
の注意事項は以下の通りです。
- パイプラインを実行するユーザーは
include:project
で指定したProjectのメンバーであり、適切な権限が必要です。
include:project
で指定したファイルが更新されても、呼び出し元のCI/CDパイプラインは起動しません。またセキュリティの観点から、以下のように ref
を使用して参照先を特定することが推奨されます。
- 特定のSHAハッシュを指定する
- 別プロジェクト上で
protected branch
/ protected tag
を使用する。この設定を適用した参照先は、Merge Requestなどの変更管理を通じて変更する確率が高くなります。
ここでは2つのGitLab Project ( include-project-test
include-project-template-test
) を用意し、include-project-test
から include-project-template-test
上のファイルを呼び出します。また include-project-template-test
上に feature
ブランチを作成し、 ref
を利用した場合も実施しています。
include-project-test/.gitlab-ci.yml
stages:
- build
- test
- deploy
build:
stage: build
script:
- echo "Start include jobs from another project."
include:
- project: 'fy0323/include-project-template-test'
file: '.gitlab-ci.project.yml'
- project: 'fy0323/include-project-template-test'
file: '.gitlab-ci.project.yml'
ref: feature
include-project-template-test/.gitlab-ci.project.yml
project:
stage: test
script:
- echo "This is from .gitlab-ci.project.yml at include-project-template-test"
include-project-template-test/.gitlab-ci.project.yml at feature branch
project-from-feature:
stage: deploy
script:
- echo "This is from .gitlab-ci.project.yml at include-project-template-test"
- echo "The branch name is feature."
include-project-test
でCI/CDパイプラインを実行すると、以下のように3つのJobを実行します。 test
Jobは include-project-template-test
の main
ブランチから、 deploy
Jobは feature
ブランチから呼び出しています。
それぞれのJobを見ると、確かに呼び出されていることを確認できます。
include:remote
docs.gitlab.com
include:remote
は別インスタンス上のファイルを対象とする時に使用します。正直利用用途があまり浮かばなかったですが、例えば何らかの理由でGitLab Self-managedインスタンス / SaaSを複数利用しており、あるProjectのテンプレートを別のインスタンスでも利用したい場合、インスタンスをまたいでテンプレートを利用できます。ただし本機能は、参照元のProjectがPublicな場合に限り利用可能です。
include:remote
は以下のように利用します。
include:
- remote: '<GitLabインスタンスのURLを含むファイルパスを指定>'
include:remote
を利用するうえでの注意事項は以下の通りです。
remote
のターゲットにできるのは、 GET
リクエストでアクセス可能なPublic Projectが対象です。
- 認証情報を付与してのURLアクセスはサポートされていません。そのためPrivate Projectの利用は基本的にできません。
今回は include-remote-test
というProjectで検証します。リモートURLには、以前作成したSelf-managedインスタンス上に作成したPublic Projectを使用しました。
.gitlab-ci.yml
では以下のように指定します。
build:
stage: build
script:
- echo "Start jobs from include:remote."
include:
- remote: 'https://<GitLabインスタンスURL>/root/include-remote-template-test/-/raw/main/.gitlab-ci.remote.yml'
なお、リモートURLは、参照先リポジトリの以下の場所から取得できます。
パイプラインを実行すると、リモートURLから定義ファイルを取得し、問題なく処理が完了したのを確認します。
test jobを見ると、確かにリモートURLが呼び出され、定義された内容が呼び出されていることを確認できます。
include:template
docs.gitlab.com
include:template
はGitLabの提供するテンプレートを利用する方法です。自分たちでイチからテンプレートを用意せずとも利用可能なので、用途に合ったものがあれば積極的に利用するのが良いと思います。
include:template
は以下のように利用します。
include:
- template: '<利用するテンプレートファイル名を指定>'
include:template
の注意事項は以下の通りです。
- include:templateで利用できるテンプレートはこちらに配置されています。ただし、すべてのテンプレートが
include:template
で利用できるわけではないため、利用前には各テンプレート中のコメントを確認する必要があります。
今回は Bash.gitlab-ci.yml というテンプレートを指定し、CI/CDから Bashスクリプトを呼び出します。
.gitlab-ci.yml
は以下のように指定します。
build:
stage: build
script:
- echo "Start jobs from include:template."
include:
- template: Bash.gitlab-ci.yml
上記ファイルを配置し、問題なければパイプラインが完了します。Jobを確認すると、 Bash.gitlab-ci.yml
で定義した内容が実行されているのを確認できます。
その他
Nested include
docs.gitlab.com
include
は入れ子構造で呼び出すことも可能です。 .gitlab-ci.yml
から include
で呼び出されるテンプレート内部で、さらに別のテンプレートを呼び出すことで、ワークフローのメンテナンス性と再利用性を向上することができます。
なお、Nested includeは1つのパイプラインあたり150ファイルが上限です。