GitHub Actions のキャッシュが復元されない
`actions/cache` の key 不一致、ブランチ間の参照ルール、10 GB のリポジトリ上限超過、7 日間未参照での自動削除が主因。
job ログの Cache miss 行で実際に検索された key を確認するのが起点。
公開:
要約
GitHub Actions の cache が復元されない原因は、key 不一致、ブランチ間参照ルール、10 GB 上限超過、7 日間未参照での evict の 4 系統に集約される。
Actions ログの Cache miss 行に表示される実際の検索 key と、Settings → Actions → Caches のリポジトリ cache 一覧を突き合わせて切り分ける。
よくある原因
- key 不一致:
keyに${{ github.sha }}のように毎回変わる値を入れていると毎回 miss する。hashFilesのような決定的な式に変える必要がある。 restore-keys未設定: 完全一致しなくても部分一致で復元したいならrestore-keysの prefix リストが必須。
これが無いと miss し空状態でジョブが始まる。- ブランチ参照ルール: PR の topic ブランチから参照できる cache は、自身のブランチで保存されたものと base / default ブランチで保存されたものに限られる。
別 PR の cache は読めない仕様。 - 10 GB 上限: 1 リポジトリの cache 合計は 10 GB。
超えると古い cache から自動削除される。node_modulesを丸ごと cache していると簡単に到達する。 - 7 日間 evict: 7 日間アクセスの無い cache は自動削除される。
長期間動かないリポジトリで起きやすい。
解決策
1. key を決定的にする
- uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
npm-${{ runner.os }}-
npm-Caching dependencies to speed up workflows のとおり、hashFiles で lockfile のハッシュを取るのが定番。restore-keys の段階フォールバックで同 OS の任意 npm cache を拾える。
2. ブランチ間参照を理解する
PR ブランチでビルドした cache は、main ブランチへマージするまで他 PR からは見えない。
default ブランチで cache を温めておき、PR からは base 経由で参照する設計にすれば cache miss を減らせる。
3. cache を整理する
Settings → Actions → Caches で個別 key を削除できる。
あるいは GitHub CLI の gh actions-cache delete で一括整理する。node_modules を直接 cache せず、パッケージマネージャの global store(~/.npm / ~/.pnpm-store)だけを cache すれば容量を抑えられる。
4. evict を防ぐ
on:
schedule:
- cron: "0 3 * * *" # 毎日 03:00 UTC短時間のジョブで cache を毎日 restore + save するワークフローを回しておくと、7 日 evict を回避できる。