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を使っています。

キャッシュ戦略

  1. デフォルトでは、すべてのジョブはキャッシュをプルするだけです。
  2. すべてのジョブは空のキャッシュでパスできなければなりません。言い換えれば、キャッシュはジョブを高速化するためだけに存在します。
  3. 現在、.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つの異なるキャッシュです)。
  4. これらのキャッシュ定義は複数のアトミック・キャッシュで Composer されています。
  5. 2時間ごとにmaintenance スケジュールされたパイプラインで実行される以下のジョブのみがキャッシュにプッシュ(つまり更新)されます:
  6. これらのジョブは、pipeline:update-cache ラベルを持つマージリクエストで実行させることもできます (これはキャッシュキーを更新する MR でキャッシュをウォームアップするのに便利です)。

アーティファクト戦略

アップロード/ダウンロードの時間とコストを削減し、アーティファクトのストレージを削減するために、ジョブによって保存および取得されるアーティファクトを最小限に制限します。

コンポーネントのキャッシュ

GitLabのいくつかの外部コンポーネント(GitLab Workhorseやフロントエンドのアセット)は、テストを実行するための前段階としてソースからビルドする必要があります。

cache-workhorse

今回のMR、そして今回のMRではcache-workhorse という新しいジョブを紹介しました:

  • すべての GitLab.comgitlab-org/gitlab スケジュールパイプラインに対して自動的に実行されます。
  • workhorse/ フォルダに触れたmaster のコミットに対して自動的に実行されます。
  • は、GitLab.com のgitlab-org のキャッシング関連ファイルに触れる MR に対して手動で実行されます。

このジョブは、GitLab テストスイート(tmp/tests/gitlab-workhorse 以下)で必要な GitLab Workhorse バイナリを含む汎用パッケージをダウンロードしようとします。

  • パッケージの URL が 404 を返した場合
    1. scripts/setup-test-env を実行し、GitLab Workhorse のバイナリがビルドされます。
    2. その後、バイナリを含むアーカイブを作成し、汎用パッケージとしてアップロードします。
  • そうでなければ、パッケージがすでに存在する場合、ジョブを正常に終了します。

また、setup-test-env のジョブを変更しました:

  1. 最初にGitLab Workhorse汎用パッケージをダウンロードし、cache-workhorse
  2. パッケージの取得に成功すると、その内容が適切なフォルダ(例えば、tmp/tests/gitlab-workhorse )に配置され、scripts/setup-test-env を後で実行したときにバイナリがビルドされるのを防ぎます。
  3. パッケージの URL が 404 を返した場合、動作は現在のものと変わりません: GitLab Workhorse のバイナリはscripts/setup-test-envの一部としてビルドされます。
note
パッケージのバージョンは Workhorse ツリーの SHA です(例えば、git rev-parse HEAD:workhorse )。

cache-assets

このMRではcache-assets:testcache-assets:test as-if-fosscache-assets:production の3つの新しいジョブを紹介しました:

  • 以下のジョブを導入しました。$CACHE_ASSETS_AS_PACKAGE == "true"
  • すべての GitLab.comgitlab-org/gitlab スケジュールパイプラインに対して自動的に実行されます。
  • アセット関連フォルダに触れたmaster のコミットに対して自動的に実行されます。
  • は、GitLab.com のgitlab-org のキャッシング関連ファイルに触れる MR に対して手動で実行されます。

このジョブは、GitLab テストスイートで必要となる GitLab コンパイル済みアセットを含む汎用パッケージをダウンロードしようとします (app/assets/javascripts/locale/**/app.jspublic/assets のもとで)。

  • パッケージの URL が 404 を返した場合
    1. bin/rake gitlab:assets:compileを実行し、GitLabアセットがコンパイルされるようにします。
    2. その後、アセットを含むアーカイブを作成し、汎用パッケージとしてアップロードします。パッケージのバージョンはassetsフォルダのハッシュ合計に設定されます。
  • そうでなければ、パッケージがすでに存在する場合、ジョブを正常に終了します。

compile-*-assets

また、compile-test-assetscompile-test-assets as-if-fosscompile-production-assets のジョブを変更しました:

  1. まず “ネイティブ “キャッシュアセットをダウンロードします:
  2. 次に、アセットが依存するすべてのソースファイルのSHA256 16進ダイジェストを、現在のチェックアウトされたブランチについて計算します。このヘックスダイジェストをGITLAB_ASSETS_HASH 変数に格納します。
  3. $CACHE_ASSETS_AS_PACKAGE == "true"の場合、cache-assets:*によってビルドされアップロードされた汎用パッケージをダウンロードします。
    • チェックアウトしたブランチのキャッシュが最新であれば、ネイティブキャッシュとキャッシュパッケージをダウンロードします。遺伝的パッケージをダウンロードしないことで最適化することもできますが、ネイティブキャッシュは2時間ごとにしか再構築されないため、実際には非常に頻繁に古くなります。
  4. 私たちはassets_compile_script 関数を実行します。この関数は内部で assets:compile Rake タスク実行します。

    このタスクは、アセットをコンパイルする必要があるかどうかを決定します。$GITLAB_ASSETS_HASH からのHEAD SHA256 hexdigest とcached-assets-hash.txt からのmaster hexdigest を比較します。

  5. ハッシュが同じなら、何もコンパイルしません。異なる場合は、アセットをコンパイルします。