リニア エンジニアの Mufeez Amjad 氏は、AI コーディング エージェントが CI を最悪のボトルネックにした後、同社が継続的インテグレーション パイプラインをどのように再構築したかについての詳細な説明を公開しました。プル リクエストの待ち時間は 6 分以上から 5 分強に短縮され、その一方でテスト スイートは年初からほぼ 4 倍に増加しました。

9 月 21 日に Linear のエンジニアリング ブログに公開されたこの投稿は、よくあることですが、上からの簡潔な指示で始まりました。今年の初め、Amjad さんは Linear を開いて、同社の CTO である Tuomas が「CI コストが高い」というタイトルの課題を彼に割り当てていることを知り、その間に CI をより速くするよう依頼しました。このストーリーの詳細については、現在進行中の AI 業界の報道 をご覧ください。

エージェントが検証を上回る場合

問題は構造的なものであり、偶発的なものではありません。 「エージェントはコードの出荷を飛躍的に高速化しました」とアムジャド氏は書いています。「しかし、それらの変更の検証は同じ速度にまったく追いついていません。」すべてのプル リクエストは依然として CI を通過する必要があるため、開発が加速するにつれて CI が課題となり、インフラストラクチャのコストが上昇し、開発者とそのエージェントがフィードバックを待つ時間が長くなります。

PR が CI で待機する時間と消費するランナー時間の 2 つの指標に対して線形的に最適化されています。数か月にわたる作業の結果、テスト スイートは 1 月からほぼ 4 倍になったにもかかわらず、プル リクエストの待機時間は 6 分強から 5 分強に短縮され、テストごとのランナー時間はおよそ半分に短縮されました。

作業は大きく 4 つのカテゴリに分類されます。インフラストラクチャとツールのアップグレード、他の作業を制御するジョブの最適化、セットアップの繰り返しの削減、テスト実行の効率化です。 Linear のコードベースは主に TypeScript ですが、最適化の多くは言語やツールチェーン全体に適用されます。

高速なマシンとネイティブ コンパイラー

初期の成果の中には、CI 自体の最適化をほとんど必要としないものもありました。ワークロードを GitHub Actions から、より高速な CPU、よりパフォーマンスの高いストレージ、より優れたキャッシュ インフラストラクチャを備えたサードパーティ ランナーに移行したことは、すぐに効果をもたらしました。切り替えの両側で 2 日間の同一条件での比較では、ジョブは平均 34% 高速に実行され、「tsc」などの一部のワークロードは 52% 低下しました。

ツールチェーンを最新化することで勝利がさらに高まりました。ネイティブ TypeScript コンパイラである 'tsgo' に切り替えると、型チェックの週次中央値が 73% 削減されました。これはボトルネックを型チェックから完全に取り除くのに十分な大きさです。

型グラフを使用しないリンティング

リンティングも初期の標的でした。 Linear の少数のカスタム ESLint ルールは TypeScript の型情報に依存していたため、lint を実行するたびに評価前に完全な型グラフを構築する必要があり、lint は最もメモリを消費する CI ジョブの 1 つとなっています。

チームは、抽象構文ツリーに対して静的分析を使用するようにルールを書き直し、型情報なしで関数のような構造とガード パターンを識別しました。これにより、ESLint は TypeScript を完全に削除し、API の lint 時間を 68%、フルリポジトリの lint 時間を 55% 削減し、メモリ使用量を大幅に削減しました。また、その後の Oxlint への移行も容易になり、CI ランナーがリンティングに費やす時間がさらに短縮されました。

クリティカル パスの縮小

個々のチェックを高速化することで、Linear はズームアウトし、CI をシステムとして扱いました。そのため、他のすべてのものの前にある小さなジョブ、つまりジョブ レベルでゲートを設定するパス変更検出とテスト結果キャッシュ チェックに注目が集まりました。つまり、8 つの API テスト シャードは完了するまで開始できません。

修正は細かく行われましたが、追加的なものでした。フェッチ深度の制限では、最も遅いゲートで 94 秒から 20 秒かかりました。作業ツリーを必要としないジョブからチェックアウトを完全に削除すると、チェックアウトが 27 秒から 7 秒に短縮されました。履歴が制限されたまばらでブロブレスなチェックアウトにより、プッシュ イベントとマージ キュー イベントにさらに 11 数秒かかりました。合計すると、変更検出ジョブの継続時間の中央値は 26 秒から 8 秒に、p90 は 31 秒から 12 秒に、最も遅い実行時間は 138 秒から 37 秒に短縮されました。

チェックアウトの信頼性にも取り組みが必要でした。サードパーティのランナーは GitHub のネットワークの外側にあり、直接 IP リンクに依存しているため、断続的なリンクの劣化によりフェッチが停止することがありました。 Linear は、「actions/checkout」を、バックオフで再試行する独自の複合アクションに置き換え、「GIT_HTTP_LOW_SPEED_LIMIT」と「GIT_HTTP_LOW_SPEED_TIME」を設定して、停止した接続がハングするのではなく約 30 秒後に中止されるようにし、スティッキー ディスク上に永続的な git ミラーを保持するチェックアウト キャッシュを使用します。

1 つの微妙な修正により、無駄なマージ キュー時間が削除されました。マージ前の最終チェックの一部としてキャッシュ マーカーが書き込まれていたため、テストに合格した後でも PR がキュー内に留まる可能性がありました。その書き込みを非ゲート ジョブに移動すると、すべての API プル リクエストとマージ キュー エントリのマージ パスが 42 秒短縮されました。これらの変更により、キャッシュ ミスに関する API PR の必要なチェックが約 1 分短縮され、ランナーの起動が減少しました。

ジョブあたりの無駄な秒数を削減

最後のカテゴリは、すべてのジョブにわたって繰り返されるセットアップ コストを攻撃します。各 API テスト シャードは、実行のたびに apt を使用して同じ Postgres クライアントをインストールするのに 7 ~ 8 秒かかりました。これをノードと一緒に小さな CI 基本イメージに移動すると、シャードが実行できる状態になり始めることができます。チームは、セットアップ中にネイティブ ビルド ヘッダーをダウンロードすると時々ハングする可能性があることを発見した後、イメージにネイティブ ビルド ヘッダーを追加しました。

共感を呼んだ理由

この投稿は開発者らの神経を逆なでし、Hacker News のトップページに掲載され、1 日以内に約 250 ポイント、約 280 件のコメントを集めました。この反応は簡単に説明できます。Linear の経験では、ほとんどのエンジニアリング組織が現在直面している AI 支援開発のコストを挙げています。プル リクエストを数分で生成するエージェントは、人間のリズムに合わせて設計された検証パイプラインで待機しており、その待機時間は並行して動作するすべてのエージェントで増加します。

Linear のリワークからの教訓は、ボトルネックは変更可能ですが、それは単一の特効薬ではなく、より高速なランナー、より安価なタイプチェック、構文レベルの lint ルール、上限付きフェッチ、回復力のあるチェックアウト、事前構築されたイメージなど、多くの小さな修正の地味な蓄積によってのみ可能であるということです。

---

AI の先を行く

最新の AI ニュース、分析、画期的な情報をすべて 1 か所で入手できます。

AI ニュースをもっと読む→