Skip to content
Latchkey

CIにおける依存関係キャッシュとは?

依存関係キャッシュは、buildがダウンロードするパッケージを保存し、次の実行でregistryからすべてを再取得する代わりに再利用できるようにします。

ほとんどのCIジョブは依存関係のインストールから始まります - npmパッケージ、Pythonのwheel、Mavenのjarなどです。これを毎回ゼロから行うのは遅く無駄です。依存関係はコミット間でめったに変わらないからです。依存関係キャッシュは、1回の実行後にそれらを保存し、次の実行の開始時に復元します。

解決する問題

新しいCI runnerはパッケージディレクトリが空です。キャッシュがないと、各ジョブは同じ依存関係を再ダウンロード(そして多くの場合は再コンパイル)し、各実行に数分とregistryへの負荷が加わります。忙しいリポジトリでは、このコストが1日に数百回繰り返されます。

仕組み

  • インストール後、パッケージディレクトリ(例えば~/.npmnode_modules)がkeyの下でキャッシュストレージにアップロードされます。
  • 次の実行では、ジョブがそのkeyを検索し、インストール前にディレクトリを復元します。
  • keyが一致すれば、インストールはほぼ瞬時の"already satisfied"パスになります。

cache keyがすべて

良いkeyはlockfileのハッシュから導出されるため、依存関係が変わったときだけ変化します。例: node-${{ hashFiles('package-lock.json') }}。keyが広すぎると古いパッケージを提供し、狭すぎると決してヒットしません。

小さな例

GitHub Actionsでは、key: npm-${{ hashFiles('package-lock.json') }}npm-のrestore-keyで~/.npmをキャッシュできます。lockfileが変わらなければ正確なkeyがヒットし、変わった場合はフォールバックが最も近い過去のキャッシュを復元するので、差分だけがダウンロードされます。

何をキャッシュすべきか(そして何をしないか)

パッケージストアやインストール済みモジュールをキャッシュし、ソースやbuildの出力(これらは独自のキャッシュを持ちます)はキャッシュしないでください。secretやマシン固有のものはキャッシュを避け、インストール手順が安価でもダウンロードが遅い場合は、インストール済みバイナリよりダウンロードキャッシュを優先しましょう。

Latchkeyについてのメモ

Latchkeyのマネージドrunnerでは、依存関係キャッシュは公開インターネットではなく同一リージョンの高速なローカルパス経由で復元されるため、大きなパッケージツリーでもキャッシュヒットが数秒で完了します。

重要なポイント

  • 依存関係キャッシュは、CI実行間でダウンロード済みパッケージを再利用します。
  • cache keyは正しく無効化されるよう、lockfileから導出すべきです。
  • パッケージストアをキャッシュし、secretsやソースは決してキャッシュしないこと。

関連ガイド