GitLab CI/CD設定ファイルの最適化
GitLab CI/CD設定ファイルの複雑さや重複した設定を減らすには、次のような方法があります:
-
アンカー (
&
) 、エイリアス (*
) 、マップマージ (<<
) のような YAML 固有の機能。YAMLの様々な機能についてもっと読む -
extends
キーワード はより柔軟で読みやすくなっています。可能であればextends
を使うべきです。
アンカー
YAML には ‘アンカー’ と呼ばれる機能があります。
プロパティを複製もしくは継承するためにアンカーを使います。ジョブのテンプレートを提供するために隠しジョブでアンカーを使います。キーが重複している場合、最新のキーが優先され、他のキーより優先されます。
特定の場合 (スクリプトのための YAML アンカー を参照)、YAML アンカーを使用して、別の場所で定義された複数のコンポーネントを持つ配列を作ることができます。たとえば
.default_scripts: &default_scripts
- ./default-script1.sh
- ./default-script2.sh
job1:
script:
- *default_scripts
- ./job-script.sh
include
キーワードを使う場合、複数のファイルにまたがって YAML アンカーを使うことはできません。アンカーは定義されたファイルでのみ有効です。異なる YAML ファイルの設定を再利用するには、!reference
タグ またはextends
キーワード を使います。
次の例はアンカーとマップのマージを使っています。この例では、.job_template
の設定を継承する2つのジョブ、test1
とtest2
が作成され、それぞれ独自のカスタムscript
が定義されています:
.job_template: &job_configuration # Hidden yaml configuration that defines an anchor named 'job_configuration'
image: ruby:2.6
services:
- postgres
- redis
test1:
<<: *job_configuration # Add the contents of the 'job_configuration' alias
script:
- test1 project
test2:
<<: *job_configuration # Add the contents of the 'job_configuration' alias
script:
- test2 project
&
はアンカーの名前を設定し (job_configuration
)、<<
は「指定されたハッシュを現在のハッシュにマージする」ことを意味し、*
は指定されたアンカーを含みます (job_configuration
再び)。この例の拡張版は
.job_template:
image: ruby:2.6
services:
- postgres
- redis
test1:
image: ruby:2.6
services:
- postgres
- redis
script:
- test1 project
test2:
image: ruby:2.6
services:
- postgres
- redis
script:
- test2 project
アンカーを使って2つのサービスセットを定義することができます。例えば、test:postgres
とtest:mysql
は、.job_template
で定義されたscript
を共有しますが、.postgres_services
と.mysql_services
で定義されたservices
は、異なるものを使用します:
.job_template: &job_configuration
script:
- test project
tags:
- dev
.postgres_services:
services: &postgres_configuration
- postgres
- ruby
.mysql_services:
services: &mysql_configuration
- mysql
- ruby
test:postgres:
<<: *job_configuration
services: *postgres_configuration
tags:
- postgres
test:mysql:
<<: *job_configuration
services: *mysql_configuration
拡張バージョンは次のとおりです:
.job_template:
script:
- test project
tags:
- dev
.postgres_services:
services:
- postgres
- ruby
.mysql_services:
services:
- mysql
- ruby
test:postgres:
script:
- test project
services:
- postgres
- ruby
tags:
- postgres
test:mysql:
script:
- test project
services:
- mysql
- ruby
tags:
- dev
隠されたジョブがテンプレートとして便利に使われていることがわかります。tags: [postgres]
はtags: [dev]
を上書きします。
スクリプトのためのYAMLアンカー
GitLab 12.5で導入されました。
YAMLアンカーを script,before_script
,after_script
で使うことで、複数のジョブで定義済みのコマンドを使うことができます:
.some-script-before: &some-script-before
- echo "Execute this script first"
.some-script: &some-script
- echo "Execute this script second"
- echo "Execute this script too"
.some-script-after: &some-script-after
- echo "Execute this script last"
job1:
before_script:
- *some-script-before
script:
- *some-script
- echo "Execute something, for this job only"
after_script:
- *some-script-after
job2:
script:
- *some-script-before
- *some-script
- echo "Execute something else, for this job only"
- *some-script-after
設定セクションを再利用するにはextends
を使います。
複数のジョブで設定を再利用するためにextends
キーワード を使うことができます。これはYAML アンカーに似ていますが、よりシンプルで、 extends
をincludes
と一緒に使うことができます。
extends
は複数レベルの継承をサポートします。複雑さが増すので3つ以上のレベルを使うことは避けるべきですが、11個まで使うことができます。以下の例では、2つのレベルの継承を行っています:
.tests:
rules:
- if: $CI_PIPELINE_SOURCE == "push"
.rspec:
extends: .tests
script: rake rspec
rspec 1:
variables:
RSPEC_SUITE: '1'
extends: .rspec
rspec 2:
variables:
RSPEC_SUITE: '2'
extends: .rspec
spinach:
extends: .tests
script: rake spinach
からキーを除外します。extends
拡張コンテンツからキーを除外するには、そのキーをnull
に割り当てる必要があります:
.base:
script: test
variables:
VAR1: base var 1
test1:
extends: .base
variables:
VAR1: test1 var 1
VAR2: test2 var 2
test2:
extends: .base
variables:
VAR2: test2 var 2
test3:
extends: .base
variables: {}
test4:
extends: .base
variables: null
マージ設定:
test1:
script: test
variables:
VAR1: test1 var 1
VAR2: test2 var 2
test2:
script: test
variables:
VAR1: base var 1
VAR2: test2 var 2
test3:
script: test
variables:
VAR1: base var 1
test4:
script: test
variables: null
extends
、include
。
異なる設定ファイルの設定を再利用するには、extends
とinclude
を組み合わせてください。
次の例では、script
がincluded.yml
ファイルで定義されています。次に、.gitlab-ci.yml
ファイルで、extends
はscript
の内容を参照します:
-
included.yml
:.template: script: - echo Hello!
-
.gitlab-ci.yml
:include: included.yml useTemplate: image: alpine extends: .template
マージの詳細
extends
を使ってハッシュをマージすることはできますが、配列をマージすることはできません。マージに使われるアルゴリズムは “最も近いスコープが勝つ “です。キーが重複している場合、GitLabはキーを元に逆ディープマージを行います。最後のメンバーからのキーは、常に他のレベルで定義されたものを上書きします。例えば
.only-important:
variables:
URL: "http://my-url.internal"
IMPORTANT_VAR: "the details"
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_BRANCH == "stable"
tags:
- production
script:
- echo "Hello world!"
.in-docker:
variables:
URL: "http://docker-url.internal"
tags:
- docker
image: alpine
rspec:
variables:
GITLAB: "is-awesome"
extends:
- .only-important
- .in-docker
script:
- rake rspec
結果はこのようになりますrspec
ジョブ:
rspec:
variables:
URL: "http://docker-url.internal"
IMPORTANT_VAR: "the details"
GITLAB: "is-awesome"
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_BRANCH == "stable"
tags:
- docker
image: alpine
script:
- rake rspec
この例では:
-
variables
のセクションはマージされますが、URL: "http://docker-url.internal"
はURL: "http://my-url.internal"
を上書きします。 -
tags: ['docker']
はtags: ['production']
を上書きします。 -
script
はマージしませんが、script: ['rake rspec']
はscript: ['echo "Hello world!"']
を上書きします。配列をマージするためにYAML アンカーを使うことができます。
!reference
タグ
!reference
カスタムYAMLタグを使って他のジョブセクションからキーワード設定を選択し、現在のセクションで再利用 !reference
します。!reference
YAMLアンカーとは異なり、 !reference
タグを使ってインクルードされた設定ファイルから設定を再利用することもできます。
次の例では、2つの異なる場所からscript
とafter_script
がtest
ジョブで再利用されています:
-
setup.yml
:.setup: script: - echo creating environment
-
.gitlab-ci.yml
:include: - local: setup.yml .teardown: after_script: - echo deleting environment test: script: - !reference [.setup, script] - echo running my own command after_script: - !reference [.teardown, after_script]
次の例では、test-vars-1
は.vars
のすべての変数を再利用し、test-vars-2
は特定の変数を選択し、新しいMY_VAR
変数として再利用します。
.vars:
variables:
URL: "http://my-url.internal"
IMPORTANT_VAR: "the details"
test-vars-1:
variables: !reference [.vars, variables]
script:
- printenv
test-vars-2:
variables:
MY_VAR: !reference [.vars, variables, IMPORTANT_VAR]
script:
- printenv
script
、before_script
、!reference
のタグを入れ子にします。after_script
GitLab 14.8で導入されました。
script
,before_script
,after_script
セクションでは、!reference
タグを 10 レベルまでネストできます。より複雑なスクリプトを作るときに、ネストしたタグを使って再利用可能なセクションを定義します。例えば
.snippets:
one:
- echo "ONE!"
two:
- !reference [.snippets, one]
- echo "TWO!"
three:
- !reference [.snippets, two]
- echo "THREE!"
nested-references:
script:
- !reference [.snippets, three]
この例では、nested-references
ジョブは 3 つのecho
コマンドをすべて実行します。
!reference
タグをサポートするように IDE を設定します。
パイプラインエディターは !reference
タグをサポートします。しかし、カスタムYAMLタグのスキーマルールは!reference
デフォルトではエディターによって無効なものとして扱われるかもしれません !reference
。タグを受け入れる!reference
ようにエディタを設定 !reference
できます。たとえば
-
VS Code では、
settings.json
ファイルのcustomTags
を解析するようにvscode-yaml
を設定できます:"yaml.customTags": [ "!reference sequence" ]
-
Sublime Text では、
LSP-yaml
パッケージを使用している場合、LSP-yaml
ユーザー設定でcustomTags
を設定できます:{ "settings": { "yaml.customTags": ["!reference sequence"] } }