GitLab CI/CDテンプレート開発ガイド
このドキュメントでは、GitLab CI/CDテンプレートの開発者について説明します。
CI/CDテンプレートの要件
新規または更新された CI/CD テンプレートでマージリクエストを提出する前に、次のことが必要です:
- テンプレートを正しいディレクトリに配置します。
- CI/CD テンプレート作成ガイドラインに従ってください。
- テンプレートの名前は
*.gitlab-ci.yml
形式に従ってください。 - 有効な
.gitlab-ci.yml
構文を使用してください 。CI/CD lintツールで有効であることを確認してください。 - テンプレート・メトリクスを追加します。
- マージリクエストがユーザー向けの変更を導入する場合、変更履歴を含めます。
- テンプレートレビュープロセスに従ってください。
- (任意ですが、強く推奨します)レビュアーがアクセスできるGitLabのサンプルプロジェクトでテンプレートをテストします。レビュアーはテンプレートが必要とするデータや設定を作成できないかもしれないので、サンプルプロジェクトはレビュアーがテンプレートが正しいことを確認するのに役立ちます。レビューのためにマージリクエストを提出する前に、サンプルプロジェクトのパイプラインが成功する必要があります。
テンプレートディレクトリ
すべてのテンプレートファイルはlib/gitlab/ci/templates
に保存されます。一般的なテンプレートはこのディレクトリに保存されますが、特定のテンプレート・タイプはそのための特定のディレクトリが予約されています。新しいファイル UI でテンプレートを選択できるかどうかは、そのディレクトリによって決まります:
サブディレクトリ | UIで選択可能 | テンプレートタイプ |
---|---|---|
/* (ルート) | はい | 一般的なテンプレート。 |
/AWS/* | なし | クラウドデプロイに関するテンプレート(AWS). |
/Jobs/* | なし | Auto DevOpsに関連するテンプレート。 |
/Pages/* | はい | GitLab Pagesで静的サイトジェネレータを使用するためのサンプルテンプレート。 |
/Security/* | はい | セキュリティスキャナに関連するテンプレート。 |
/Terraform/* | なし | Infrastructure as Code(Terraform)関連のテンプレート。 |
/Verify/* | はい | テスト機能に関連するテンプレート。 |
/Workflows/* | なし |
workflow: キーワードを使用するためのサンプル テンプレートです。 |
テンプレート作成ガイドライン
テンプレート投稿が標準に従っていることを確認するために、以下のガイドラインを使用してください:
テンプレートの種類
テンプレートには、テンプレートの書き方や使い方に影響を与える2つの異なるタイプがあります。テンプレートのスタイルは、この2つのタイプのどちらかに合わせる必要があります:
パイプラインテンプレートは、プロジェクトの構造や言語などにマッチした、エンドツーエンドのCI/CDワークフローを提供します。通常、他の.gitlab-ci.yml
ファイルがないプロジェクトでは、パイプラインテンプレートを単独で使うべきです。
パイプラインテンプレートの作成者
-
image
やbefore_script
のようなグローバルキーワードは、テンプレートの一番上のdefault
セクションに置きます。 - そのテンプレートが、既存の
.gitlab-ci.yml
ファイルのincludes
キーワードとともに使用されるように設計されているかどうかを、コード・コメントに明記してください。
ジョブテンプレートは、既存のCI/CDワークフローに追加できる特定のジョブを提供します。通常、includes
キーワードを使用して既存の.gitlab-ci.yml
ファイルに追加して使用します。また、既存の.gitlab-ci.yml
ファイルに内容をコピー&ペーストすることもできます。
ジョブテンプレートを設定し、ユーザーが現在のパイプラインにほとんど、またはまったく変更せずに追加できるようにします。他のパイプライン設定と競合するリスクを減らすように設定する必要があります。
ジョブテンプレートの作成者
-
グローバルキーワードや
default
キーワードを使用しないでください。ル.gitlab-ci.yml
ートにテンプレートが含ま.gitlab-ci.yml
れる場合.gitlab-ci.yml
、グローバルキーワードやデフォルトキーワードがオーバーライドされ、予期しない動作を引き起こす可能性が.gitlab-ci.yml
あります。.gitlab-ci.yml
ジョブテンプレートが特定のステージを必要とする場合、ユーザーが手動でメイン設定にステージを追加しなければならないことをコードコメントで説明して.gitlab-ci.yml
ください。 -
コード・コメントには、テンプレートが
includes
キーワードと共に使用されるか、既存の設定にコピーされるように設計されていることを明確に記述してください。 -
後方互換性の問題を避けるために、テンプレートのバージョニングを最新かつ安定したバージョンにしてください。
includes
でインポートされたテンプレートを変更すると、そのテンプレートを使用しているすべてのプロジェクトのパイプラインが壊れる可能性があるため、このタイプのテンプレートのメンテナンスはより複雑になります。
テンプレート作成者のその他の注意点
テンプレート設計のポイント | パイプラインテンプレート | ジョブテンプレート |
---|---|---|
stages を含むグローバルキーワードを使用できます。 | はい | なし |
ジョブを定義できます。 | はい | はい |
新規ファイルUIで選択可能 | はい | なし |
他のジョブテンプレートをinclude
| はい | なし |
include で他のパイプラインテンプレートを含めることができます。 | なし | なし |
構文ガイドライン
テンプレートに従うことを容易にするために、テンプレートはすべて一貫した書式で明確な構文スタイルを使用すべきです。
すべてのジョブのbefore_script
,script
,after_script
キーワードはShellCheckを使用してリントされ、可能な限りシェルスクリプトの標準とスタイルガイドラインに従うべきです。
ShellCheckは、スクリプトがBashを使用して実行されるように設計されていることを前提としています。BashのShellCheckルールと互換性のないシェル用のスクリプトを使用するテンプレートは、ShellCheckのリンティングから除外できます。スクリプトを除外するには、scripts/lint_templates_bash.rb
のEXCLUDED_TEMPLATES
リストに追加します。
デフォルトのブランチをハードコーディングしないでください。
ハードコードされたmain
ブランチの代わりに$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
を使い、決してmaster
を使わないでください:
job1:
rules:
if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script:
echo "example job 1"
job2:
only:
variables:
- $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script:
echo "example job 2"
rules
only
またはexcept
only
やexcept
の使用はできるだけ避けてください。Only と except は現在開発されておらず、rules
が望ましい構文です:
job2:
script:
- echo
rules:
- if: $CI_COMMIT_BRANCH
長いコマンドを分割
コマンドが非常に長かったり、-o
や--option
のように多くのコマンドラインフラグがあったりする場合は、コマンドを分割してください:
- これらを複数行のコマンドに分割して、コマンドのすべての部分を見やすくしてください。
- フラグがある場合は、長い名前を使用してください。
例えば、docker run --e SOURCE_CODE="$PWD" -v "$PWD":/code -v /var/run/docker.sock:/var/run/docker.sock "$CODE_QUALITY_IMAGE" /code
のような短いCLIフラグを持つ長いコマンドの場合:
job1:
script:
- docker run
--env SOURCE_CODE="$PWD"
--volume "$PWD":/code
--volume /var/run/docker.sock:/var/run/docker.sock
"$CODE_QUALITY_IMAGE" /code
複数行のコマンドを分割するために|
と>
の YAML オペレータを使うこともできます。
コメントでテンプレートを説明します
新しいファイルメニューからテンプレートの内容にアクセスすることができ、これがユーザーがテンプレートに関する情報を見る唯一の場所かもしれません。テンプレートの動作をテンプレート自身で直接明確に文書化することが重要です。
以下のガイドラインは、すべてのテンプレート投稿で期待される基本的なコメントをカバーしています。コメントがユーザーやテンプレートのレビュアーに役立つと思われる場合は、必要に応じてコメントを追加してください。
要件と期待の説明
ファイルの一番上にある#
のコメントで、テンプレートの使い方の詳細を説明してください。これには
- リポジトリ/プロジェクト要件。
- 期待される動作
- テンプレートを使用する前にユーザーが編集しなければならない場所。
- テンプレートを設定ファイルにコピーペーストして使用する場合、または既存のパイプラインで
include
キーワードを使用して使用する場合。 - プロジェクトの CI/CD 設定に変数を保存する必要がある場合。
# Use this template to publish an application that uses the ABC server.
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
#
# Requirements:
# - An ABC project with content saved in /content and tests in /test
# - A CI/CD variable named ABC-PASSWORD saved in the project CI/CD settings. The value
# should be the password used to deploy to your ABC server.
# - An ABC server configured to listen on port 12345.
#
# You must change the URL on line 123 to point to your ABC server and port.
#
# For more information, see https://gitlab.com/example/abcserver/README.md
job1:
...
変数がテンプレートの動作にどのように影響するかを説明します。
テンプレートが変数を使用する場合、最初に定義される#
のコメントで説明します。変数が明白な場合はコメントを省略できます:
variables: # Good to have a comment here, for example:
TEST_CODE_PATH: <path/to/code> # Update this variable with the relative path to your Ruby specs
job1:
variables:
ERROR_MESSAGE: "The $TEST_CODE_PATH path is invalid" # (No need for a comment here, it's already clear)
script:
- echo ${ERROR_MESSAGE}
非ローカル変数には大文字小文字を区別しないでください。
CI/CDの設定やvariables
キーワードによって変数が提供されることを期待している場合、その変数はアンダースコア(_
)で単語を区切り、すべて大文字で命名する必要があります。
.with_login:
before_script:
# SECRET_TOKEN should be provided via the project settings
- docker login -u my-user -p "$SECRET_TOKEN my-registry
script
キーワードの内部で定義された変数には、オプションで小文字の命名を使用できます:
job1:
script:
- response="$(curl "https://example.com/json")"
- message="$(echo "$response" | jq -r .message)"
- 'echo "Server responded with: $message"'
下位互換性
テンプレートはinclude:template:
キーワードで動的に内部インクルードされるかもしれません。既存のテンプレートに変更を加える場合、既存のプロジェクトのCI/CDを壊さないようにしなければなりません。
例えば、テンプレートのジョブ名を変更すると、既存のプロジェクトのパイプラインが壊れる可能性があります。例えば、Performance.gitlab-ci.yml
という名前のテンプレートがあり、次のような内容になっているとします:
performance:
image: registry.gitlab.com/gitlab-org/verify-tools/performance:v0.1.0
script: ./performance-test $TARGET_URL
そして、ユーザーはperformance
ジョブに引数を渡すことでこのテンプレートをインクルードします。これは、.gitlab-ci.yml
_に_CI/CD 変数TARGET_URL
を指定することで可能です:
include:
template: Performance.gitlab-ci.yml
performance:
variables:
TARGET_URL: https://awesome-app.com
performance
テンプレートのジョブ名performance
がbrowser-performance
にリネームされた場合、ユーザーの.gitlab-ci.yml
は直ちに lint エラーを引き起こします。そのため、ユーザーはワークフローを混乱させる可能性のある.gitlab-ci.yml
を修正しなければなりません。
変更を安全に導入するために、バージョン管理のセクションを読んでください。
バージョニング
現在のテンプレートに依存している既存のプロジェクトに影響を与えることなく変更を加えるには、安定版と最新版を使用します。
通常、安定版テンプレートはメジャーバージョンのリリースでのみ変更点を受け取りますが、最新版テンプレートはどのリリースでも変更点を受け取ることができます。メジャーリリースのマイルストーンでは、最新のテンプレートが新しい安定版テンプレートになります(最新のテンプレートは削除されるかもしれません)。
最新のテンプレートを追加することは安全ですが、メンテナンスの負担が伴います:
- GitLabは、次のGitLabのメジャーリリース時に安定版テンプレートを最新テンプレートの内容で上書きするDRIを選ばなければなりません。DRIは、変更に問題があるユーザーをサポートする責任があります。
- 壊れることのない新しい変更を行うときは、安定版テンプレートと最新版テンプレートの両方を、可能な限り一致するように更新しなければなりません。
- 最新のテンプレートは予定よりも長く残る可能性があります。
新しい最新版テンプレートを追加する前に、その変更を安定版テンプレートに加えることができるかどうか確認してください。そのテンプレートがコピーペーストでの使用のみを意図している場合、安定版を直接変更することが可能かもしれません。マイナーマイルストーンで安定版テンプレートを変更する前に、確認してください:
-
パイプラインテンプレートであり、
includes
で使用するように設計されていないことを説明するコードコメントがあります。 -
CI/CD テンプレートの使用メトリクスは、使用量を示しません。メトリクスがテンプレートの使用量をゼロと示している場合、そのテンプレートは
include
でアクティブに使用されていません。
安定版
CI/CD テンプレートの安定版とは、主要なリリースのマイルストーンにおいてのみ変更を加えるテンプレートのことです。テンプレートの安定版には<template-name>.gitlab-ci.yml
のような名前をつけます、例えばJobs/Deploy.gitlab-ci.yml
。
13.0
のように、GitLab のメジャーマイルストーンリリースで利用可能な最新のテンプレートをコピーすることで、新しい安定版テンプレートを作ることができます。例えば、GitLab.comは13.0に移行し、狭い範囲で変更を加えています。
13.1
のようなGitLabのマイナーリリースで、安定版テンプレートのバージョンを変更できるのは以下の場合です:
- その変更がブレークチェンジでないこと。
- この変更は、最新のテンプレートが存在すれば、それに移植されます。
最新バージョン
latest
とマークされたテンプレートは、どのリリースでも更新できます。最新バージョンとみなされる場合は、テンプレート名に.latest
を追加してください。例えば、Jobs/Deploy.latest.gitlab-ci.yml
。
壊れる変更を導入する場合、アップグレードパスをテストし、文書化する必要があります。一般的に、最新のテンプレートを最良の選択肢として昇格させるべきではありません。
latest
テンプレートがまだ存在しない場合は、安定版テンプレートをコピーすることができます。
古い安定版テンプレートをインクルードする方法
ユーザーは、現在のGitLabパッケージにバンドルされていない古い安定版テンプレートを使いたいと思うかもしれません。例えば、GitLab 13.0とGitLab 14.0の安定版テンプレートはとても異なっていて、GitLab 14.0にアップグレードした後でもGitLab 13.0のテンプレートを使い続けたいというユーザーがいるかもしれません。
include:remote
、古いバージョンのテンプレートをインクルードする方法を説明するメモをテンプレートやドキュメントに追加することができます。他のテンプレートがinclude: template
に含まれている場合は、include: remote
と組み合わせることができます:
# To use the v13 stable template, which is not included in v14, fetch the specific
# template from the remote template repository with the `include:remote:` keyword.
# If you fetch from the GitLab canonical project, use the following URL format:
# https://gitlab.com/gitlab-org/gitlab/-/raw/<version>/lib/gitlab/ci/templates/<template-name>
include:
- template: Auto-DevOps.gitlab-ci.yml
- remote: https://gitlab.com/gitlab-org/gitlab/-/raw/v13.0.1-ee/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
さらに読む
GitLab CI/CDテンプレートにバージョニングの概念を導入することに関するオープンイシューがあります。このイシューで進捗を確認することができます。
テスト
各CI/CDテンプレートは、公開しても安全であることを確認するためにテストされなければなりません。
手動QA
テンプレートを最小限のデモプロジェクトでテストすることは常に良い習慣です。そのためには、以下の手順に従ってください:
- https://gitlab.comに公開サンプルプロジェクトを作成します。
- 提案されたテンプレートで
.gitlab-ci.yml
をプロジェクトに追加します。 - パイプラインを実行し、すべての可能なケース(マージリクエストパイプライン、スケジュールなど)で、すべてが適切に実行されることを確認します。
- 新しいテンプレートを追加するマージリクエストの説明でプロジェクトにリンクしてください。
これはレビュアーがテンプレートをマージしても安全であることを確認するための有用な情報です。
新しいテンプレートがUIで選択できることを確認してください。
いくつかのディレクトリにあるテンプレートは、新規ファイルUIでも選択可能です。これらのディレクトリの1つにテンプレートを追加する場合、ドロップダウンリストに正しく表示されることを確認してください:
RSpec テストを書く
パイプラインジョブが正しく生成されることを確認するために、RSpecテストを書く必要があります:
- テストファイルを
spec/lib/gitlab/ci/templates/<template-category>/<template-name>_spec.rb
- パイプラインジョブが
Ci::CreatePipelineService
経由で正しく作成されることをテストします。
変更点の検証
latest
テンプレートにブレークチェンジを導入する場合、次のことが必要です:
- 安定版テンプレートからのアップグレードパスをテストしてください。
- ユーザーがどのようなエラーに遭遇するかを検証してください。
- トラブルシューティングガイドとして文書化します。
この情報は、GitLabのメジャーバージョンリリースで安定版テンプレートが更新されたときにユーザーにとって重要です。
メトリクスを追加
すべての CI/CD テンプレートには、その使用状況を追跡するためのメトリクスを定義する必要があります。CI/CD テンプレートの月間使用レポートはSisense で見ることができます(GitLab チームメンバーのみ)。テンプレートを選択すると、そのテンプレートのグラフが表示されます。
新しいテンプレートのメトリクス定義を追加するには:
- GitLab GDKをインストールし、起動します。
- GDK の
gitlab
ディレクトリで、新しいテンプレートを含むブランチをチェックしてください。 - 新しいテンプレートのイベント名を、週ごとと月ごとの CI/CD テンプレート総数のメトリクスに追加します:
-
上記と同じイベント名を次のコマンドの最後の引数として使用して、新しいメトリクス定義を追加します:
bundle exec rails generate gitlab:usage_metric_definition:redis_hll ci_templates <template_metric_event_name>
出力は次のようになります:
$ bundle exec rails generate gitlab:usage_metric_definition:redis_hll ci_templates p_ci_templates_my_template_name create config/metrics/counts_7d/20220120073740_p_ci_templates_my_template_name_weekly.yml create config/metrics/counts_28d/20220120073746_p_ci_templates_my_template_name_monthly.yml
-
新しく生成された両方のファイルを以下のように編集してください:
-
name:
およびperformance_indicator_type:
: 削除 (不要)。 -
introduced_by_url:
:テンプレートを追加するMRのURL。 -
data_source:
:redis_hll
に設定します。 -
description
:このメトリクスが何をカウントしているかの短い説明を追加します:Count of pipelines using the latest Auto Deploy template
-
product_*
:メトリクス辞書ガイドに従って、セクション、ステージ、グループ、機能カテゴリに設定します。これらのキーワードに何を使用すればよいかわからない場合は、マージリクエストで助けを求めることができます。 -
各ファイルの末尾に以下を追加してください:
options: events: - p_ci_templates_my_template_name
-
- 変更をコミットしてプッシュしてください。
例えば、これらは5分プロダクションアプリテンプレートのメトリクス設定ファイルです:
- 週間および月間メトリクス定義:
- メトリクスのカウント合計:
セキュリティ
テンプレートは悪意のあるコードを含む可能性があります。例えば、ジョブ内にexport
シェルコマンドを含むテンプレートは、誤ってジョブログに秘密のプロジェクト CI/CD 変数を公開してしまうかもしれません。安全かどうかわからない場合は、セキュリティの専門家に相互検証を依頼する必要があります。
CI/CD テンプレートのマージリクエストに貢献してください。
あなたの CI/CD テンプレート MR が作成され、ci::templates
でラベル付けされた後、DangerBot はあなたのコードをレビューできるレビュアーとメンテナーを一人ずつ提案します。あなたのマージリクエストがレビューできる状態になったら、レビュアーについて言及し、CI/CDテンプレートの変更をレビューするよう依頼してください。CI/CD テンプレート MR のために DangerBot タスクを追加したマージリクエストの詳細を参照してください。