C'est quoi le trunk based development ? Guide pour SRE
Résumé
Le trunk based development consiste à intégrer chaque changement dans une branche partagée au moins une fois par jour, en gardant cette branche déployable. Il exige une CI rapide, des tests fiables, une revue courte et un moyen de livrer du code incomplet, généralement avec des feature flags ou du branch by abstraction. Le modèle réduit les conflits et les grosses revues, mais il crée une dette de flags à gérer. Les métriques DORA permettent de vérifier s'il progresse.
C'est quoi le trunk based development ? C'est un modèle de branches où chaque développeur intègre ses changements dans une seule branche partagée, le trunk (souvent main), au moins une fois par jour, et où cette branche reste déployable à tout moment. À 3h du matin, la différence se voit : une branche de release qui ne merge plus, quarante commits vieux de trois semaines et des fichiers que tout le monde a touchés. Ce guide s'adresse aux platform engineers qui connaissent déjà Git. Il décrit ce que le modèle exige, ce qu'il vous évite et l'endroit où il casse discrètement.
Ce que le trunk based development exige, en pratique
Réduisez la définition à ses contraintes. Tous les développeurs intègrent dans une seule branche. Toute autre branche vit quelques heures, pas des semaines. Le trunk se construit et passe ses tests à chaque commit, donc il peut partir en production à la demande.
La page capacités de DORA donne des chiffres : trois branches actives ou moins dans le dépôt, des merges vers le trunk au moins une fois par jour, aucun gel de code, et un cycle de build et de test de quelques minutes. Ces chiffres sont le fond du sujet. Le modèle est un budget de boucle de feedback, pas une préférence de style pour les branches.

Les petites équipes committent parfois directement sur le trunk. Les plus grandes utilisent des branches courtes et des pull requests pour la revue et les vérifications de build, mais jamais pour retenir du travail hors de l'intégration. La référence trunkbaseddevelopment.com décrit les deux modes et cite Google, qui fait travailler environ 35 000 développeurs sur un seul trunk, dans un monorepo.
Pourquoi les branches longues échouent à une date prévisible
Une branche de fonctionnalité est un prêt. Les intérêts, ce sont les conflits de merge, et ils s'accumulent à chaque commit qui atterrit sur main pendant votre absence. Plus la branche vit, plus le diff grossit, et plus personne ne le relit vraiment.
Voici ce que ça fait à votre taux d'échec des changements. Un merge de 2 000 lignes reçoit un coup d'œil et un approve. Un merge de 60 lignes se lit. Les relecteurs ne sont pas paresseux, ils rationnent leur attention. Les petits lots sont le seul mécanisme qui passe à l'échelle pour garder une revue de qualité.
Le second coût reste invisible jusqu'à la release. Deux branches qui passent chacune la CI peuvent quand même se casser mutuellement au moment de se rencontrer. Vous le découvrez à l'intégration, au pire moment possible, avec une deadline accrochée.
Passer au trunk sans les pratiques de soutien, c'est le chemin le plus court vers un retour aux branches de fonctionnalité dans le trimestre. Quatre choses doivent exister d'abord.
Un build et des tests qui tournent en moins de dix minutes environ. Si la CI prend 40 minutes, les développeurs regroupent leurs changements, et ce regroupement annule le modèle.
Des tests qui échouent pour de vraies raisons. Une suite instable apprend aux gens à relancer le pipeline et à merger quand même.
Une revue de code rapide et honnête. DORA cite la revue lourde et asynchrone comme obstacle fréquent, parce qu'elle pousse à regrouper le travail.
Un moyen de livrer du travail incomplet sans risque. C'est la section suivante.
Sans l'un de ces éléments, le trunk devient l'endroit où les casses s'accumulent, au lieu de celui où on les attrape.
Merger du travail inachevé sans le livrer, et payer la dette des flags
C'est la question que pose chaque sceptique, et la réponse est ennuyeuse : vous découplez le déploiement de la mise en production. Le code arrive en prod éteint, et un flag décide qui le voit.
// checkout.ts
import { flags } from "./flags";
export async function renderCheckout(user: User) {
if (await flags.isEnabled("new-payment-flow", { userId: user.id })) {
return renderNewPaymentFlow(user); // mergé sur trunk, éteint par défaut
}
return renderLegacyCheckout(user);
}Le nouveau parcours est mergé dès le premier jour, derrière un flag désactivé. Vous l'activez pour les utilisateurs internes, puis pour 1 %, puis pour 10 %, avec une porte SLO à chaque palier. Si le taux d'erreur dépasse le budget, le flag repasse à off et le changement est annulé dans les faits, sans redéploiement. Les équipes qui évaluent un service de flags hébergé commencent souvent par LaunchDarkly, mais le motif fonctionne avec n'importe quel fournisseur ou avec un store de configuration maison.
La seconde technique est le branch by abstraction, pour les gros refactorings. Vous introduisez une interface, vous faites passer les appelants par elle, vous construisez la nouvelle implémentation derrière, puis vous basculez. Pas de branche longue, pas de merge big bang.

