GitLab CI/CDテンプレート開発ガイド

このドキュメントでは、GitLab CI/CDテンプレートの開発者について説明します。

CI/CDテンプレートの要件

新規または更新された CI/CD テンプレートでマージリクエストを提出する前に、次のことが必要です:

テンプレートディレクトリ

すべてのテンプレートファイルは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 ファイルがないプロジェクトでは、パイプラインテンプレートを単独で使うべきです。

パイプラインテンプレートの作成者

  • imagebefore_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.rbEXCLUDED_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

onlyexcept の使用はできるだけ避けてください。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 テンプレートのジョブ名performancebrowser-performance にリネームされた場合、ユーザーの.gitlab-ci.yml は直ちに lint エラーを引き起こします。そのため、ユーザーはワークフローを混乱させる可能性のある.gitlab-ci.yml を修正しなければなりません。

変更を安全に導入するために、バージョン管理のセクションを読んでください。

バージョニング

現在のテンプレートに依存している既存のプロジェクトに影響を与えることなく変更を加えるには、安定版と最新版を使用します。

通常、安定版テンプレートはメジャーバージョンのリリースでのみ変更点を受け取りますが、最新版テンプレートはどのリリースでも変更点を受け取ることができます。メジャーリリースのマイルストーンでは、最新のテンプレートが新しい安定版テンプレートになります(最新のテンプレートは削除されるかもしれません)。

最新のテンプレートを追加することは安全ですが、メンテナンスの負担が伴います:

  • GitLabは、次のGitLabのメジャーリリース時に安定版テンプレートを最新テンプレートの内容で上書きするDRIを選ばなければなりません。DRIは、変更に問題があるユーザーをサポートする責任があります。
  • 壊れることのない新しい変更を行うときは、安定版テンプレートと最新版テンプレートの両方を、可能な限り一致するように更新しなければなりません。
  • 最新のテンプレートは予定よりも長く残る可能性があります。

新しい最新版テンプレートを追加する前に、その変更を安定版テンプレートに加えることができるかどうか確認してください。そのテンプレートがコピーペーストでの使用のみを意図している場合、安定版を直接変更することが可能かもしれません。マイナーマイルストーンで安定版テンプレートを変更する前に、確認してください:

安定版

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

テンプレートを最小限のデモプロジェクトでテストすることは常に良い習慣です。そのためには、以下の手順に従ってください:

  1. https://gitlab.comに公開サンプルプロジェクトを作成します。
  2. 提案されたテンプレートで.gitlab-ci.yml をプロジェクトに追加します。
  3. パイプラインを実行し、すべての可能なケース(マージリクエストパイプライン、スケジュールなど)で、すべてが適切に実行されることを確認します。
  4. 新しいテンプレートを追加するマージリクエストの説明でプロジェクトにリンクしてください。

これはレビュアーがテンプレートをマージしても安全であることを確認するための有用な情報です。

新しいテンプレートがUIで選択できることを確認してください。

いくつかのディレクトリにあるテンプレートは、新規ファイルUIでも選択可能です。これらのディレクトリの1つにテンプレートを追加する場合、ドロップダウンリストに正しく表示されることを確認してください:

CI/CD template selection

RSpec テストを書く

パイプラインジョブが正しく生成されることを確認するために、RSpecテストを書く必要があります:

  1. テストファイルをspec/lib/gitlab/ci/templates/<template-category>/<template-name>_spec.rb
  2. パイプラインジョブがCi::CreatePipelineService 経由で正しく作成されることをテストします。

変更点の検証

latest テンプレートにブレークチェンジを導入する場合、次のことが必要です:

  1. 安定版テンプレートからのアップグレードパスをテストしてください。
  2. ユーザーがどのようなエラーに遭遇するかを検証してください。
  3. トラブルシューティングガイドとして文書化します。

この情報は、GitLabのメジャーバージョンリリースで安定版テンプレートが更新されたときにユーザーにとって重要です。

メトリクスを追加

すべての CI/CD テンプレートには、その使用状況を追跡するためのメトリクスを定義する必要があります。CI/CD テンプレートの月間使用レポートはSisense で見ることができます(GitLab チームメンバーのみ)。テンプレートを選択すると、そのテンプレートのグラフが表示されます。

新しいテンプレートのメトリクス定義を追加するには:

  1. GitLab GDKをインストールし、起動します。
  2. GDK のgitlab ディレクトリで、新しいテンプレートを含むブランチをチェックしてください。
  3. 新しいテンプレートのイベント名を、週ごとと月ごとの CI/CD テンプレート総数のメトリクスに追加します:
  4. 上記と同じイベント名を次のコマンドの最後の引数として使用して、新しいメトリクス定義を追加します:

    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
    
  5. 新しく生成された両方のファイルを以下のように編集してください:

    • 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
      
  6. 変更をコミットしてプッシュしてください。

例えば、これらは5分プロダクションアプリテンプレートのメトリクス設定ファイルです:

セキュリティ

テンプレートは悪意のあるコードを含む可能性があります。例えば、ジョブ内にexport シェルコマンドを含むテンプレートは、誤ってジョブログに秘密のプロジェクト CI/CD 変数を公開してしまうかもしれません。安全かどうかわからない場合は、セキュリティの専門家に相互検証を依頼する必要があります。

CI/CD テンプレートのマージリクエストに貢献してください。

あなたの CI/CD テンプレート MR が作成され、ci::templates でラベル付けされた後、DangerBot はあなたのコードをレビューできるレビュアーとメンテナーを一人ずつ提案します。あなたのマージリクエストがレビューできる状態になったら、レビュアーについて言及し、CI/CDテンプレートの変更をレビューするよう依頼してください。CI/CD テンプレート MR のために DangerBot タスクを追加したマージリクエストの詳細を参照してください。