できない.dev

GitHub Actions のキャッシュが復元されない

`actions/cache` の key 不一致、ブランチ間の参照ルール、10 GB のリポジトリ上限超過、7 日間未参照での自動削除が主因。
job ログの Cache miss 行で実際に検索された key を確認するのが起点。

#github-actions#cache#ci#workflow

公開:

要約

GitHub Actions の cache が復元されない原因は、key 不一致ブランチ間参照ルール10 GB 上限超過7 日間未参照での evict の 4 系統に集約される。
Actions ログの Cache miss 行に表示される実際の検索 key と、Settings → Actions → Caches のリポジトリ cache 一覧を突き合わせて切り分ける。

よくある原因

  1. key 不一致: key${{ github.sha }} のように毎回変わる値を入れていると毎回 miss する。hashFiles のような決定的な式に変える必要がある。
  2. restore-keys 未設定: 完全一致しなくても部分一致で復元したいなら restore-keys の prefix リストが必須。
    これが無いと miss し空状態でジョブが始まる。
  3. ブランチ参照ルール: PR の topic ブランチから参照できる cache は、自身のブランチで保存されたものと base / default ブランチで保存されたものに限られる。
    別 PR の cache は読めない仕様。
  4. 10 GB 上限: 1 リポジトリの cache 合計は 10 GB。
    超えると古い cache から自動削除される。node_modules を丸ごと cache していると簡単に到達する。
  5. 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 を回避できる。

この記事は役立ちましたか?