Personne dans les conférences n'aime en parler : chaque flag ajouté est une condition en production que quelqu'un doit retirer un jour. On a vu des équipes de 80 ingénieurs porter plusieurs centaines de flags périmés, chacun une branche de code que personne ne peut tester à fond. Traitez les flags comme éphémères, par contrat. Donnez à chacun un propriétaire et une date d'expiration à la création, alertez sur les flags plus vieux que leur expiration, et supprimez le chemin de code mort dans la même pull request que celle qui retire le flag.
Le risque combinatoire est réel aussi. Dix flags booléens indépendants donnent 1 024 configurations possibles, et vous ne les testerez jamais toutes. Gardez peu d'interactions entre flags, et séparez les flags de release des bascules opérationnelles durables, comme les kill switches.
Les stratégies de release au-dessus du trunk
Il existe deux façons courantes de couper une release depuis le trunk, et aucune n'exige de branche longue.
Release directement depuis le trunk. Chaque commit vert est un candidat. Les bugs se corrigent en avant, par un nouveau commit, et non en patchant une ancienne branche. C'est adapté aux équipes qui ont de solides tests automatisés et des déploiements rapides.
Couper une branche de release juste à temps. Vous branchez depuis un commit du trunk connu comme bon, vous le durcissez, vous livrez, puis vous supprimez la branche. Les correctifs atterrissent d'abord sur le trunk et sont reportés ensuite par cherry-pick. C'est adapté aux équipes avec des portes de release lentes ou une validation réglementaire.
Le choix dépend de votre temps de détection. Si vous remarquez un mauvais déploiement en cinq minutes et que vous revenez en arrière en deux, corrigez en avant. Si votre temps moyen de détection est d'une heure, une branche de release vous donne un point d'appui.

