CircleCIの1.0が8月でサポート終了ということで、先月くらいに、重い腰をあげて作業していました。
いくつかキャッシュの指定関連で詰まって、試行錯誤したのでメモしておきます。
ディレクトリをjob単位で設定できない
以前書いたこの記事の内容です。
CircleCI 2.0でbuild_dirを指定する
1.0ではbuild_dir
という設定があり、checkoutしたリポジトリルートからたどる場所をjob単位で簡単に固定できましたが、
2.0ではtask単位で指定する必要があります。
(2.0でjob単位で指定できるのはリポジトリルートの場所だけ)
名前はworking_directory
という名前に変更されています。
ただし、working_directory
はrun
やdeploy
等のタスクにしか適用されず、
キャッシュ関連のタスクである、save_cache
,restore_cache
には適用されません
対策
なのでkey等でファイルのchecksumを参照する場合はrootパスから指定する必要があります。
上記記事の再掲ですが、以下のようにします。
- restore_cache:
working_directory: api # ここのブロックには有効にならない
key: venv-{{ checksum "requirements.txt" }}
# ....
- save_cache:
working_directory: api # ここのブロックには有効にならない
key: venv-{{ checksum "requirements.txt" }}
paths: venv
- restore_cache:
key: venv-{{ checksum "api/requirements.txt" }} # checksum関数に渡すときに示す。
# ....
- save_cache:
key: venv-{{ checksum "api/requirements.txt" }}
paths: api/venv # 保存するパスもきちんと示す
キャッシュキーに環境変数を指定できない
キャッシュのキーは特殊なリテラルでchecksum等を指定できます。
使える関数はこちら: using-keys-and-templates
いかに少し転記します。
Template | Description |
---|---|
{{ .Branch }} |
The VCS branch currently being built. |
{{ .BuildNum }} |
The CircleCI build number for this build. |
{{ .Revision }} |
The VCS revision currently being built. |
{{ .Environment.variableName }} |
The environment variable variableName (supports any environment variable exported by CircleCI or added to a specific Context—not any arbitrary environment variable). |
{{ checksum "filename" }} |
ここに書いてあるんですが、.Environment.variableName
を使えば環境変数もkeyに含めそうだな、と思っていました。
でも自分で設定した変数は使えないと書いてますね、、
- パスの記事: Can I use variables in cache paths?
- keyの記事: Cannot use circle.yml environment variables in cache keys
上の記事でもありますが、他の方法でも関数自体は展開してもらえませんでした。
- save_cache:
key: v1-{{ epoch }}
paths:
- $(my cache dir) # 展開されない
- save_cache:
key: v1-{{ epoch }}
paths:
- $MY_CACHE_DIR # 環境変数も展開されない
- save_cache:
key: v1-{{ epoch }}
paths:
- {{ .Environment.MY_CACHE_DIR }} # これはCircleCIが設定した値しか入らない
- save_cache:
key: v1-{{ .Environment.MY_CACHE_DIR }} # keyでも同じ。
paths:
- /my/cache/dir
悲しいですね。
対策
pathの対策はhardcodeです
- save_cache:
key: v1-{{ epoch }}
paths:
- /my/cache/dir # hardcodeしよう
keyも基本的にはhardcodeですが、checksumとかで環境変数の値に応じてkeyを変えたいケースもありそうです。
その場合は環境変数を一回ファイルに書き出してchecksumします。
- save_cache:
key: v1-{{ 1.0.0 }} # 環境変数もハードコードしちゃう
paths:
- /my/cache/dir
環境変数が展開できる場所でファイルに書き出し、そのファイルのchecksumをkeyに入れます。
version: 2
jobs:
build:
# ...
environment:
MY_VERSION: 1.0.0
steps:
- checkout
- run: echo ${MY_VERSION} > _my_version # 展開される場所で書き出す。
- restore_cache:
key: v1-{{ checksum "_my_version" }} # ファイルのchecksumをkeyに入れる
# ...
- save_cache:
key: v1-{{ checksum "_my_version" }}
paths:
- /my/cache/dir
そもそもキャッシュすべきファイルが何か、っていうのも難しいですし、
基本的にバージョン依存はファイルとしてリポジトリに含まれるケースが多いので、
あまり遭遇しないかもしれませんね。
削除できない
一度キャッシュされた内容は削除できないようです。
上のように色々試行錯誤して、ちゃんとキャッシュされてるかを確認して行ったらゴミというか以前試した空のキャッシュができてしまって上書きもできなくなり困りました。
対策
特にないです。
試行錯誤中はkeyにtest
とかprefixを入れるとか、名前や順番を変えて試すしかないです。
そのうち削除機能やフラグが実装されるかもしれませんね。。
まとめ
大体の問題は既にdiscuss.circleci.comで議論・回答されている内容かなと思うので、
困った時は見て見るといいな、と思います。
でも結構CircleCI担当者の回答が素っ気ないというか、「これで十分」「できないのでハードコードして」という感じでなんか冷たく感じました。
「忙しくて無理 」「いつか検討するからissueに入れておくね」「頑張るから待っててね〜」みたいな姿勢が欲しくなってしまいました。
贅沢ですね。