CircleCI実践入門

CircleCI 自体は前から使っていたのですが、知識を update せにゃいかん気になってきたので読みました。 まとまった状態で読めるのはありがたいです。

構成

本書は、なぜ CI / CD が必要か?から始まり、CircleCI の基本、GitHub との連携やジョブが失敗した時のデバッグ方法の説明等がなされています。基本的に CircleCI の機能の説明なのですが、CI / CD のインフラをオンプレ、SaaS どちらにするのかの判断材料として読んでも良いんじゃないかと思います。

気になったところ

CircleCI の機能自体も発見が多かったのですが、ワークフローとジョブの作り方の所が気になりました。

ジョブは分割すべし

最初の方はプロジェクトのコードも小さいので、1つのジョブに

  • 静的解析
  • テスト
  • docker image 生成

みたいな感じで step を連ねて記載していくと思いますが、規模が大きくなってくると、途中で失敗しまうことも多くなります。 長い時間をかけて失敗してしまった時も、リソースを使用した分だけコストが発生します。 再実行する時も最初から実行することになります。 その辺りの余計なコストを発生させないようにするために、それぞれジョブで分けて、実行するのはワークフローで制御する方がベストプラクティスなようです。

確かに規模が大きくなってくると、テストの実行時間を短縮したくなり、並列で実行することを考えます。 その時に1つのジョブになっていると、並列で実行したい内容と1つのプロセスで実行したい内容が混在してきます。 テストだけ並列数を上げて実行したいのに静的解析も並列でやっても意味ありませんし、「他の処理が終わるのを待つ時間」というのもコストになりますから、もったいないですよね。

ジョブ間のファイル共有も考えられていて、ストレージやキャッシュを使って共有できます。

ジョブを小さな責務で分けておくことで、1つのジョブを並列で実行することもできますし、異なるジョブを同時実行することもできます。トータルでかかる時間を減らしやすくなると思いました。これは気にしていこう。

Exit Code 137 問題

私は Java で SpringBoot 使ったアプリケーションのビルドに使うことが多いので、gradle 使うことが多いです。 よく目にするのが、OOM でジョブが失敗する、という奴です。

ジョブを動かすリソースクラスを良いものにすれば大体解決はするのですが、コストが跳ね上がります。 そのために、メモリチューニングする必要があるのですが、GRADLE_OPTS-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=2 しましょうと書いてあるのに好感が持てました。確かにサポートページに書いてあるのですが、これだけでも本書を読む価値ありだと思います。

gradle のプラグインによっては、環境変数でなく設定の方でメモリ指定する奴もいるのでご注意くださいませ。

まとめ

CI / CD のインフラ部分を面倒見られる体制があるなら考えなくて良いかもしれませんが、そんな余裕ない or リソースを他のことに回したいのであれば SaaS の検討しても良いんじゃないかと思います。他の SaaS は正直使ったことないのですが、CircleCI は安定していてお勧めできると思います。

目下の悩みは、機能追加に伴ってテストの数も増えていって、CI 回すたびに時間(+SaaS のコスト)がかかる問題の折り合いをどうつけるかなのですが、誰か相談できる人おらんかな...。