はじめに
NuxtJSは、以下のコマンドで新しいプロジェクトを作ることができます。
yarn create nuxt-app <project-name>
途中、以下の設定をすると、親切にもGitHubのCI用ファイルをデフォルトで作成してくれます。
Continuous integration: GitHub Actions (GitHub only)
ただ、自分の環境だとキャッシュのパスがおかしくキャッシュできていないどころか不要なものをキャッシュしており、CIに余計な時間がかかっていた、というお話です。
改善法
結論としてやったことです。僕らはnode_modulesのみをキャッシュしたいのですが、パスが僕の環境では間違っていたようです。
- name: Cache node_modules 📦
uses: actions/cache@v2.1.7
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 }} この行を下のようにする
path: node_modules
// key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} この行も一応下のようにする(こちらはたぶん不要?)
key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
問題
上の画像は、左がとあるPRをマージする直前の、右がとあるPRをマージする際に走ったnuxt製のCIの結果で、リポジトリ内のコードに変更はありません。左右を見比べると、それぞれのタスクの時間がほとんど同じことがわかるかと思います。
どちらもキャッシュが使われているのであれば、これは特に問題にならないのですが、気になるのは赤線を引いたところ。どちらもその1つ前のタスクで(タイトル的に)node_modules
のキャッシュを取り出していると考えられますが、その割にはInstall dependencies
に時間がかかっています。キャッシュを使っていれば数秒もあれば十分なはず…
では、後に実行された画像右のCIのタスクの中身を詳しく見てみましょう。
赤線を読む限り、何らかのファイルのキャッシュの復元は成功しているようです。ただ、Install dependencies
では、yarn install
でnode_modules
を作成しているため、node_modules
ではない何かを復元しているようです。
これより、意図したキャッシュが行われていない問題がわかります。改善法に書いた方法で直して直してあげましょう。
まとめ
上の例ではCIの時間が全体で1分もかかっていないためキャッシュの失敗は問題にならないと思いますが、環境によっては大問題になります。実際の経験談として、CIが終わるまで基本10分、場合によってはキャッシュの復元に途中で失敗してactions/cache
のタイムアウトである1時間以上かかることがありました。PRをマージするためにCIが通ることを必須としていたのですが、CIの大渋滞でマージどころではなくなりました… ちなみに、CIのキャッシュの容量もおかしかったです。クローンしてきたファイルにnode_modules
を含めても500MB程度なのに、キャッシュの容量をCIのタスクの中身で確認すると2GB。どこからそんなに持ってきた。キャッシュのバカヤロー!
キャッシュのパスを上の方法で直すと、CIは1回2分程度。サクサクです。キャッシュよアリガトー!
(いうてキャッシュ切っても10秒程度しか変わらなかったと思いますが)
デフォルト設定は多くの先人が作り上げた血と汗と涙の結晶であることが多いと思いますが、今回のように環境によっては残念な結果になることもあります。問題となったら疑ってあげましょう。