CircleCIで時々思わぬところでライブラリ系のキャッシュがされずにエラーになってしまうことがあった。 処理を速くするために複雑なキャッシュをするようになっていたので、それが原因である…。久々に自分で見てみても複雑だなぁ〜と思う。
もっとシンプルにしたいなぁと思っていたら、たまたま以下の記事を見かけた。
これには感銘を受けた。makeはイマイチよくわかっていないので今のところは採用しないが、.circleci/config.yml
で使っているcommand類はShellScriptにすることが可能だ。ShellScriptにすることで、ローカル環境で試しやすくなる。config.ymlに直書きだと、試しづらい。当たり前だけれどなんだか目から鱗だった。
遅くても必ず完走させるようにしたい
キャッシュの不備が原因でテストがコケるのは本当にダサい…。しかも何が原因でライブラリの更新漏れやキャッシュし忘れが発生するのかを探すのが大変になってくると本末転倒…。
それならばもうシンプルに毎度毎度、ちゃんとライブラリの更新処理とキャッシュ処理をするようにした。これでもう予期しないエラーにはならないはず!😀
ただし、このせいで6分くらい遅くなっている…😫
workspaceを渡すのが遅い
CircleCIでは、workspaceを保存して次のジョブに渡すことができる。これをすると、次のジョブで環境構築する手間が省けるので速…そうなのだが、この受け渡し処理が遅い…。dockerイメージを含めているせいで容量も大きいというのはあるのだが、3分以上かかる。受け取るのも1分近くかかる。
1コンテナで環境構築を行い、テストを流す際は4コンテナにそれを渡して処理させているので、料金的には多少安いはずなのだが、時間的には直列になるので頂けない。
コマンドのShellScript化
これはローカルで実験がしやすくなったのでよかった。
エラーを見逃してしまう
ただ、CircleCIのconfig.ymlではステップ毎に定義していたものを1つのShellScriptにまとめたので、エラーの検知がうまくいっていなかった。エラーが起きているのに次の処理に行ってしまい、最後の処理が成功しているので終了コードが0になり、CircleCI上で成功したことになってしまっていた。
エラー対策
ShellScriptでもtry-catchみたいなことができれば…と思い、調べてみたら、trap
関数を使えばできることがわかった。
手元にあるシェルスクリプトコマンドブックにも書いてあった。とにかく、これを使えばtry-catch-finallyができる。
エラーが起きようが起きまいが、docker-compose down
はさせたかったので、finally的にやるようにした。
docker_compose_down() { docker-compose down } catch_error() { printf "エラーが発生しました" exit 1 } trap docker_compose_down EXIT trap catch_error ERR
上記の定義してあるファイル(common.sh)を、全てのShellScriptで読み込むように修正した。
#!/bin/bash SCRIPT_DIR=$(cd $(dirname $0); pwd) . $SCRIPT_DIR/common.sh
一旦これで様子見する。
高速化するには?
スタディストさんの開発ブログにCircleCIの高速化に効きそうな記事があったので、これらについて今後試していきたい。
それにしてもやはりdocker-composeを使ってテストをするのは速くなりにくいようだ…。 machineだと、resource_class: smallが選択不可能なので、smallにして並列数を2倍に増やす作戦も失敗に終わったし、打ち手に限りがある。
1台でキャッシュ用ファイルを作る戦略だったが、そろそろ見直したほうがいいかもなぁ…と考えている。 まぁdocker-composeを使っているせいなので(キャッシュしたいファイルがdocker volumeにあるから引っ張り出すのが遅い)もうちょい、いい方法がないか考える。まぁ速度よりも安定性をまずは重視する。