ワークフローの依存関係のキャッシングについて
ワークフローの実行は、しばしば他の実行と同じ出力あるいはダウンロードされた依存関係を再利用します。 たとえばMaven、Gradle、npm、Yarnといったパッケージ及び依存関係管理ツールは、ダウンロードされた依存関係のローカルキャッシュを保持します。
GitHub ホステッド ランナー上のジョブは、クリーンなランナー イメージで開始されますが、依存関係を毎回ダウンロードする必要があるため、ネットワークの利用率が増大し、実行時間が長くなり、コストが高くなります。 依存関係などのファイルの再生成にかかる時間を短縮しやすくするために、GitHub ではワークフロー内で頻繁に使われるファイルをキャッシュできます。
ジョブの依存関係をキャッシュするには、GitHub の cache
アクションを使用できます。 このアクションは、一意のキーによって識別されるキャッシュを作成し、復元します。 なお、以下に示すパッケージ マネージャーをキャッシュする場合、それぞれの setup-* アクションを使用するには、最小構成が必要となります。これにより、依存関係キャッシュが作成され、復元されます。
パッケージ マネージャー | キャッシュの setup-* アクション |
---|---|
npm、Yarn、pnpm | setup-node |
pip、pipenv、Poetry | setup-python |
Gradle、Maven | setup-java |
RubyGems | setup-ruby |
Go go.sum | setup-go |
.NET NuGet | setup-dotnet |
Warning
GitHub Actions でキャッシュを使用する場合は、次の点に注意してください。
- キャッシュには、機密情報を保存しないことをお勧めします。 たとえばキャッシュパス内のファイルに保存されたアクセストークンあるいはログインクレデンシャルなどがセンシティブな情報です。 また、
docker login
のようなコマンド ライン インターフェイス (CLI) プログラムでは、アクセス資格情報を構成ファイルに保存できます。 読み取りアクセスを持つ人は誰でも、リポジトリに pull request を作成し、キャッシュの内容にアクセスできます。 リポジトリのフォークも、ベースブランチ上にPull Requestを作成し、ベースブランチ上のキャッシュにアクセスできます。 - セルフホステッド ランナーを使用する場合、ワークフロー実行のキャッシュは、GitHub 所有のクラウド ストレージに保存されます。 顧客所有のストレージ ソリューションは、GitHub Enterprise Server でのみ使用できます。
成果物の比較と依存関係のキャッシング
成果物とキャッシングは、GitHubにファイルを保存できるようにするので似ていますが、それぞれの機能のユースケースは異なっており、入れ替えて使うことはできません。
- パッケージ管理システムからのビルドの依存関係など、ジョブまたはワークフローの実行の間で頻繁に変更されないファイルを再利用する場合は、キャッシュを使用します。
- ビルドされたバイナリやビルド ログなど、ワークフローの実行が終了した後に表示するためにジョブによって生成されたファイルを保存する場合は、成果物を使用します。
ワークフロー実行の成果物について詳しくは、「ワークフローからのデータの格納と共有」をご覧ください。
キャッシュへのアクセスについての制限
アクセス制限を使用すると、さまざまなブランチまたはタグ間に論理境界を作成することで、キャッシュを分離しセキュリティで保護することができます。
ワークフロー実行では、現在のブランチまたは既定のブランチ (通常は main
) で作成されたキャッシュを復元できます。 pull request に対してワークフロー実行がトリガーされた場合は、ベース ブランチで作成されたキャッシュを復元することもできます (フォークされたリポジトリのベース ブランチも含む)。 たとえば、ブランチ feature-b
にベース ブランチ feature-a
がある場合、pull request でトリガーされたワークフロー実行では、既定のブランチ main
、ベース ブランチ feature-a
、および現在のブランチ feature-b
で作成されたキャッシュにアクセスできます。
ワークフロー実行では、子ブランチまたは兄弟ブランチ用に作成されたキャッシュを復元することはできません。 たとえば、子ブランチ feature-b
用に作成されたキャッシュに、親ブランチ main
でトリガーされたワークフロー実行からアクセスすることはできません。 同様に、ベース main
を持つブランチ feature-a
用に作成されたキャッシュに、ベース main
を持つその兄弟ブランチ feature-c
からアクセスすることはできません。 また、ワークフロー実行では、異なるタグ名に対して作成されたキャッシュを復元することもできません。 たとえば、タグ release-a
に対してベース main
で作成されたキャッシュに、タグ release-b
に対してベース main
でトリガーされたワークフロー実行からアクセスすることはできません。
pull request でトリガーされたワークフロー実行によってキャッシュが作成される場合、そのキャッシュは merge ref (refs/pull/.../merge
) に対して作成されます。 このため、このキャッシュのスコープは制限され、pull request の再実行によってのみ復元できます。 ベース ブランチ、またはそのベース ブランチを対象とする他の pull request では、復元できません。
リポジトリ内の複数のワークフロー実行で、キャッシュを共有できます。 あるワークフロー実行でブランチ用に作成されたキャッシュは、同じリポジトリとブランチの別のワークフロー実行からアクセスおよび復元できます。
cache
アクションの使用
cache
action アクションは、指定した key
に基づいてキャッシュの復元を試みます。 アクションがそのキーと "厳密に" 一致するキャッシュを見つけた場合、構成した path
にキャッシュされたファイルが復元されます。
必要に応じて、key
が既存のキャッシュと一致しない場合に使用する restore-keys
のリストを指定できます。 restore-keys
のリストは、別のブランチからキャッシュを復元する場合に便利です。restore-keys
はキャッシュ キーと "部分的に" 一致する可能性があるためです。 restore-keys
の照合の詳細については、「キャッシュ キーのマッチング」を参照してください。
指定した key
との完全な一致があった場合は、キャッシュ ヒットと見なされます。 指定した key
と完全に一致するキャッシュがなかった場合は、キャッシュ ミスと見なされます。 キャッシュ ミスの場合は、ジョブが正常に完了すると、このアクションによって新しいキャッシュが自動的に作成されます。 新しいキャッシュでは、指定した key
が使用され、path
で指定したファイルが含められます。 この処理方法について詳しくは、「キャッシュ ヒットとキャッシュ ミス」を参照してください。
既存のキャッシュの内容を変更することはできません。 代わりに、新しいキーを使って新しいキャッシュを作成できます。
cache
アクションの入力パラメーター
-
key
: 必須 キャッシュの保存時に作成されたキーと、キャッシュの検索に使用されるキー。 変数、コンテキスト値、静的な文字列、関数の任意の組み合わせが使えます。 キーの長さは最大で512文字であり、キーが最大長よりも長いとアクションは失敗します。 -
path
: 必須 キャッシュまたは復元するランナー上のパス。-
1 つのパスを指定することも、複数のパスを別々の行に追加することもできます。 たとえば次のような点です。
- name: Cache Gradle packages uses: actions/cache@v3 with: path: | ~/.gradle/caches ~/.gradle/wrapper
-
ディレクトリまたは単一ファイルのいずれかを指定できます。glob パターンがサポートされています。
-
絶対パス、またはワークスペース ディレクトリに対する相対パスを指定できます。
-
-
restore-keys
: オプション 代替の復元キーを含んだ文字列。各復元キーは新しい行に配置されます。key
に対するキャッシュ ヒットが発生しない場合は、キャッシュを検索して復元するために、これらの復元キーが指定された順序で使用されます。 たとえば次のような点です。restore-keys: | npm-feature-${{ hashFiles('package-lock.json') }} npm-feature- npm-
-
enableCrossOsArchive
: 省略可能 ブール値。有効の場合、キャッシュが作成されたオペレーティング システムに関係なく、Windows ランナーがキャッシュを保存または復元できます。 このパラメーターが設定されていない場合、既定値はfalse
になります。 詳しくは、Actions Cache に関するドキュメントの「Cross OS cache (クロス OS キャッシュ)」を参照してください。
cache
アクションの出力パラメーター
cache-hit
: キーに対して完全一致が見つかったかどうかを示すブール値。
キャッシュ ヒットとキャッシュ ミス
key
が既存のキャッシュと厳密に一致した場合、それは "キャッシュ ヒット" と呼ばれ、アクションによってキャッシュされたファイルが path
ディレクトリに復元されます。
key
が既存のキャッシュと一致しない場合 (これは キャッシュ ミス と呼ばれます)、ジョブが正常に完了すると、新しいキャッシュが作成されます。
キャッシュ ミスが発生した場合、アクションはユーザーが指定した restore-keys
の一致も検索します。
restore-keys
を指定した場合、cache
アクションはrestore-keys
のリストに一致するすべてのキャッシュを順次検索します。- 完全に一致する場合、アクションはキャッシュ内のファイルを
path
ディレクトリに復元します。 - 完全なマッチがなかった場合、アクションはリストアキーに対する部分一致を検索します。 アクションで部分的な一致が見つかると、最新のキャッシュが
path
ディレクトリに復元されます。
- 完全に一致する場合、アクションはキャッシュ内のファイルを
cache
アクションが完了し、ジョブの次のステップが実行されます。- ジョブが正常に完了すると、アクションは
path
ディレクトリのコンテンツを含んだ新しいキャッシュを自動的に作成します。
キャッシュ照合プロセスの詳細については、「キャッシュキーのマッチング」を参照してください。
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@v4 - name: Cache node modules id: cache-npm uses: actions/cache@v3 env: cache-name: cache-node-modules with: # npm cache files are stored in `~/.npm` on Linux/macOS 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 }}- - if: ${{ steps.cache-npm.outputs.cache-hit != 'true' }} name: List the state of node modules continue-on-error: true run: npm list - name: Install dependencies run: npm install - name: Build run: npm run build - name: Test run: npm test
name: Caching with npm
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Cache node modules
id: cache-npm
uses: actions/cache@v3
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
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 }}-
- if: ${{ steps.cache-npm.outputs.cache-hit != 'true' }}
name: List the state of node modules
continue-on-error: true
run: npm list
- name: Install dependencies
run: npm install
- name: Build
run: npm run build
- name: Test
run: npm test
コンテキストを使ったキャッシュキーの作成
キャッシュキーには、コンテキスト、関数、リテラル、GitHub Actionsがサポートする演算子を含めることができます。 詳細については、「ワークフロー実行に関するコンテキスト情報へのアクセス」および「ワークフローとアクションで式を評価する」を参照してください。
式を使用して key
を作成すると、依存関係が変更されたときに新しいキャッシュを自動的に作成できます。
たとえば、npm package-lock.json
ファイルのハッシュを計算する式を使用して key
を作成できます。 その場合、package-lock.json
ファイルを構成する依存関係が変更されると、キャッシュ キーが変更され、新しいキャッシュが自動的に作成されます。
npm-${{ hashFiles('package-lock.json') }}
GitHub は、式 hash "package-lock.json"
を評価して最終的な key
を導き出します。
npm-d5ea0750
cache
アクションの出力の使用
cache
アクションの出力を使用すると、キャッシュ ヒットやキャッシュ ミスが発生したどうかに基づいて操作を実行することができます。 指定した key
のキャッシュに完全一致が見つかった場合、cache-hit
の出力は true
に設定されます。
上記のワークフロー例では、キャッシュ ミスが発生した場合に、Node モジュールの状態をリストする手順があります。
- if: ${{ steps.cache-npm.outputs.cache-hit != 'true' }}
name: List the state of node modules
continue-on-error: true
run: npm list
キャッシュキーのマッチング
cache
アクションは、最初にワークフロー実行を含むブランチで、key
とキャッシュ "バージョン" のキャッシュ ヒットを検索します。 ヒットがない場合は、restore-keys
と "バージョン" を検索します。 それでも現在のブランチにヒットがない場合、cache
アクションは既定のブランチに対して同じ手順を再試行します。 検索中はスコープの制限が適用されることに注意してください。 詳しくは、「キャッシュへのアクセスについての制限」を参照してください。
キャッシュ バージョンは、キャッシュの作成時に使用された path
と圧縮ツールのメタデータを使って、キャッシュにスタンプを付ける方法です。 これにより、使用するワークフロー実行が、実際に圧縮を解除して使用できるキャッシュと一意に一致することが保証されます。 詳しくは、Actions Cache に関するドキュメントの「Cache Version (キャッシュ バージョン)」を参照してください。
restore-keys
では、key
でキャッシュ ミスが発生した場合に使用する代替復元キーのリストを指定できます。 特定の度合いが強いものから弱いものへ並べて複数のリストアキーを作成できます。 cache
アクションは restore-keys
を順番に検索します。 キーが直接マッチしなかった場合、アクションはリストアキーでプレフィックスされたキーを検索します。 リストアキーに対して複数の部分一致があった場合、アクションは最も最近に作成されたキャッシュを返します。
複数のリストアキーの利用例
restore-keys: |
npm-feature-${{ hashFiles('package-lock.json') }}
npm-feature-
npm-
ランナーは式を評価し、次の restore-keys
に解決します。
restore-keys: |
npm-feature-d5ea0750
npm-feature-
npm-
復元キー npm-feature-
は、文字列 npm-feature-
で始まるすべてのキーと一致します。 たとえば、npm-feature-fd3052de
および npm-feature-a9b253ff
の両方のキーと復元キーが一致します。 最も最近の期日に作成されたキャッシュが使われます。 この例でのキーは、以下の順序で検索されます。
npm-feature-d5ea0750
は特定のハッシュと一致します。npm-feature-
はnpm-feature-
というプレフィックスが付いたキャッシュ キーと一致します。npm-
はnpm-
というプレフィックスが付いたすべてのキーと一致します。
検索の優先度の例
key:
npm-feature-d5ea0750
restore-keys: |
npm-feature-
npm-
たとえば、pull request が 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日間以上アクセスされていないキャッシュエントリを削除します。 保存できるキャッシュの数に制限はありませんが、リポジトリ内のすべてのキャッシュの合計サイズは制限されています (最大 10 GB)。 リポジトリがその最大キャッシュ ストレージに達すると、キャッシュの削除ポリシーによって、リポジトリ内の最も古いキャッシュが削除されてスペースが作成されます。
この制限を超えると、GitHub は新しいキャッシュを保存しますが、合計サイズがリポジトリの制限を下回るまでキャッシュの削除を開始します。 キャッシュの削除プロセスが原因で、キャッシュのスラッシングが発生する場合があります。その場合は、キャッシュが高い頻度で作成および削除されます。 これを軽減するには、リポジトリのキャッシュを確認し、修正手順を実行できます (特定のワークフローからキャッシュを削除するなど)。 詳細については、「キャッシュの管理」を参照してください。
キャッシュの管理
ワークフローから作成されたキャッシュを管理する場合、次の操作を実行できます。
- リポジトリの全キャッシュ エントリの一覧を表示する。
- 特定のメタデータを使って、キャッシュの一覧のフィルター処理と並べ替えを行う (キャッシュ サイズ、作成日時、最終アクセス日時など)。
- リポジトリからキャッシュ エントリを削除する。
- リポジトリと組織の集計されたキャッシュ使用状況を監視する。
リポジトリのキャッシュを管理する方法は複数あります。
-
以下に示すように、GitHub Web インターフェイスを使う。
-
REST API を使う。 詳しくは、「GitHub Actions キャッシュの REST API エンドポイント」を参照してください。
-
コマンド・ラインからキャッシュを管理するための
gh cache
サブコマンドのインストール。 詳しくは、「GitHub CLI のドキュメント」をご覧ください。Note
これを手動で行う場合は、バージョン 2.32.0 以降の CLI がインストールされていることを確認してください。
キャッシュ エントリの表示
Web インターフェイスを使って、リポジトリのキャッシュ エントリの一覧を表示できます。 キャッシュの一覧では、各キャッシュで使用されているディスク領域の量、キャッシュが作成された日時、キャッシュが最後に使用された日時を確認できます。
-
GitHub で、リポジトリのメイン ページに移動します。
-
リポジトリ名の下にある [アクション] をクリックします。
-
左サイドバーの [管理] セクションで、 [キャッシュ] をクリックします。
-
リポジトリのキャッシュ エントリの一覧を確認します。
- 特定のブランチ用に使用されるキャッシュ エントリを検索するには、 [Branch] ドロップダウン メニューをクリックして、ブランチを選択します。 キャッシュの一覧に、選択したブランチ用に使用されるすべてのキャッシュが表示されます。
- 特定のキャッシュ キーを持つキャッシュ エントリを検索するには、 [Filter caches] フィールドで構文
key: key-name
を使用します。 キャッシュの一覧に、そのキーが使用されたすべてのブランチのキャッシュが表示されます。
キャッシュ エントリの削除
リポジトリへの write
アクセス権を持つユーザーは、GitHub Web インターフェイスを使ってキャッシュ エントリを削除できます。
-
GitHub で、リポジトリのメイン ページに移動します。
-
リポジトリ名の下にある [アクション] をクリックします。
-
左サイドバーの [管理] セクションで、 [キャッシュ] をクリックします。
-
削除するキャッシュ エントリの右側にある をクリックします。
キャッシュ エントリの強制削除
キャッシュにはブランチ スコープの制限が設定されています。つまり、一部のキャッシュは使用オプションが制限されます。 キャッシュ スコープの制限について詳しくは、この記事で前述した「キャッシュへのアクセスについての制限」をご覧ください。 特定のブランチに限定されたキャッシュで大量のストレージ クォータが使用されている場合は、default
ブランチからのキャッシュが頻繁に作成および削除される可能性があります。
たとえば、リポジトリでは新しい pull request が多数オープンされ、それぞれがそのブランチに制限された独自のキャッシュがある場合があります。 これらのキャッシュは、そのリポジトリのキャッシュ ストレージの大部分を占める可能性があります。 リポジトリがその最大キャッシュ ストレージに達すると、キャッシュの削除ポリシーによって、リポジトリ内の最も古いキャッシュが削除されてスペースが作成されます。 このような場合にキャッシュのスラッシングを防ぐため、キャッシュの削除ポリシーよりも速い周期でキャッシュを削除するようにワークフローを設定できます。 GitHub CLI を使って、特定のブランチのキャッシュを削除できます。
次のワークフローの例では、gh cache
を使用して、pull request が閉じられた後にブランチによって作成された最大 100 個のキャッシュを削除します。
リポジトリ間の pull request またはフォークからの pull request で次の例を実行するには、pull_request_target
イベントを使用してワークフローをトリガーできます。 ワークフローのトリガーに pull_request_target
を使用する場合は、セキュリティに関する考慮事項に留意する必要があります。 詳しくは、「ワークフローをトリガーするイベント」を参照してください。
name: cleanup caches by a branch
on:
pull_request:
types:
- closed
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- name: Cleanup
run: |
echo "Fetching list of cache key"
cacheKeysForPR=$(gh cache list --ref $BRANCH --limit 100 --json id --jq '.[].id')
## Setting this to not fail the workflow while deleting cache keys.
set +e
echo "Deleting caches..."
for cacheKey in $cacheKeysForPR
do
gh cache delete $cacheKey
done
echo "Done"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge
または、API を使用して、独自の周期ですべてのキャッシュを自動で一覧表示または削除することもできます。 詳しくは、「GitHub Actions キャッシュの REST API エンドポイント」を参照してください。