CircleCI

Circle CI 2.0 移行時のキャッシュ設定メモ

3行で

  • Circle CI 2.0 でキャッシュの設定をしたい
  • 英語読める人は Caching Dependencies - CircleCI を読みましょう
  • これは↑のドキュメントを読みつつ自分用にメモし直しただけの記事です

※ 必要なところは意訳してます。間違いを見つけたらご指摘お願いします

背景

Circle CI はテストを走らせるのに使ってるわけですが、テスト走らせるために毎回 bundle install とか yarn install してライブラリを全部ダウンロードしてたら時間がかかって困ります。だから vendor/bundle とか node_modules をキャッシュしようというモチベーションが発生します。

そこで、キャッシュってCircle CI 2.0 だとどうやって設定するの、という話になります。

基本的な設定

save_cache にキャッシュのキーとキャッシュしたいパスを, restore_cache に利用したいキャッシュのキーを指定します。

save_cache

キャッシュを保存する。ドキュメントのサンプル見るとこう書かれています。

      - save_cache:
          key: gem-cache-{{ arch }}-{{ .Branch }}-{{ checksum "Gemfile.lock" }}
          paths:
            - vendor/bundle

キー名の謎の変数はなんでしょう。もちろんドキュメントに書かれています。

arch

The OS and CPU information. Useful when caching compiled binaries that depend on OS and CPU architecture, for example, darwin amd64 versus linux i386/32-bit.

とのこと。

(意訳: OSとCPUの情報。コンパイルされたOS・CPUアーキテクチャに依存するバイナリをキャッシュするときに使える。たとえば darwin amd64 と linux i386/32-bit)

なるほど、並列で走らせるときに各台が違う arch の場合は使ったほうがよい(?)

checksum "filename"

A base64 encoded SHA256 hash of the given filename’s contents, so that a new cache key is generated if the file changes. This should be a file committed in your repo. Consider using dependency manifests, such as package.json, pom.xml or project.clj. The important factor is that the file does not change between restore_cache and save_cache, otherwise the cache will be saved under a cache key that is different from the file used at restore_cache time.

とのこと。

(意訳: 与えられたファイル名の内容をbase64エンコードされたSHA256ハッシュ。なので、そのファイルが変更されると新しいキャッシュキーが生成されます。このファイルはリポジトリにコミットされているべきです。package.json, pom.xml, あるいは project.clj などの依存関係のマニフェストファイルを利用したらいいんじゃないでしょうか。大事なのは、そのファイルが restore_cachesave_cache の間で変更されないことです。そうしないと、キャッシュはrestore_cache 時に使われているファイルと異なるキャッシュキーで保存されます)

gemの場合は checksum "Gemfile.lock" でよさそう。

.Branch

The VCS branch currently being built.

とのこと。ブランチ名が feature/example ならfeature/exampleになるってことか

restore_cache

キャッシュを利用する設定。サンプルにこんなのが書かれています。

      - restore_cache:
          keys:
            - gem-cache-{{ arch }}-{{ .Branch }}-{{ checksum "Gemfile.lock" }}
            - gem-cache-{{ arch }}-{{ .Branch }}
            - gem-cache

何個もキーが設定されてるのはどうしてでしょうか。

Each cache key is namespaced to the project and retrieval is prefix-matched. As caches become less specific going down the list in the following example, there is greater likelihood that the dependencies they contain are different from those that the current job requires. When your dependency tool runs (for example, npm install) it will discover out-of-date dependencies and install those the current job specifies. This is also referred to as partial cache restore.

(意訳: 各キャッシュキーはプロジェクトに名前空間を持ち、検索は前方一致です。リストの下へいくほどキャッシュの指定がゆるくなり、依存関係が現行のジョブとは異なる可能性が高くなります。依存解決ツール(たとえば npm install) が走ると、期限切れのものを発見し、現在のジョブが指定しているものをインストールします。これは partial cache リストアとも呼ばれます)

なるほど便利。部分キャッシュっていうのか。

キャッシュをクリーンしたいとき

依存解決ツールのバージョンが変わるときとかにキャッシュをクリーンしたいときもあるだろうけどどうするの、という話。これについては、こういう感じにするのがいいですよと推奨されている。

    steps:
      - restore_cache:
          keys:
            # Find a cache corresponding to this specific package.json checksum
            # when this file is changed, this key will fail
            - v1-npm-deps-{{ checksum "package.json" }}
            # Find the most recent cache used from any branch
            - v1-npm-deps-

v1-というプレフィクスを付けて、ツールのバージョンを変えるときにはこれをv2にする、という感じらしい。なるほど。じゃあ付けておこう。


以上でだいたいやりたいこと出来たはず。なにかあれば随時書き足します。