Le travail qui commence après le merge

6 min de lecture

Également disponible en English, Español, Português, 简体中文, 日本語, 한국어, Deutsch, ไทย, Tiếng Việt et Te Reo Māori.

Le merge était autrefois la ligne d'arrivée. Vous ouvriez une pull request, quelqu'un la relisait, elle était intégrée, et le changement était terminé. Les agents de codage ont discrètement déplacé cette ligne. Lorsqu'un agent prend en charge une issue Linear, écrit le code et ouvre une merge request pendant que vous êtes en réunion, le merge n'est plus la fin du travail — c'est le début de tout ce que ce merge touche.

Le merge n'est plus la ligne d'arrivée

Un merge n'est jamais qu'un simple merge. Chaque changement s'appuie sur les systèmes qui l'entourent : l'issue qui devrait maintenant être fermée, la documentation qui décrit depuis ce matin quelque chose de légèrement faux, la CI un peu plus rouge qu'hier, les notes de version que personne n'a encore rédigées, la conversation de support qui attend toujours un correctif en réalité livré il y a plusieurs heures.

Lorsqu'un ingénieur livrait quelques changements par semaine, ce travail de suivi tenait dans les interstices. Vous fermiez l'issue pendant que la pull request était encore ouverte ; vous vous souveniez de la documentation parce que vous veniez juste de toucher au code. Lorsqu'un agent — ou toute une flotte d'agents — livre de nombreux changements par jour, ces interstices débordent. Le code n'est plus le goulot d'étranglement. Tout ce qui se trouve en aval du code l'est.

Le modèle de maintenance n'a pas changé

Le développement est devenu plus rapide. La maintenance non. Les outils que nous utilisons pour garder un projet cohérent restent en grande partie manuels, et dépendent toujours d'une personne qui se souvient d'y recourir au bon moment :

  • Une merge request est intégrée, mais l'issue Linear qu'elle résout reste ouverte.
  • La documentation décrit toujours l'ancien comportement, et personne ne sait vraiment sur quelle page.
  • La CI échoue par intermittence depuis une semaine et tout le monde a appris à l'ignorer.
  • Un feature flag vieux de trois mois n'a ni responsable ni date de suppression.
  • Le support répond à un ticket avec une solution de contournement pour un bug corrigé mardi.
  • Quelqu'un demande ce qui est sorti dans cette version, et la réponse honnête est « laissez-moi consulter le git log ».

Rien de tout cela n'est nouveau, et rien de tout cela n'est vraiment un problème lié à l'agent. C'est l'entropie ordinaire d'un projet logiciel. L'agent ne fait qu'accélérer le rythme jusqu'à ce que le système informel qui absorbait autrefois ces tâches ne suive plus.

Le nettoyage sur demande ne passe pas à l'échelle

La solution évidente est de demander à l'agent de nettoyer aussi, et vous le pouvez. Mentionnez @taskgoblin sur la merge request et demandez-lui de mettre à jour la documentation, de fermer l'issue, de rédiger la note de version. Cela fonctionne. Mais cela dépend de la ressource la plus rare de toute la boucle : une personne qui se souvient de le demander, à chaque fois, au bon moment.

La maintenance n'est pas une tâche ponctuelle ; c'est une boucle. « Vérifier que la documentation est à jour » n'est pas quelque chose que l'on fait une seule fois. « S'assurer que les issues mergées sont fermées » n'est pas quelque chose que l'on fait une seule fois. Tout ce qui attend qu'une personne remarque qu'il est temps d'exécuter la boucle sera exécuté de façon incohérente — parce que les gens remarquent les choses de façon incohérente, surtout quand tout l'intérêt de l'agent était justement de ne plus avoir à garder tout cela en tête. Le nettoyage sur demande déplace le travail vers l'agent, mais laisse la planification de ce travail exactement là où elle était : sur vous.

Pourquoi nous avons créé les Loops

Une exécution d'agent normale est déclenchée par un événement — l'assignation d'une issue, une mention, une nouvelle pull request. Un Loop est déclenché par le temps. Vous donnez à l'agent une consigne permanente et une cadence — chaque matin de jour ouvré, chaque lundi, le premier du mois — et il s'exécute lui-même, dans un sandbox, avec les mêmes outils et le même accès que n'importe quelle autre exécution.

La consigne constitue la tâche tout entière, et les bonnes consignes se lisent comme une fiche de poste plutôt que comme un vœu : quoi regarder, quel dépôt, quoi faire, quoi ne pas faire et — la partie qui rend son exécution sans surveillance sûre — quoi faire lorsqu'il n'y a rien à faire, à savoir rien.

Chaque jour ouvré à 09h00, examinez les merge requests fusionnées au cours du dernier jour dans group/repo, et fermez toute issue Linear qu'elles résolvent et qui est encore ouverte. S'il n'y en a aucune, ne faites rien.

C'est une boucle de maintenance dotée d'un responsable. Elle n'attend pas que vous vous en souveniez. Comme une exécution planifiée est une exécution d'agent complète, elle peut aller jusqu'au bout : non seulement signaler la documentation obsolète, mais ouvrir la merge request qui la corrige ; non seulement remarquer que des issues mergées sont restées ouvertes, mais les fermer — puis rendre compte là où vous le verrez réellement, en commentaire sur l'issue Linear, en message dans le canal Slack que vous avez indiqué, ou par e-mail s'il n'existe pas de meilleur endroit.

Et comme elle réutilise tout ce qu'une exécution normale fait déjà, les cas délicats sont pris en charge. Le temps manqué est ignoré plutôt que rattrapé, de sorte qu'un planificateur resté hors service pendant une heure ne se réveille pas en vous déclenchant une centaine d'exécutions de rattrapage. Chaque exécution dispose de son propre budget et de ses propres garde-fous. Nous fournissons un ensemble de modèles de départ précisément pour ces boucles — garder les issues et les merges synchronisés, surveiller une CI restée rouge trop longtemps, traquer les feature flags qui ont survécu à leur responsable, rédiger les notes de version au fil des livraisons — car les boucles utiles sont les mêmes dans la plupart des équipes. Vous n'avez plus qu'à renseigner votre dépôt et votre canal ; les garde-fous sont déjà écrits.

Le rôle de l'ingénieur monte d'un niveau

Une inquiétude sous-tend tout cela : automatiser la maintenance reviendrait à automatiser le jugement. Ce n'est pas le cas. Cela fait monter le jugement d'un niveau. Lorsque les boucles s'exécutent d'elles-mêmes, vous cessez d'être la personne qui se souvient de fermer les issues et devenez la personne qui décide quelles boucles doivent exister, quels sont leurs garde-fous, et ce que signifie « terminé » pour chacune d'elles. Vous relisez la consigne permanente au lieu d'exécuter la corvée vous-même.

C'est, de toute façon, la version la plus expérimentée de ce métier. L'agent a rendu l'écriture du code peu coûteuse ; ce qui reste à faire, c'est décider de ce qui doit être vrai à propos du système et veiller à ce que cela le reste. Les Loops sont le moyen de garder cela vrai sans tout porter en tête — l'agent crée le travail, et une boucle permanente l'entretient.