GitHub ActionsのCIでpnpm install
を実行するたびに、全パッケージのダウンロードを待つのが少し非効率に感じる方もいるかと思います。
今回はよく使う方法ではありますが、CIの実行時間を短縮するために、actions/cache
を使ってpnpmの依存パッケージをキャッシュした際の設定メモを書いておきます。
基本のキャッシュ設定
まずはactions/cache
を使い、pnpmがパッケージを保存しておく「ストア」と呼ばれる場所を丸ごとキャッシュするように。
実際のコードはこんな感じです。まずpnpm store path
でキャッシュすべき場所を取得し、それをactions/cache
に渡しています。
- name: pnpmのstoreパスを取得
id: pnpm-cache
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: pnpmのキャッシュを設定
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
キャッシュを識別するためのkey
がここで重要になります。pnpm-lock.yaml
のハッシュ値をキーに含めることで、「ロックファイルに変更がなければ同じキャッシュを使い、変更があれば新しいキャッシュを作る」という賢い動きをしてくれます。
応用メモ
キャッシュには、他にもいくつか便利な使い方があるようです。
いろんなキャッシュを一度に
pnpmのキャッシュだけでなく、ビルドツール(Turborepoなど)やFirebaseエミュレーターのキャッシュなども一緒に保存しておくと、さらにCIが速くなるかもしれません。path
には複数のパスを指定できます。
- uses: actions/cache@v4
with:
path: |
${{ env.STORE_PATH }}
~/.cache/firebase
./functions/.turbo
key: ${{ runner.os }}-build-${{ hashFiles('**/pnpm-lock.yaml') }}
# ...
あえてキャッシュを無効にする時
まれにキャッシュが原因で問題が起きたり、クリーンな状態で動作確認したい時もあります。そんな時は、キャッシュキーを毎回ユニークなものにすれば、キャッシュがヒットしなくなります。
ワークフローの実行番号(github.run_number
)をキーに加えるのが簡単な方法です。
key: cache-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ github.run_number }}
これなら実行ごとに必ずキーが変わるので、毎回新しいキャッシュが作られる(=キャッシュが使われない)状態になります。
まとめ
pnpmのキャッシュ設定は、CIの実行時間を短縮するのにかなり効果がありました。ビルドが速くなると開発体験も良くなるので、試してみて損はないと思います。
また、キャッシュキーの仕組みや応用的な使い方を知っておくと、いざという時のトラブルシューティングにも役立ちそうだと感じました。
どなたかの参考になれば嬉しいです。