powered by TechFeed
表示モード
Deep Dive

AIがコードを書きすぎてCIが詰まった — LinearがテストをほぼCI4倍に増やしながら待ち時間を短縮できた理由

9月21日、Linearが「AI coding has made CI a bottleneck, so we reworked ours to keep up」と題した記事を公開した。AIコーディングによってコード量が急増する中、CIがボトルネック化した問題にLinearがどう対処したかを詳述した記事だ。

9月21日、Linearが「AI coding has made CI a bottleneck, so we reworked ours to keep up」と題した記事を公開した。AIコーディングによってコード量が急増する中、CIがボトルネック化した問題にLinearがどう対処したかを詳述した記事だ。

プロジェクト管理ツールを提供するLinearは、自社の開発フローにAIエージェントを積極的に取り入れている。その結果、年初からテストスイートがほぼ4倍に膨らんだ。コードが増えればCIに流れるPRも増え、テスト実行時間もコストも雪だるま式に増加する。開発を加速させたAIが、今度はCIを詰まらせるという皮肉な状況だ。AIによる開発速度の向上がインフラ側の新たな課題を生む——多くのチームが直面し始めているこの問題に、Linearがどう向き合ったかは実践的な参考になる。

Linear社のCTOであるTuomasが「CIコストが高い。なおかつ速くしてほしい」という課題を起票したことが取り組みの発端となった。結果として、PRのCI待ち時間を6分超から5分強へ短縮し、テスト1件あたりのランナー時間をおよそ半減させることに成功した。改善の柱は4つある。

最大の効果:テスト分離の廃止とシャード最適化

記事の中で最もインパクトが大きかった改善が、Vitestのモジュール分離(isolate)設定の変更だ。

LinearのテストランナーにはVitestを使っている。Vitestはデフォルトでテストファイルごとにモジュールを分離する。これ自体は正しい設計だが、LinearのAPIテストでは毎回エンティティ・GraphQL・デコレーターのグラフを再構築する必要があり、オーバーヘッドが積み重なっていた。

そこでisolate: falseを設定したオプトイン方式のVitestプロジェクトを導入し、安全なファイルだけがワーカー内でモジュールレジストリを共有できるようにした。各ファイルにオプトインのコメントを明示的に付与し、共有状態のティアダウン処理も追加している。フェイクタイマーや共有状態が複雑に絡み合うファイルは無理に移行せず、隔離プロジェクト側に残した。

この1点だけで月間ランナー時間の約17%削減を達成。最も遅いシャードの実行時間は300〜379秒から約195秒へ短縮、APIシャード全体のランナー時間は1回あたり32.8分から22分に落ちた。

加えて、AIエージェントが書くテストにも同じルールが適用されるよう、エージェントへの指示定義(スキル設定)を更新した点も興味深い。LinearではAIエージェントにコーディング規約やベストプラクティスをスキルとして登録しており、そこにCIパフォーマンス上の制約を組み込むことで、AIが生成するコードが最初からパフォーマンス要件に沿う仕組みを整備した。

シャード数については3→4→8と段階的に増やした。8シャードへの移行で、ベンチマーク上はクリティカルジョブが19%高速化かつ19%コスト削減。1週間後の実測では最も遅いシャードが5.25分から4.33分に短縮された。

ただし、シャードを増やすだけでは逆効果になる場合がある。セットアップコストがシャード数に比例して増えるからだ。 後述のセットアップ削減を先に行っていたからこそ、8シャードが現実的な選択肢になった。

積み重ねが効いた:インフラ・セットアップ・クリティカルパスの最適化

インフラの刷新では、GitHub Actionsからサードパーティランナーへ移行したことで、同じパイプラインが平均34%高速化tscのような重い処理は52%削減された。

さらに、MicrosoftがTypeScript向けに開発しているGoベースのネイティブコンパイラtsgo(TypeScript Go移植プロジェクト)への移行で、tscチェックの週次中央値が73%短縮。型チェックがボトルネックでなくなった。なお、tsgoは元記事公開時点での同社環境での実績として紹介されている。

ESLintのカスタムルールからTypeScript型情報への依存を排除し、ASTの静的解析に書き直したことで、APIのlint時間が68%減、リポジトリ全体のlint時間が55%減。これによりOxlintへの移行も容易になった。

セットアップの削減では、pnpmのモノレポ構成でAPIテストワークフローがリポジトリ全体の依存関係をインストールしていた問題に対処した。APIパッケージとその依存だけに絞ることで、pnpm installが44〜73秒から16〜18秒に短縮。加えて、ロックファイルが頻繁に変わる影響でキャッシュヒットしても28秒かかっていたnode_modulesのキャッシュを廃止した。フィルタードインストールなら約7.5秒で済むため、キャッシュより再ビルドの方が速いという結論だ。

7つの独立したチェックをそれぞれ別ジョブで実行していた箇所は、2ジョブに統合して内部で並行実行する構成に変更。この変更だけで月間約87,000ランナー分(全CI使用量の11.8%相当)の節約になった。

クリティカルパスの短縮では、変更検出ジョブがリポジトリ全体をcheckoutしていたのをフェッチ深度制限に変更し、処理時間を94秒から20秒に短縮。またマージキューに入った後もキャッシュマーカー書き込みがゲートとして残っていたのを、テスト完了後に非ゲートで実行するよう変更し、APIのPR・マージキューエントリごとに42秒を削減した。

現在の到達点と今後

これらの改善を施さなければ、現在のテストスイートは約11分かかっていた計算になる。実際には5分強に収まっている。

Linearでは現在、週あたり約2,000件のテストが追加されている。AIエージェントが開発を加速し続ける以上、CIの高速化は一度きりのプロジェクトではなく継続的な取り組みになる、と記事は結んでいる。

詳細はAI coding has made CI a bottleneck, so we reworked ours to keep upを参照していただきたい。