はじめまして、エンジニアリンググループの山口です。9月にjoinし、クラウド型電子カルテ「デジカル」を開発しています(今後「エムスリーデジカル」として本格展開することがプレスリリースで発表されました!)。
今回は、テスト並列化や札束ビンタ以外の方法で、GitLab CIの実行時間を15%短縮した話です。
3行でまとめると
- GitLab CIのrawログに隠し要素がある
- 原因の深掘り大事
- キャッシュを雑に設定してはいけない
前提: デジカルの開発スタイル
デジカルは、 Ruby, Scala, Java, JavaScript と複数の言語を組み合わせてサービスを構成しています。
チームの開発スタイルは以下の通りで、比較的安全に開発が進められるようになっています。
- git-flowに近い開発フロー
- GitLab CIによるビルド、ユニットテスト、静的解析
- 窓が壊れているのを放置しない (割れ窓理論 - Wikipedia)
- 誰もレビューしていない状態でマージしない
- CIが通らない状態でマージやリリースをしない
ただし、改善の余地は山ほどあります。そのひとつは、"CIの遅さ"でした。
問題: CIが遅いことによる弊害
CIは、全ジョブ合計で1時間半近く掛かっていました。依存関係のないジョブを複数ランナーで並列実行しても40分。遅い。
CIの遅さによって、主に2つの問題が生じていました。
hotfixリリースに時間が掛かる
好ましくはありませんが、何らかの理由で急いでリリースする場合があります。
その際、CIが通ってからリリースするようにしているため、CIの遅さはそのままリリースの遅さに直結します。仮に不具合の修正だとすると、修正の適用がそれだけ遅れます。これは問題です*1。
また、それを認識した上でCIを待たなければならない、という精神的な辛さもあります。
コンテキストスイッチに時間が掛かる
時々CIの通らないpushをしてしまうこともあります。しかし、その失敗が通知されるのは、最悪の場合1時間半後です。
もう内容はほとんど覚えていません。なんだっけ、と思い出す時間が積み上がります。
原因: なぜCIが遅いのか?
この問題に対処することを決め、早速原因を探っていきます。
*1:念の為ですが、CIを通さずにリリースするのは、リスクを考えると現実的ではないため実施していません