GitHub Actions で yarn install を爆速にしたい
結論
- actions/cache にある yarn のサンプルはネットワークからパッケージを fetch してくる分をサボれる
- GitHub-hosted runners の IOPS が低いのか今回のケースでは50%程度の高速化に留まった
-
node_modules
をキャッシュすれば爆速- nuxt.js はこの方針
- https://github.com/nuxt/nuxt.js/blob/dev/.github/workflows/test.yml
- npm パッケージの開発においてはこの方針でも問題ないのかも
- なんでこの方針をサンプルに載せていないかは issue で聞いてもいいかも
- nuxt.js はこの方針
背景
基本的に公式のサンプルの https://github.com/actions/cache/blob/main/examples.md#node---yarn を設定しておけば良さそうにみえる
しかしこれだとローカルで yarn install
を叩いて success Already up-to-date.
が出て1秒未満でコマンドが終了するという挙動にはならない
公式のサンプルの設定でもいくらかは速くなるけど1秒未満の方が嬉しいので調査したい
試したプルリク
公式のサンプルの挙動を調べる
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
これは yarn cache dir
で返されたディレクトリをキャッシュしている
yarn cache | Yarn
このディレクトリには yarn 全体のキャッシュが保存されている
あるプロジェクトで使用しているパッケージを他のプロジェクトで使用するときにファイルのダウンロードは行わず、ローカルでのファイルのコピーだけで済むようになっている
yarn cache dir
のディレクトリをキャッシュすることでどれぐらい速くなるか
素の yarn install
yarn cache dir
をキャッシュする場合
画像の通り
- 素の
yarn install
に25秒 -
yarn cache dir
のリストアに3秒、リストア後のyarn install
に12秒
となった
おおよそ50%の高速化だけど、これを良いと思うかは人次第
yarn install
に --verbose
オプションを付与して、中の様子を追ってみる
11.2秒ぐらいでパッケージの fetch が終わっている。これはキャッシュありなしで yarn install
にかかる時間の差分に大体近い
node_modules
自体をキャッシュしてみる
https://github.com/nuxt/nuxt.js/blob/dev/.github/workflows/test.yml を参考に、以下の設定を書いてみた
- name: cache node_modules
id: node_modules_cache_id
uses: actions/cache@v2
with:
path: |
node_modules
key: node-v${{ matrix.node-version }}-deps-${{ hashFiles(format('{0}{1}', github.workspace, '/yarn.lock')) }}
この場合だと、yarn install
が1秒ぐらいで終わっている。嬉しい
yarn cache dir
をキャッシュした場合の yarn install
遅くない?
手元の MacBook Pro (13-inch, 2019)
で node_modules
を消して yarn install
を実行した結果次のようになった
$ rm -rf node_modules
$ time yarn install
yarn install v1.22.10
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
✨ Done in 4.72s.
yarn install 3.74s user 6.39s system 197% cpu 5.144 total
GitHub Actions での yarn install
と比べて半分ぐらいの時間で終了している
Github actions have inconsistent CPU and IOPS - Code to Cloud / GitHub Actions - GitHub Support Community
GitHub-hosted runners は IOPS があんまり良くないのかも(未検証)
CI が高速化しました!ありがとうございます!