CI設定のパフォーマンス
中断可能なパイプライン
デフォルトでは、すべてのジョブは割り込み可能です。ただし、dont-interrupt-me
ジョブはmain
で自動的に実行され、それ以外はmanual
となります。
マージリクエストに新しいコミットをプッシュしても実行中のパイプラインを終了させたい場合は、プッシュする前に必ずdont-interrupt-me
ジョブを開始してください。
Git フェッチキャッシュ
GitLab.comはpack-objectsキャッシュを使用しているため、同じパイプラインの同時GitフェッチはGitalyサーバー上で(常に)重複排除され、(利用可能な場合は)キャッシュから提供されます。
これは以下の理由でうまく機能します:
- pack-objectsキャッシュはGitLab.comのすべてのGitalyサーバーで有効になっています。
-
gitlab-org/gitlab
の CI/CDGit 戦略設定は Git cloneで、すべてのジョブが同じデータを取得するようにし、キャッシュのヒット率を最大にしています。 - ジョブごとに Git の全履歴をダウンロードするのを避けるために、shallow cloneを使っています。
キャッシュ戦略
- デフォルトでは、すべてのジョブはキャッシュをプルするだけです。
- すべてのジョブは空のキャッシュでパスできなければなりません。言い換えれば、キャッシュはジョブを高速化するためだけに存在します。
- 現在、
.gitlab/ci/global.gitlab-ci.yml
で、固定キーで定義されたいくつかの異なるキャッシュ定義があります:.setup-test-env-cache
.ruby-cache
.static-analysis-cache
.rubocop-cache
.ruby-gems-coverage-cache
.ruby-node-cache
.qa-cache
.yarn-cache
-
.assets-compile-cache
(キーは${NODE_ENV}
を含むので、実際には2つの異なるキャッシュです)。
- これらのキャッシュ定義は複数のアトミック・キャッシュで Composer されています。
- 2時間ごとに
maintenance
スケジュールされたパイプラインで実行される以下のジョブのみがキャッシュにプッシュ(つまり更新)されます:-
update-setup-test-env-cache
.gitlab/ci/rails.gitlab-ci.yml
で定義されています。 -
update-gitaly-binaries-cache
.gitlab/ci/rails.gitlab-ci.yml
で定義されています。 -
update-rubocop-cache
.gitlab/ci/rails.gitlab-ci.yml
で定義されています。 -
update-qa-cache
.gitlab/ci/qa.gitlab-ci.yml
で定義されています。 -
update-assets-compile-production-cache
.gitlab/ci/frontend.gitlab-ci.yml
で定義されています。 -
update-assets-compile-test-cache
.gitlab/ci/frontend.gitlab-ci.yml
で定義されています。 -
update-storybook-yarn-cache
.gitlab/ci/frontend.gitlab-ci.yml
で定義されています。
-
- これらのジョブは、
pipeline:update-cache
ラベルを持つマージリクエストで実行させることもできます (これはキャッシュキーを更新する MR でキャッシュをウォームアップするのに便利です)。
アーティファクト戦略
アップロード/ダウンロードの時間とコストを削減し、アーティファクトのストレージを削減するために、ジョブによって保存および取得されるアーティファクトを最小限に制限します。
コンポーネントのキャッシュ
GitLabのいくつかの外部コンポーネント(GitLab Workhorseやフロントエンドのアセット)は、テストを実行するための前段階としてソースからビルドする必要があります。
cache-workhorse
今回のMR、そして今回のMRでは、cache-workhorse
という新しいジョブを紹介しました:
- すべての GitLab.com
gitlab-org/gitlab
スケジュールパイプラインに対して自動的に実行されます。 -
workhorse/
フォルダに触れたmaster
のコミットに対して自動的に実行されます。 - は、GitLab.com の
gitlab-org
のキャッシング関連ファイルに触れる MR に対して手動で実行されます。
このジョブは、GitLab テストスイート(tmp/tests/gitlab-workhorse
以下)で必要な GitLab Workhorse バイナリを含む汎用パッケージをダウンロードしようとします。
- パッケージの URL が 404 を返した場合
-
scripts/setup-test-env
を実行し、GitLab Workhorse のバイナリがビルドされます。 - その後、バイナリを含むアーカイブを作成し、汎用パッケージとしてアップロードします。
-
- そうでなければ、パッケージがすでに存在する場合、ジョブを正常に終了します。
また、setup-test-env
のジョブを変更しました:
- 最初にGitLab Workhorse汎用パッケージをダウンロードし、
cache-workhorse
。 - パッケージの取得に成功すると、その内容が適切なフォルダ(例えば、
tmp/tests/gitlab-workhorse
)に配置され、scripts/setup-test-env
を後で実行したときにバイナリがビルドされるのを防ぎます。 - パッケージの URL が 404 を返した場合、動作は現在のものと変わりません: GitLab Workhorse のバイナリは
scripts/setup-test-env
の一部としてビルドされます。
git rev-parse HEAD:workhorse
)。
cache-assets
このMRでは、cache-assets:test
、cache-assets:test as-if-foss
、cache-assets:production
の3つの新しいジョブを紹介しました:
- 以下のジョブを導入しました。
$CACHE_ASSETS_AS_PACKAGE == "true"
- すべての GitLab.com
gitlab-org/gitlab
スケジュールパイプラインに対して自動的に実行されます。 - アセット関連フォルダに触れた
master
のコミットに対して自動的に実行されます。 - は、GitLab.com の
gitlab-org
のキャッシング関連ファイルに触れる MR に対して手動で実行されます。
このジョブは、GitLab テストスイートで必要となる GitLab コンパイル済みアセットを含む汎用パッケージをダウンロードしようとします (app/assets/javascripts/locale/**/app.js
とpublic/assets
のもとで)。
- パッケージの URL が 404 を返した場合
-
bin/rake gitlab:assets:compile
を実行し、GitLabアセットがコンパイルされるようにします。 - その後、アセットを含むアーカイブを作成し、汎用パッケージとしてアップロードします。パッケージのバージョンはassetsフォルダのハッシュ合計に設定されます。
-
- そうでなければ、パッケージがすでに存在する場合、ジョブを正常に終了します。
compile-*-assets
また、compile-test-assets
、compile-test-assets as-if-foss
、compile-production-assets
のジョブを変更しました:
- まず “ネイティブ “キャッシュアセットをダウンロードします:
- コンパイルされたアセット。
-
cached-assets-hash.txt
ファイル アセットが依存するすべてのソースファイルのSHA256
16進ダイジェストを含みます。このファイルのリストは悲観的なリストで、アセットはこれらのファイルのいくつかに依存しないかもしれません。最悪の場合、アセットをより頻繁にコンパイルすることになります。このファイルはアセットがコンパイルされた後に作成されます。
- 次に、アセットが依存するすべてのソースファイルの
SHA256
16進ダイジェストを、現在のチェックアウトされたブランチについて計算します。このヘックスダイジェストをGITLAB_ASSETS_HASH
変数に格納します。 -
$CACHE_ASSETS_AS_PACKAGE == "true"
の場合、cache-assets:*
によってビルドされアップロードされた汎用パッケージをダウンロードします。- チェックアウトしたブランチのキャッシュが最新であれば、ネイティブキャッシュとキャッシュパッケージをダウンロードします。遺伝的パッケージをダウンロードしないことで最適化することもできますが、ネイティブキャッシュは2時間ごとにしか再構築されないため、実際には非常に頻繁に古くなります。
-
私たちは
assets_compile_script
関数を実行します。この関数は内部でassets:compile
Rake タスク を実行します。このタスクは、アセットをコンパイルする必要があるかどうかを決定します。
$GITLAB_ASSETS_HASH
からのHEAD
SHA256
hexdigest とcached-assets-hash.txt
からのmaster
hexdigest を比較します。 - ハッシュが同じなら、何もコンパイルしません。異なる場合は、アセットをコンパイルします。