L'ingénieur linéaire Mufeez Amjad a publié un compte rendu détaillé de la façon dont l'entreprise a retravaillé son pipeline d'intégration continue après que les agents de codage d'IA ont transformé l'IC en son pire goulot d'étranglement – réduisant le temps d'attente des demandes d'extraction de plus de six minutes à un peu plus de cinq tandis que ses suites de tests ont presque quadruplé depuis le début de l'année.
L'article, publié sur le blog d'ingénierie de Linear le 21 septembre, commençait, comme c'est souvent le cas, par un billet laconique venant d'en haut. Plus tôt cette année, Amjad a ouvert Linear et a découvert que Tuomas, le CTO de l'entreprise, lui avait confié un problème intitulé « Les coûts de l'IC sont élevés » – et lui avait demandé de rendre l'IC plus rapide pendant qu'il y était. Pour plus de contexte sur cette histoire, consultez notre couverture continue de l'industrie de l'IA.
Lorsque les agents dépassent la validation
Le problème est structurel et non accidentel. "Les agents ont rendu l'expédition du code exponentiellement plus rapide", a écrit Amjad, "mais la validation de ces modifications n'a pas tout à fait suivi le même rythme." Chaque pull request doit toujours passer par CI, de sorte qu'à mesure que le développement s'accélère, CI devient le point d'étranglement, ce qui augmente les coûts d'infrastructure et oblige les développeurs et leurs agents à attendre plus longtemps les commentaires.
Linéaire optimisé pour deux métriques : combien de temps un PR attend sur CI et combien de temps d'exécution il consomme. Les résultats après des mois de travail : bien que les suites de tests aient presque quadruplé depuis janvier, le temps d'attente des pull request est passé de plus de six minutes à un peu plus de cinq, et le temps d'exécution par test a été réduit environ de moitié.
Le travail se répartissait globalement en quatre catégories : mise à niveau de l'infrastructure et des outils, optimisation des tâches qui alimentent d'autres tâches, réduction des configurations répétées et amélioration de l'efficacité de l'exécution des tests. La base de code de Linear est principalement TypeScript, mais la plupart des optimisations s'appliquent à tous les langages et chaînes d'outils.
Des machines plus rapides et un compilateur natif
Certains des premiers gains ne nécessitaient pratiquement aucune optimisation de CI lui-même. Le déplacement des charges de travail de GitHub Actions vers des exécuteurs tiers dotés de processeurs plus rapides, d'un stockage plus performant et d'une meilleure infrastructure de cache s'est révélé immédiatement rentable : dans une comparaison comparable des deux jours de chaque côté du commutateur, les tâches ont été exécutées 34 % plus rapidement en moyenne, avec certaines charges de travail comme "tsc" chutant de 52 %.
La modernisation de la chaîne d'outils a aggravé la victoire. Le passage à « tsgo », le compilateur TypeScript natif, a réduit la médiane hebdomadaire de la vérification de type de 73 %, ce qui est suffisamment important pour éliminer complètement le goulot d'étranglement de la vérification de type.
Linting sans le graphique de type
Le peluchage était une autre des premières cibles. Une poignée de règles ESLint personnalisées de Linear dépendaient des informations de type TypeScript, ce qui obligeait chaque exécution de lint à créer le graphe de type complet avant de les évaluer, ce qui faisait du lint l'une des tâches CI les plus gourmandes en mémoire.
L'équipe a réécrit les règles pour utiliser l'analyse statique sur l'arbre syntaxique abstrait, identifiant les constructions de type fonction et les modèles de garde sans aucune information de type. Cela a permis à ESLint d'abandonner entièrement TypeScript, réduisant ainsi le temps de charpie de l'API de 68 % et le temps de charpie du référentiel complet de 55 %, avec une utilisation de la mémoire considérablement réduite. Cela a également facilité la migration ultérieure vers Oxlint, ce qui a encore réduit les minutes de CI consacrées au peluchage.
Réduire le chemin critique
Avec des contrôles individuels plus rapides, Linear a effectué un zoom arrière et a traité CI comme un système. Cela a attiré l'attention sur les petits travaux placés devant tout le reste : la détection des changements de chemin et les vérifications du cache des résultats des tests qui se déroulent au niveau du travail, ce qui signifie qu'aucun des huit fragments de test de l'API ne peut démarrer avant d'avoir terminé.
Les correctifs étaient granulaires mais additifs. Le plafonnement de la profondeur de récupération a fait passer la porte la plus lente de 94 secondes à 20. La suppression complète de l'extraction des tâches qui n'ont jamais eu besoin d'un arbre fonctionnel a réduit celles-ci de 27 secondes à 7. Une extraction clairsemée et sans tache avec un historique limité a permis d'économiser environ 11 secondes supplémentaires pour les événements de poussée et de fusion de file d'attente. Au total, la durée médiane de la tâche de détection de changement est passée de 26 secondes à 8 secondes, son p90 de 31 à 12 et son exécution la plus lente de 138 secondes à 37.
La fiabilité du paiement devait également être améliorée : comme les exécuteurs tiers se trouvent en dehors du réseau de GitHub et s'appuient sur une liaison IP directe, la dégradation intermittente de la liaison bloquait parfois les récupérations. Linear a remplacé `actions/checkout` par sa propre action composite qui réessaye avec interruption, définit `GIT_HTTP_LOW_SPEED_LIMIT` et `GIT_HTTP_LOW_SPEED_TIME` pour qu'une connexion bloquée s'interrompe après environ 30 secondes au lieu de se bloquer, et utilise un cache de paiement qui conserve un miroir git persistant sur un disque collant.
Un correctif subtil supprimait le temps perdu dans la file d'attente de fusion : les marqueurs de cache étaient écrits dans le cadre de la vérification finale avant la fusion, de sorte qu'un PR pouvait rester dans la file d'attente même après la réussite de ses tests. Le déplacement de cette écriture dans une tâche non bloquée a permis de réduire de 42 secondes le chemin de fusion pour chaque demande d'extraction d'API et entrée de file d'attente de fusion. Ensemble, ces changements ont réduit d'environ une minute les vérifications requises pour les PR API en cas d'échec de cache tout en réduisant les démarrages d'exécuteurs.
Moins de secondes perdues par tâche
La dernière catégorie attaquait les coûts de configuration répétés pour chaque tâche. Chaque fragment de test d'API a passé 7 à 8 secondes à installer le même client Postgres avec apt à chaque exécution ; le déplacer dans une petite image de base CI à côté de Node signifiait que les fragments pouvaient démarrer, prêts à fonctionner. L'équipe a ensuite ajouté des en-têtes de build natifs à l'image après avoir découvert que leur téléchargement lors de l'installation pouvait parfois se bloquer.
Pourquoi ça a résonné
Le message a touché une corde sensible chez les développeurs : il a fait la une de Hacker News, attirant environ 250 points et environ 280 commentaires en une journée. La réaction est facile à expliquer : l'expérience de Linear cite un coût du développement assisté par l'IA auquel la plupart des organisations d'ingénierie sont confrontées seulement maintenant. Les agents qui génèrent des requêtes pull en quelques minutes attendent toujours sur des pipelines de validation conçus pour la cadence humaine, et chaque minute de cette attente est multipliée par chaque agent travaillant en parallèle.
La leçon de la refonte de Linear est que le goulot d'étranglement est mobile, mais uniquement grâce à l'accumulation peu glamour de nombreux petits correctifs - des coureurs plus rapides, des vérifications de type moins chères, des règles de charpie au niveau de la syntaxe, des récupérations plafonnées, des extractions résilientes, des images prédéfinies - plutôt que n'importe quelle solution miracle.
---
Gardez une longueur d'avance sur l'IARecevez les dernières actualités, analyses et avancées en matière d'IA, le tout en un seul endroit.
Lire plus d'actualités sur l'IA →