ワークフローの依存関係のキャッシングについて
ワークフローの実行は、しばしば他の実行と同じ出力あるいはダウンロードされた依存関係を再利用します。 たとえばMaven、Gradle、npm、Yarnといったパッケージ及び依存関係管理ツールは、ダウンロードされた依存関係のローカルキャッシュを保持します。
GitHubホストランナー上のジョブは、クリーンな仮想環境で開始され、依存関係を毎回ダウンロードしなければならず、ネットワークの利用率を増大させ、実行時間が長くなり、コストが高まってしまいます。 これらのファイルの再生成にかかる時間を短縮しやすくするために、GitHubはワークフロー内で頻繁に使われる依存関係をキャッシュできます。
ジョブのために依存関係をキャッシュするには、GitHubのcacheアクションを使わなければなりません。 このアクションは、ユニークなキーで指定されるキャッシュを取得します。 詳しい情報については「actions/cache」を参照してください。 Ruby gem をキャッシュする場合は、代わりに、開始時にバンドルインストールをキャッシュ可能な Ruby で維持されているアクションを使用することを検討してください。 詳しい情報については、ruby/setup-ruby を参照してください。
警告: パブリックリポジトリのキャッシュには、センシティブな情報を保存しないことをおすすめします。 たとえばキャッシュパス内のファイルに保存されたアクセストークンあるいはログインクレデンシャルなどがセンシティブな情報です。 また、docker loginのようなコマンドラインインターフェース(CLI)プログラムは、アクセスクレデンシャルを設定ファイルに保存することがあります。 読み取りアクセスを持つ人は誰でも、リポジトリにプルリクエストを作成し、キャッシュの内容にアクセスできます。 リポジトリのフォークも、ベースブランチ上にプルリクエストを作成し、ベースブランチ上のキャッシュにアクセスできます。
成果物の比較と依存関係のキャッシング
成果物とキャッシングは、GitHubにファイルを保存できるようにするので似ていますが、それぞれの機能のユースケースは異なっており、入れ替えて使うことはできません。
- キャッシングは、ジョブやワークフローの実行間で頻繁に変化しないファイルを再利用したいときに使ってください。
- ジョブによって生成されたファイルをワークフローの終了後に見るために保存したい場合に成果物を使ってください。 詳しい情報については「成果物を利用してワークフローのデータを永続化する」を参照してください。
キャッシュへのアクセスについての制限
cache アクションの v2 を使用すると、GITHUB_REF を含むイベントによってトリガーされるワークフローのキャッシュにアクセスできます。 cache アクションの v1 を使用している場合、pull_request の closed イベントを除いて、push イベントと pull_request イベントによってトリガーされるワークフローでのみキャッシュにアクセスできます。 詳しい情報については、「ワークフローをトリガーするイベント」を参照してください。
ワークフローは、現在のブランチ、ベースブランチ(フォークされたリポジトリのベースブランチを含む)、またはデフォルトブランチ(通常は main)で作成されたキャッシュにアクセスして復元できます。 たとえば、デフォルトブランチで作成されたキャッシュは、どのPull Requestからもアクセスできます。 また、feature-b ブランチに feature-a ベースブランチがある場合、feature-b でトリガーされたワークフローは、デフォルトのブランチ(main)、feature-a、および feature-b で作成されたキャッシュにアクセスできます。
アクセス制限は、様々なワークフローとブランチ間の論理的な境界を作成することによって、キャッシュの分離とセキュリティを提供します。 たとえば、feature-a ブランチ(ベース main を使用)向けに作成されたキャッシュは、feature-b ブランチ(ベース main を使用)のPull Requestにアクセスできません。
cacheアクションの利用
cacheアクションは、提供されたkeyに基づいてキャッシュをリストアしようとします。 このアクションは、キャッシュを見つけるとそのキャッシュされたファイルを設定されたpathにリストアします。
正確なマッチがなければ、ジョブが成功したならこのアクションは新しいキャッシュエントリを作成します。 新しいキャッシュは提供されたkeyを使い、pathディレクトリ内にファイルを保存します。
既存のキャッシュにkeyがマッチしなかった場合に使われる、restore-keysのリストを提供することもできます。 restore-keysのリストは、 restore-keysがキャッシュキーと部分的にマッチできるので、他のブランチからのキャッシュをリストアする場合に役立ちます。 restore-keysのマッチに関する詳しい情報については「キャッシュキーのマッチ」を参照してください。
詳しい情報については「actions/cache」を参照してください。
cache アクションの入力パラメータ
key: 必須 このキーはキャッシュの保存時に作成され、キャッシュの検索に使われます。 変数、コンテキスト値、静的な文字列、関数の任意の組み合わせが使えます。 キーの長さは最大で512文字であり、キーが最大長よりも長いとアクションは失敗します。path: 必須 ランナーがキャッシュあるいはリストアをするファイルパス。 このパスは、絶対パスでも、ワーキングディレクトリからの相対パスでもかまいません。cacheアクションのv2では、単一のパスまたは複数のパスをリストとして指定できます。 パスはディレクトリまたは単一ファイルのいずれかで、glob パターンがサポートされています。cacheアクションのv1では、単一のパスのみがサポートされ、かつそれがディレクトリである必要があります。 単一のファイルをキャッシュすることはできません。
restore-keys: オプションkeyに対するキャッシュヒットがなかった場合にキャッシュを見つけるために使われる代理キーの順序付きリスト。
cacheアクションの出力パラメータ
cache-hit: キーの完全一致が見つかったことを示すブール値。
cache アクションの使用例
以下の例では、package-lock.jsonファイル内のパッケージが変更された場合、あるいはランナーのオペレーティングシステムが変更された場合に新しいキャッシュが作成されます。 キャッシュキーはコンテキストと式を使い、ランナーのオペレーティングシステムとpackage-lock.jsonファイルのSHA-256ハッシュを含むキーを生成します。
name: Caching with npm
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
# npm キャッシュファイルは Linux/macOS の「~/.npm」に保存される
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install Dependencies
run: npm install
- name: Build
run: npm build
- name: Test
run: npm test
keyが既存のキャッシュにマッチした場合はキャッシュヒットと呼ばれ、このアクションはキャッシュされたファイルをpathディレクトリにリストアします。
keyが既存のキャッシュにマッチしなかった場合はキャッシュミスと呼ばれ、ジョブが成功して完了したなら新しいキャッシュが作成されます。 キャッシュミスが生じた場合、このアクションはrestore-keysと呼ばれる代理キーを検索します。
restore-keysが渡された場合、cacheアクションはrestore-keysのリストにマッチするキャッシュを順番に検索します。- 完全なマッチがあった場合、アクションはそのファイルを
pathディレクトリ中のキャッシュにリストアします。 - 完全なマッチがなかった場合、アクションはリストアキーに対する部分一致を検索します。 アクションが部分一致を見つけた場合、最も最近のキャッシュが
pathディレクトリにリストアされます。
- 完全なマッチがあった場合、アクションはそのファイルを
cacheアクションが完了し、ジョブ内の次のワークフローステップが実行されます。- ジョブが成功して完了したなら、アクションは
pathディレクトリの内容で新しいキャッシュを作成します。
複数のディレクトリにファイルをキャッシュするには、各ディレクトリごとにcache アクションを使うステップが必要です。 キャッシュをいったん作成すると、既存のキャッシュの内容を変更することはできませんが、新しいキーで新しいキャッシュを作成することはできます。
コンテキストを使ったキャッシュキーの作成
キャッシュキーには、コンテキスト、関数、リテラル、GitHub Actionsがサポートする演算子を含めることができます。 詳しい情報については、「GitHub Actions のコンテキストと式構文」を参照してください。
式を使ってkeyを作成すれば、依存関係が変化したときに自動的に新しいキャッシュを作成できます。 たとえばnpmのpackage-lock.jsonファイルのハッシュを計算する式を使ってkeyを作成できます。
npm-${{ hashFiles('package-lock.json') }}
GitHubはhash "package-lock.json"という式を評価して、最終的なkeyを導出します。
npm-d5ea0750
キャッシュキーのマッチング
cache アクションは最初に、ワークフロー実行を含むブランチで key および restore-keys のキャッシュヒットを検索します。 現在のブランチにヒットがない場合、cache アクションは、親ブランチと上流のブランチで key および restore-keys を検索します。
keyでキャッシュミスがあった場合に使うリストアキーのリストを提供できます。 特定の度合いが強いものから弱いものへ並べて複数のリストアキーを作成できます。 cacheアクションは順番にrestore-keysを検索していきます。 キーが直接マッチしなかった場合、アクションはリストアキーでプレフィックスされたキーを検索します。 リストアキーに対して複数の部分一致があった場合、アクションは最も最近に作成されたキャッシュを返します。
複数のリストアキーの利用例
restore-keys: |
npm-foobar-${{ hashFiles('package-lock.json') }}
npm-foobar-
npm-
ランナーは式を評価します。この式は以下のようなrestore-keysになります。
restore-keys: |
npm-foobar-d5ea0750
npm-foobar-
npm-
リストアキーのnpm-foobar-は、npm-foobar-という文字列で始まる任意のキーにマッチします。 たとえばnpm-foobar-fd3052deやnpm-foobar-a9b253ffというキーはいずれもこのリストアキーにマッチします。 最も最近の期日に作成されたキャッシュが使われます。 この例でのキーは、以下の順序で検索されます。
npm-foobar-d5ea0750は特定のハッシュにマッチします。npm-foobar-はnpm-foobar-をプレフィックスとするキャッシュキーにマッチします。npm-はnpm-をプレフィックスとする任意のキーにマッチします。
検索の優先度の例
key:
npm-feature-d5ea0750
restore-keys: |
npm-feature-
npm-
たとえば、プルリクエストに feature ブランチ(現在のスコープ)が含まれ、デフォルトブランチ(main)をターゲットにしている場合、アクションは次の順序で key と restore-keys を検索します。
featureブランチのスコープ内でnpm-feature-d5ea0750というキーfeatureブランチのスコープ内でnpm-feature-というキーfeatureブランチのスコープ内でnpm-というキーmainブランチのスコープ内でnpm-feature-d5ea0750というキーmainブランチのスコープ内でnpm-feature-というキーmainブランチのスコープ内でnpm-というキー
利用制限と退去のポリシー
GitHubは、7日間以上アクセスされていないキャッシュエントリを削除します。 保存できるキャッシュ数には上限がありませんが、1つのリポジトリ内のすべてのキャッシュの合計サイズは5GBに制限されます。 この制限を超えた場合、GitHubはキャッシュを保存しますが、合計サイズが5GB以下になるまでキャッシュを退去させはじめます。