L'observabilité est l'autre moitié du contrat
Le trunk based development augmente votre fréquence de déploiement, donc le nombre de moments où quelque chose peut casser. Le modèle ne tient que si vous voyez une régression en quelques minutes après un merge. Il vous faut des taux d'erreur, des percentiles de latence et de la saturation rattachés à une release précise, pas un dashboard que quelqu'un consulte le lundi.
Un test utile : après un merge, pouvez-vous répondre « ce changement a-t-il bougé le p99 ou le taux d'erreur ? » sans ouvrir cinq onglets ? Si non, vous n'êtes pas prêt à merger dix fois par jour.
Quelle que soit votre stack, l'exigence est la même : des marqueurs de déploiement sur vos graphes, des alertes de burn rate SLO et un chemin de revert qu'une personne fatiguée peut exécuter à 3h du matin sans réfléchir.
Trunk based development, GitFlow ou GitHub Flow : la différence qui compte
Ces trois modèles se confondent souvent. Séparez-les par une seule propriété : combien de temps le travail reste hors de la branche partagée.
GitFlow garde une branche develop, des branches de fonctionnalité, de release et de hotfix. Le travail peut rester isolé pendant des semaines. Il a été conçu pour des releases versionnées et planifiées, et ça se voit quand vous voulez déployer dix fois par jour.
GitHub Flow est proche du trunk : branches courtes, pull requests, merge sur
main, déploiement. La différence que fait le site de référence tient surtout à l'origine des releases.Le trunk based development est le plus strict des trois sur la durée de vie des branches. Il suppose des flags ou du branch by abstraction pour tout ce qui ne peut pas partir dans un changement petit et unique.
Si votre équipe fait déjà du GitHub Flow avec des branches qui vivent moins de deux jours, vous êtes plus proche du trunk que vous ne le pensez. L'écart porte en général sur la discipline des flags et la latence de revue, pas sur l'outillage.
Quand le trunk based development est le mauvais choix
Passez-le, ou repoussez-le, dans quelques cas. Soyez honnête sur celui dans lequel vous êtes.
Votre suite de tests prend une heure et vous ne pouvez pas la paralléliser. Vous regrouperez vos changements, et le regroupement casse le modèle.
Vous livrez des artefacts versionnés à des clients qui restent sur d'anciennes versions pendant des années. Il vous faut des branches de maintenance. C'est légitime, et vous pouvez quand même intégrer chaque jour sur le trunk.
Vous n'avez pas de système de flags et aucune envie d'en construire un. Le travail à moitié fini fuira dans les releases.
Votre équipe ne fait pas confiance au build. Corrigez les tests d'abord, le trunk ne réglera rien à votre place.
Le trunk based development ne garantit rien non plus. La constatation de DORA repose sur des données de 2016 et 2017 et montre une corrélation : les équipes qui suivent ces pratiques ont de meilleures performances de livraison et opérationnelles. Cela ne dit pas que renommer vos branches répare votre pipeline.
Comment démarrer sans migration big bang, en mesurant d'abord
N'annoncez pas une politique. Mesurez d'abord, puis réduisez.
Instrumentez les métriques DORA avant de commencer, sinon vous argumenterez au ressenti après coup. La fréquence de déploiement et le délai de mise en production des changements réagissent en premier, parce que de plus petits lots traversent le pipeline plus vite. Le taux d'échec des changements et le temps de restauration suivent, et dépendent de votre observabilité et de votre chemin de revert plus que du modèle de branches seul. Ne transformez pas ces chiffres en bulletin de notes individuel : ils décrivent un système. Quand le délai monte, regardez la file de revue et la durée de la CI avant de regarder les personnes.
Relevez la durée de vie actuelle de vos branches et la taille médiane de vos pull requests. Ce sont vos chiffres de référence.
Fixez un plafond, par exemple aucune branche de plus de deux jours, et rendez-le visible sur un dashboard.
Corrigez la partie la plus lente de la CI. Si le build prend 30 minutes, rien d'autre ne compte encore.
Introduisez un flag pour une vraie fonctionnalité. Livrez-la éteinte, puis retirez le flag dans le sprint.
Supprimez les gels de code en dernier, une fois que votre chemin de revert a été éprouvé en conditions réelles.
Refaites le point dans un mois. Les chiffres qui bougent en premier sont en général la taille des pull requests et le délai de merge. Le taux d'échec des changements prend plus de temps, et il peut même empirer avant de s'améliorer, parce que vous voyez enfin les casses plus tôt.
Que dira votre post-mortem ? C'est la bonne question avant de shipper. Si votre dernier incident venait d'un merge que personne n'a pu relire, d'une branche divergée pendant trois semaines ou d'une release qui regroupait quarante changements, vous savez déjà où la dette arrive à échéance. Regardez vos trois derniers incidents : combien impliquaient une intégration tardive et volumineuse ? Ce nombre est votre argumentaire.