CI設定内部
ワークフロールール
GitLab プロジェクトのパイプラインは、GitLab CI/CD のworkflow:rules
キーワード 機能を使って作成します。
パイプラインは常に以下のシナリオのために作成されます:
-
main
ブランチ(スケジュール、プッシュ、マージなど)。 - マージリクエスト
- タグ
- 安定、
auto-deploy
、セキュリティブランチ。
パイプラインの作成は、以下の CI/CD 変数の影響も受けます:
-
$FORCE_GITLAB_CI
が設定されている場合、パイプラインが作成されます。使用は推奨されません。$FORCE_GITLAB_CI
を参照してください。 -
$GITLAB_INTERNAL
が設定されていない場合、パイプラインは作成されません。
それ以外の場合、パイプラインは作成されません (たとえば、MR のないブランチをプッシュする場合など)。
これらのワークフロールールのソースオブトゥルースは、.gitlab-ci.yml
で定義されています。
避ける$FORCE_GITLAB_CI
パイプラインは非常に複雑で、どのようなパイプラインをトリガーしたいのかを明確に理解する必要があります。どのジョブを実行すべきで、どのジョブを実行すべきでないかを知る必要があります。
パイプラインを強制的にトリガーするために$FORCE_GITLAB_CI
を使用した場合、どのようなパイプラインなのかがよくわかりません。その結果、必要なジョブが実行されなかったり、どうでもいいジョブがたくさん実行されたりします。
より詳細な背景については、以下を参照してください:予期せぬ実行を避けるために、包括的な変更は避けましょう
以下は、私たちが今現在これを使用している場所のリストです。$FORCE_GITLAB_CI
.
デフォルトの画像
デフォルトの画像は.gitlab-ci.yml
で定義されています。
Ruby、Go、Git、Git LFS、Chrome、Node、Yarn、PostgreSQL、Graphics Magickが含まれています。
パイプラインで使用されるイメージはgitlab-org/gitlab-build-images
プロジェクトで設定され、冗長性のためにgitlab/gitlab-build-images
にプッシュミラーされています。
現在のビルドイメージのバージョンは、“Used by GitLab section “にあります。
デフォルト変数
定義済みのCI/CD変数に加えて、各パイプラインには.gitlab-ci.yml
で定義されたデフォルト変数が含まれています。
ステージ
現在のステージは以下の通りです:
-
sync
:このステージはgitlab-org/gitlab
からgitlab-org/gitlab-foss
への変更の同期に使用されます。 -
prepare
:このステージには、後続ステージのジョブが必要とするアーティファクトを準備するジョブが含まれます。 -
build-images
:このステージには、後続ステージやダウンストリームパイプラインのジョブが必要とするDockerイメージを準備するジョブが含まれます。 -
fixtures
:このステージには、フロントエンドのテストに必要なフィクスチャを準備するジョブが含まれます。 -
lint
:このステージはリントと静的解析のジョブを含みます。 -
test
:このステージにはほとんどのテストとDB/マイグレーションジョブが含まれます。 -
post-test
:このステージには、レポーターを作成したり、test
ステージのジョブからデータを収集したりするジョブが含まれます (カバレッジ、Knapsack メタデータなど)。 -
review
:このステージには、CNG イメージをビルドし、デプロイし、レビューアプリに対してエンドツーエンドのテストを実行するジョブが含まれます (詳細はレビューアプリを参照してください)。Docs レビューアプリのジョブも含まれます。 -
qa
:このステージには、ステージreview
でデプロイされたレビューアプリに対して QA タスクを実行するジョブが含まれます。 -
post-qa
:このステージには、レポートを作成したり、qa
ステージのジョブからデータを収集したりするジョブが含まれます (レビューアプリのパフォーマンスレポートなど)。 -
pages
:このステージには、様々なレポートをGitLab Pagesとしてデプロイするジョブが含まれます(例えば、coverage-ruby
、webpack-report
(https://gitlab-org.gitlab.io/gitlab/webpack-report/
で見つかりましたが、デプロイにイシューがあります)。 -
notify
:このステージには、様々な失敗をSlackに通知するジョブが含まれます。
依存関係プロキシ
ジョブの中にはDocker Hubのイメージを使用しているものがあります。この場合、依存プロキシからイメージを取得するために、イメージパスのプレフィックスとして${GITLAB_DEPENDENCY_PROXY_ADDRESS}
を使用します。デフォルトでは、この変数は${GITLAB_DEPENDENCY_PROXY}
の値から設定されます。
${GITLAB_DEPENDENCY_PROXY}
はgitlab-org
で${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/
として定義されているグループ CI/CD 変数です。と定義されています:
image: ${GITLAB_DEPENDENCY_PROXY_ADDRESS}alpine:edge
gitlab-org
グループ内のプロジェクトは依存プロキシからプルしますが、他の個人ネームスペースやグループに存在するフォークは、${GITLAB_DEPENDENCY_PROXY}
が定義されていない限りDocker Hubにフォールバックします。
プロジェクトアクセストークンユーザーによってパイプラインが開始された場合の回避策
パイプラインがプロジェクトアクセストークンユーザー(例えば、メインプロジェクトで使用されるGitalyバージョンを自動的に更新するrelease-tools approver bot
ユーザー)によって開始されると、依存プロキシにアクセスできず、Preparing the "docker+machine" executor
ステップでジョブが失敗します。これを回避するために、${GITLAB_DEPENDENCY_PROXY_ADDRESS}
変数をオーバーライドする特別なワークフロールールを用意し、依存プロキシが使用されないようにしています:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $GITLAB_USER_LOGIN =~ /project_\d+_bot\d*/'
variables:
GITLAB_DEPENDENCY_PROXY_ADDRESS: ""
.gitlab-ci.yml
変数よりも優先順位が高いため、${GITLAB_DEPENDENCY_PROXY}
変数を直接上書きすることはありません。一般的なジョブ定義
ほとんどのジョブは、.gitlab/ci/global.gitlab-ci.yml
で定義された、単一の設定キーワードにスコープされたいくつかのCI定義から拡張されます。
ジョブの定義 | 説明 |
---|---|
.default-retry |
unknown_failure ,api_failure ,runner_system_failure ,job_execution_timeout ,stuck_or_timeout_failure のときにジョブの再試行を許可します。 |
.default-before_script | データベースの実行が必要なRuby/Railsタスク (たとえばテスト) に適したデフォルトのbefore_script 定義をジョブで使用できるようにします。 |
.setup-test-env-cache | ジョブに、後続のRuby/Railsタスクのテスト環境を設定するのに適したデフォルトのcache 定義を使えるようにします。 |
.ruby-cache | Ruby タスクに適したデフォルトのcache 定義をジョブに使わせます。 |
.static-analysis-cache | ジョブが静的解析タスクに適したデフォルトのcache 定義を使えるようにします。 |
.ruby-gems-coverage-cache | ジョブがカバレッジタスクに適したデフォルトのcache 定義を使用できるようにします。 |
.qa-cache | ジョブがQAタスクに適したデフォルトのcache 定義を使用できるようにします。 |
.yarn-cache |
yarn install を行うフロントエンドジョブに適したデフォルトのcache 定義をジョブに使用できるようにします。 |
.assets-compile-cache | アセットをコンパイルするフロントエンドジョブに適したデフォルトのcache 定義をジョブが使用できるようにします。 |
.use-pg13 | ジョブがpostgres 13、redis 、およびrediscluster サービスを使用できるようにします (サービスの特定のバージョンについては.gitlab/ci/global.gitlab-ci.yml を参照してください)。 |
.use-pg13-ee |
.use-pg13 と同じですが、elasticsearch サービスも使用します (サービスの具体的なバージョンは.gitlab/ci/global.gitlab-ci.yml を参照)。 |
.use-pg14 | ジョブがpostgres 14、redis 、およびrediscluster サービスを使用できるようにします (サービスの具体的なバージョンは.gitlab/ci/global.gitlab-ci.yml を参照)。 |
.use-pg14-ee |
.use-pg14 と同じですが、elasticsearch サービスも使用します (サービスの具体的なバージョンは.gitlab/ci/global.gitlab-ci.yml を参照)。 |
.use-pg15 | ジョブがpostgres 15、redis 、およびrediscluster サービスを使用できるようにします (サービスの具体的なバージョンは.gitlab/ci/global.gitlab-ci.yml を参照)。 |
.use-pg15-ee |
.use-pg15 と同じですが、elasticsearch サービスも使用します (サービスの具体的なバージョンは.gitlab/ci/global.gitlab-ci.yml を参照)。 |
.use-kaniko | ジョブがkaniko ツールを使って Docker イメージをビルドできるようにします。 |
.as-if-foss |
FOSS_ONLY='1' CI/CD変数を設定してFOSSプロジェクトをシミュレートします。 |
.use-docker-in-docker | ジョブがDockerでDockerを使えるようにします。詳細はCI/CD設定についてのハンドブックを参照してください。 |
rules
,if:
条件とchanges:
パターン
rules
キーワード を多用しています。
すべてのrules
定義はrules.gitlab-ci.yml
で定義され、extends
を介して個々のジョブに含まれます。
rules
定義はif:
条件とchanges:
パターンで Composer されます。これらはrules.gitlab-ci.yml
でも定義され、YAML アンカーを介してrules
定義に含まれます。
if:
条件
if: 条件 | 説明 | 備考 |
---|---|---|
if-not-canonical-namespace | プロジェクトが正規 (gitlab-org/ とgitlab-cn/ ) またはセキュリティ (gitlab-org/security ) 名前空間にない場合にマッチします。 | フォーク用のジョブを作成する場合 (when: on_success またはwhen: manual を使用)、またはフォーク用のジョブを作成しない場合 (when: never を使用) に使用します。 |
if-not-ee | プロジェクトがEEでない場合(つまり、プロジェクト名がgitlab またはgitlab-ee でない場合)にマッチします。 | FOSSプロジェクトでのみジョブを作成する場合(when: on_success またはwhen: manual を使用)、プロジェクトがEEの場合はジョブを作成しない場合(when: never を使用)に使用します。 |
if-not-foss | プロジェクトがFOSSでない場合(つまり、プロジェクト名がgitlab-foss 、gitlab-ce 、gitlabhq でない場合)にマッチします。 | EEプロジェクトでのみジョブを作成する場合(when: on_success またはwhen: manual を使用)、プロジェクトがFOSSの場合はジョブを作成しない場合(when: never を使用)に使用します。 |
if-default-refs | パイプラインがmaster 、main 、/^[\d-]+-stable(-ee)?$/ (安定ブランチ)、/^\d+-\d+-auto-deploy-\d+$/ (自動デプロイブランチ)、/^security\// (セキュリティブランチ)、マージリクエスト、タグの場合にマッチします。 | このデフォルト設定のブランチでは、ジョブは作成されないことに注意してください。 |
if-master-refs | 現在のブランチがmaster またはmain の場合にマッチします。 | |
if-master-push | 現在のブランチがmaster またはmain で、パイプラインソースがpush の場合にマッチします。 | |
if-master-schedule-maintenance | 現在のブランチがmaster またはmain で、パイプラインが 2 時間ごとのスケジュールで実行されている場合にマッチします。 | |
if-master-schedule-nightly | 現在のブランチがmaster またはmain で、パイプラインが夜間スケジュールで実行されている場合にマッチします。 | |
if-auto-deploy-branches | 現在のブランチが自動デプロイされている場合にマッチします。 | |
if-master-or-tag | パイプラインがmaster ブランチかmain ブランチ、またはタグのものである場合にマッチします。 | |
if-merge-request | パイプラインがマージリクエストの場合にマッチします。 | |
if-merge-request-title-as-if-foss | パイプラインがマージリクエストで、MR のラベルが ~"pipeline:run-as-if-foss" の場合にマッチします。 | |
if-merge-request-title-update-caches | パイプラインがマージリクエストで、MR のラベルが ~"pipeline:update-cache" の場合にマッチします。 | |
if-merge-request-labels-run-all-rspec | パイプラインがマージリクエストで、MR のラベルが ~"pipeline:run-all-rspec" の場合に一致します。 | |
if-security-merge-request | パイプラインがセキュリティマージリクエストの場合にマッチします。 | |
if-security-schedule | パイプラインがセキュリティスケジュールパイプラインの場合にマッチします。 | |
if-nightly-master-schedule | パイプラインが$NIGHTLY が設定されたmaster スケジュールパイプラインの場合にマッチします。 | |
if-dot-com-gitlab-org-schedule | GitLab.com のgitlab-org グループのスケジュールされたパイプラインにジョブの作成を制限します。 | |
if-dot-com-gitlab-org-master | GitLab.comのgitlab-org グループに対して、ジョブの作成をmaster またはmain ブランチに制限します。 | |
if-dot-com-gitlab-org-merge-request | GitLab.com のgitlab-org グループに対して、ジョブの作成をマージリクエストに制限します。 | |
if-dot-com-gitlab-org-and-security-tag | GitLab.com のgitlab-org とgitlab-org/security グループに対して、ジョブの作成をタグに制限します。 | |
if-dot-com-gitlab-org-and-security-merge-request | GitLab.com のgitlab-org とgitlab-org/security グループに対して、ジョブの作成をマージリクエストに制限します。 | |
if-dot-com-gitlab-org-and-security-tag | GitLab.com のgitlab-org とgitlab-org/security グループに対して、ジョブ作成をタグに制限。 | |
if-dot-com-ee-schedule | GitLab.com のgitlab-org/gitlab プロジェクトのスケジュールされたパイプラインにジョブを制限します。 |
changes:
パターン
changes: パターン | 説明 |
---|---|
ci-patterns | CI設定関連の変更にのみジョブを作成します。 |
ci-build-images-patterns |
build-images ステージに関連する CI 設定関連の変更にのみジョブを作成します。 |
ci-review-patterns |
review ステージに関連する CI 設定関連の変更にのみジョブを作成します。 |
ci-qa-patterns |
qa ステージに関連する CI 設定関連の変更にのみジョブを作成します。 |
yaml-lint-patterns | YAML関連の変更に対してのみジョブを作成します。 |
docs-patterns | docs関連の変更にのみジョブを作成します。 |
frontend-dependency-patterns | フロントエンドの依存関係が更新されたときのみジョブを作成します (たとえば、package.json 、yarn.lock )。 |
frontend-patterns-for-as-if-foss | FOSSに影響を与えるフロントエンド関連の変更に対してのみジョブを作成します。 |
backend-patterns | バックエンド関連の変更にのみジョブを作成します。 |
db-patterns | DB関連の変更にのみジョブを作成します。 |
backstage-patterns | バックステージ関連の変更 (つまり、Danger、フィクスチャ、RuboCop、specs) に対してのみジョブを作成します。 |
code-patterns | コード関連の変更にのみジョブを作成します。 |
qa-patterns | QA関連の変更にのみジョブを作成してください。 |
code-backstage-patterns |
code-patterns とbackstage-patterns の組み合わせ。 |
code-qa-patterns |
code-patterns とqa-patterns の組み合わせ。 |
code-backstage-qa-patterns |
code-patterns 、backstage-patterns 、qa-patterns の組み合わせ。 |
static-analysis-patterns | ジョブの作成は、Static Analytics設定関連の変更に限定してください。 |
ベストプラクティス
extends:
、<<: *xyz
(YAMLアンカー)、あるいは!reference
キーポイント
-
ハッシュを拡張する必要がある場合は
extends
-
配列を拡張する必要がある場合は、
!reference
を使うか、最後の手段としてYAML anchors
を使う必要があります。 - より複雑な場合 (たとえば、配列の内部でハッシュを拡張する、ハッシュの内部で配列を拡張する…) には、
!reference
またはYAML anchors
extends
とYAML anchors
は何ができますか?
extends
- ハッシュのディープマージ
- 配列に対するマージはありません。上書きします。
YAML アンカー
- ハッシュのディープマージはできませんが、ハッシュを拡張するために使用することはできます (以下の例を参照ください)。
- 配列のマージは行いませんが、配列を拡張するために使用することはできます (以下の例を参照ください)。
すばらしい例
この例では、複雑な YAML データ構造を!reference
とYAML anchors
で拡張する方法を示します:
.strict-ee-only-rules:
# `rules` is an array of hashes
rules:
- if: '$CI_PROJECT_NAME !~ /^gitlab(-ee)?$/ '
when: never
# `if-security-merge-request` is a hash
.if-security-merge-request: &if-security-merge-request
if: '$CI_PROJECT_NAMESPACE == "gitlab-org/security"'
# `code-qa-patterns` is an array
.code-qa-patterns: &code-qa-patterns
- "{package.json,yarn.lock}"
- ".browserslistrc"
- "babel.config.js"
- "jest.config.{base,integration,unit}.js"
.qa:rules:as-if-foss:
rules:
# We extend the `rules` array with an array of hashes directly
- !reference [".strict-ee-only-rules", rules]
# We extend a single array entry with a hash
- <<: *if-security-merge-request
# `changes` is an array, so we pass it an entire array
changes: *code-qa-patterns
qa:selectors-as-if-foss:
# We include the rules from .qa:rules:as-if-foss in this job
extends:
- .qa:rules:as-if-foss
.fast-no-clone-job
ジョブの拡張
正規プロジェクトのブランチをダウンロードするのに20秒から30秒かかります。
GitLab API を使ってダウンロードできる限られた数のファイルしか必要としないジョブもあります。
以下のパターンをジョブに追加することで、ジョブgit clone
/git fetch
をスキップすることができます。
シナリオ 1: ジョブにbefore_script
が定義されていない場合。
これはジョブが拡張する親セクションにもあてはまります。
.fast-no-clone-job
を拡張するだけです:
を拡張するだけです:
# Note: No `extends:` is present in the job
a-job:
script:
- source scripts/rspec_helpers.sh scripts/slack
- echo "No need for a git clone!"
After:
# Note: No `extends:` is present in the job
a-job:
extends:
- .fast-no-clone-job
variables:
FILES_TO_DOWNLOAD: >
scripts/rspec_helpers.sh
scripts/slack
script:
- source scripts/rspec_helpers.sh scripts/slack
- echo "No need for a git clone!"
シナリオ2:before_script
ブロックがジョブ(もしくはジョブが拡張するジョブ)内ですでに定義されている場合
このシナリオでは、あなたは
- 最初のシナリオと同様に、
.fast-no-clone-job
を拡張します(これにより、FILES_TO_DOWNLOAD
変数が他の変数とマージされます)。 -
.fast-no-clone-job
のbefore_script
セクションが、このジョブで使用するbefore_script
で参照されていることを確認してください。
を拡張するだけです:
.base-job:
before_script:
echo "Hello from .base-job"
a-job:
extends:
- .base-job
script:
- source scripts/rspec_helpers.sh scripts/slack
- echo "No need for a git clone!"
After:
.base-job:
before_script:
echo "Hello from .base-job"
a-job:
extends:
- .base-job
- .fast-no-clone-job
variables:
FILES_TO_DOWNLOAD: >
scripts/rspec_helpers.sh
scripts/slack
before_script:
- !reference [".fast-no-clone-job", before_script]
- !reference [".base-job", before_script]
script:
- source scripts/rspec_helpers.sh scripts/slack
- echo "No need for a git clone!"
注意点
- このパターンは、リポジトリへのアクセスを
git
に依存しているスクリプトでは動作しません。なぜなら、クローンやフェッチなしではリポジトリを持っていないからです。 - このパターンを使用するジョブは
curl
を利用できる必要があります。 - ジョブ内で
bundle install
を実行する必要がある場合 (BUNDLE_ONLY
を使用する場合でも)、必要です:-
gitlab-org/gitlab
プロジェクトに格納されている gems をダウンロードします。- そのためには
download_local_gems
shell コマンドを使用します。
- そのためには
-
Gemfile
、Gemfile.lock
、Gemfile.checksum
(該当する場合)を含めます。
-
このパターンはどこで使われていますか?
- 今のところ、私たちはこのパターンを以下のようなジョブに使っており、これらは非公開リポジトリをブロックしません:
-
review-build-cng-env
のためです:GITALY_SERVER_VERSION
GITLAB_ELASTICSEARCH_INDEXER_VERSION
GITLAB_KAS_VERSION
GITLAB_METRICS_EXPORTER_VERSION
GITLAB_PAGES_VERSION
GITLAB_SHELL_VERSION
scripts/trigger-build.rb
VERSION
-
review-deploy
のためです:GITALY_SERVER_VERSION
GITLAB_SHELL_VERSION
scripts/review_apps/review-apps.sh
scripts/review_apps/seed-dast-test-data.sh
VERSION
-
rspec:coverage
のためです:config/bundler_setup.rb
Gemfile
Gemfile.checksum
Gemfile.lock
scripts/merge-simplecov
spec/simplecov_env_core.rb
spec/simplecov_env.rb
-
さらに、このパターンが使用されると、scripts/utils.sh
が常にAPIからダウンロードされます(このファイルには、.fast-no-clone-job
のコードが含まれています)。
ランナーのタグ
GitLab.com では、非特権ランナーと特権ランナーの両方が利用できます。gitlab-org
グループのプロジェクトとそのフォークでは、以下のタグのうち一つだけをジョブに追加してください:
-
gitlab-org
:ジョブは特権ランナーと非特権ランナーをランダムに使用します。 -
gitlab-org-docker
:ジョブは特権ランナーを使用する必要があります。Docker-in-Dockerのサポートが必要な場合は、gitlab-org-docker
gitlab-org
の代わりにgitlab-org-docker
使用してgitlab-org-docker
ください。
gitlab-org-docker
タグは、上記の.use-docker-in-docker
ジョブ定義によって追加されます。
フォークとの互換性を確保するために、gitlab-org
とgitlab-org-docker
の両方を同時に使用することは避けてください。gitlab-org
とgitlab-org-docker
の両方のタグを持つインスタンスランナーはいません。gitlab-org
プロジェクトのフォークの場合、マッチする Runner がないため、両方のタグが指定されると、ジョブはスタックします。
詳しくはGitLab Repositories handbook ページをご覧ください。