GitLab CI/CD設定ファイルを最適化する
- プラン: Free、Premium、Ultimate
- 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated
次の機能やキーワードを使用すると、GitLab CI/CD設定ファイルにおける複雑さや重複した設定を軽減できます:
- アンカー(
&)、エイリアス(*)、マップのマージ(<<)などのYAML固有の機能。さまざまなYAMLの機能について、詳細をご覧ください。 - より柔軟で読みやすい
extendsキーワード。可能な場合はextendsの使用が推奨されます。
複数の類似したジョブを作成するものの、異なる変数の値を使用するには、`parallel:matrixを使用します。
アンカー
YAMLには「アンカー」という機能があり、ドキュメント全体で内容を複製して利用できます。
アンカーを使用して、プロパティを複製または継承できます。非表示ジョブでアンカーを使用して、ジョブのテンプレートを提供できます。重複するキーがある場合、最後に追加されたキーが優先され、その他のキーはオーバーライドされます。
特定のケース(スクリプトのYAMLアンカーを参照)では、YAMLアンカーを使用して、他の場所で定義された複数のコンポーネントを含む配列を作成できます。例は次のとおりです:
.default_scripts: &default_scripts
- ./default-script1.sh
- ./default-script2.sh
job1:
script:
- *default_scripts
- ./job-script.shincludeキーワードを使用する場合、複数のファイルにまたがってYAMLアンカーを使用することはできません。アンカーは、定義されたファイル内でのみ有効です。異なるYAMLファイルから設定を再利用するには、!referenceタグまたはextendsキーワードを使用します。
次の例では、アンカーとマップのマージを使用します。test1とtest2の2つのジョブを作成します。これらのジョブは.job_template設定を継承し、それぞれに独自のカスタム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アンカー
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-afterextendsを使用して設定セクションを再利用する
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 spinachextendsからキーを除外する
拡張された内容からキーを除外するには、そのキーに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: nullextendsとincludeを組み合わせて使用する
異なる設定ファイルから設定を再利用するには、extendsとincludeを組み合わせます。
次の例では、included.ymlファイルでscriptが定義されています。次に、.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タグ
カスタムYAMLタグ!referenceを使用して、その他のジョブセクションからキーワード設定を選択し、現在のセクションで再利用できます。YAMLアンカーとは異なり、!referenceタグを使用してインクルードされた設定ファイルから設定を再利用することもできます。
次の例では、2つの異なる場所にあるscriptとafter_scriptをtestジョブ内で再利用しています:
configs.yml:.setup: script: - echo creating environment.gitlab-ci.yml:include: - local: configs.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!referenceタグをparallel:matrixキーワードとともに使用する場合、既知のイシューが存在します。
CI/CD入力は!referenceタグでは使用できません。!referenceタグは入力補間の前に評価されるためです。
script、before_script、after_script内で!referenceタグをネストする
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タグをサポートしています。ただし、!referenceのようなカスタムYAMLタグのスキーマルールは、デフォルトではエディタによって無効と見なされる場合があります。一部のエディタでは、!referenceタグを受け入れるように設定できます。例は次のとおりです:
VS Codeでは、
settings.jsonファイル内で、customTagsを解析するようにvscode-yamlを設定できます:"yaml.customTags": [ "!reference sequence" ]Sublime Textで
LSP-yamlパッケージを使用している場合は、LSP-yamlユーザー設定でcustomTagsを設定できます:{ "settings": { "yaml.customTags": ["!reference sequence"] } }