patorashのブログ

方向性はまだない

CircleCIで使う処理をShellScriptにしていっている

CircleCIで時々思わぬところでライブラリ系のキャッシュがされずにエラーになってしまうことがあった。 処理を速くするために複雑なキャッシュをするようになっていたので、それが原因である…。久々に自分で見てみても複雑だなぁ〜と思う。

patorash.hatenablog.com

もっとシンプルにしたいなぁと思っていたら、たまたま以下の記事を見かけた。

qiita.com

これには感銘を受けた。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関数を使えばできることがわかった。

zuqqhi2.com

手元にあるシェルスクリプトコマンドブックにも書いてあった。とにかく、これを使えば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の高速化に効きそうな記事があったので、これらについて今後試していきたい。

medium.com

medium.com

それにしてもやはりdocker-composeを使ってテストをするのは速くなりにくいようだ…。 machineだと、resource_class: smallが選択不可能なので、smallにして並列数を2倍に増やす作戦も失敗に終わったし、打ち手に限りがある。

1台でキャッシュ用ファイルを作る戦略だったが、そろそろ見直したほうがいいかもなぁ…と考えている。 まぁdocker-composeを使っているせいなので(キャッシュしたいファイルがdocker volumeにあるから引っ張り出すのが遅い)もうちょい、いい方法がないか考える。まぁ速度よりも安定性をまずは重視する。