Open7

GitHub Actions で yarn install を爆速にしたい

結論

  • actions/cache にある yarn のサンプルはネットワークからパッケージを fetch してくる分をサボれる
    • GitHub-hosted runners の IOPS が低いのか今回のケースでは50%程度の高速化に留まった
  • node_modules をキャッシュすれば爆速

背景

基本的に公式のサンプルの https://github.com/actions/cache/blob/main/examples.md#node---yarn を設定しておけば良さそうにみえる
しかしこれだとローカルで yarn install を叩いて success Already up-to-date. が出て1秒未満でコマンドが終了するという挙動にはならない
公式のサンプルの設定でもいくらかは速くなるけど1秒未満の方が嬉しいので調査したい

試したプルリク

https://github.com/odanado/typescript-nodejs-template/pull/188

公式のサンプルの挙動を調べる

- 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 が高速化しました!ありがとうございます!

ログインするとコメントできます