Livraison continue boostée grâce à Git

Maintenant que Git a résolu le problème du merge, les workflows de création de branches sont beaucoup plus intéressants.

Sarah Goff-Dupont Sarah Goff-Dupont

Nous avons tous entendu le dicton « méfiez-vous du code écrit par une seule personne » et nous connaissons les avantages du développement logiciel en équipe : vous travaillez avec des personnes qui ont des modes de pensée, des expériences et des parcours différents... et lorsque vous mettez ces différences au service du problème que vous essayez de résoudre, vous obtenez de meilleurs logiciels. Le logiciel est plus facile à mettre à jour, il est de meilleure qualité et, en fin de compte, il sert mieux l'utilisateur.

Collaboration entre équipes | CI/CD Atlassian

Mais nous savons également autre chose : le développement en équipe peut être très brouillon !

Vous essayez de comprendre sur quelles parties du code tout le monde travaille, de vous assurer que les changements n'entrent pas en conflit, de trouver les défauts avant vos clients et de tenir toutes les personnes liées au projet informées de son avancement. Il s'avère que chacun de ces problèmes est résolu soit par la création de branches Git, soit par la livraison continue.

J'espère vous convaincre qu'en combinant les deux (et peut-être en ajoutant quelques outils super cool juste pour le plaisir), vous obtiendrez une recette surpuissante pour réussir.

La puissance des workflows basés sur les branches 

À vrai dire, Git en soi n'est pas si parfait pour la livraison continue. Ce sont plutôt les workflows de création de branches qui sont parfaits pour la livraison continue et Git qui est parfait pour les workflows de création de branches. En plus d'être le meilleur allié de la livraison continue, un workflow « branch-and-merge » vous permet de vous attaquer à des bugs complexes, d'essayer de nouvelles technologies ou de commencer à programmer une nouvelle fonctionnalité à partir de rien sans risquer que vos changements empêchent vos coéquipiers de poursuivre leurs propres tâches.

Diagramme des workflows de base | CI/CD Atlassian

Bien sûr, Subversion et d'autres systèmes traditionnels de contrôle de version vous permettent aussi de créer des branches. Mais arrêtons-nous un instant pour découvrir le double maléfique de la création de branches : le merge.

Les systèmes traditionnels de contrôle de version comme Subversion ne sont tout simplement pas très bons lorsqu'il s'agit de suivre les versions de fichiers qui se trouvent sur différentes branches. Et lorsque vient le moment du merge, Subversion doit souvent s'arrêter pour demander son chemin. (Vous savez... ce petit pop-up demandant « Voulez-vous cette ligne ou celle-ci dans la version mergée ? ») Le fait qu'une telle interaction humaine soit nécessaire pendant les merges incite les équipes à instaurer un gel du code afin que la personne qui effectue le merge ne soit pas perturbée par de nouveaux changements survenant sur l'une des branches. Et les gels du code sont coûteux : ils représentent des moments peu productifs.

Git, en revanche, est très efficace pour suivre les changements apportés aux différentes versions de fichiers qui se trouvent sur différentes branches et il sait toujours à quoi ressemblait l'ancêtre commun de ce fichier. C'est un peu comme si Git disposait de son propre GPS, qui lui permet de naviguer entre les merges sans avoir à constamment s'arrêter pour vous demander son chemin.

Avec Git, vous êtes libre d'exploiter la puissance des branches d'une manière qui ne serait pas possible avec Subversion. Les frais liés à la création de branches et à leur merge sont si minimes que même les branches qui ne vivent qu'un ou deux jours sont non seulement réalisables, mais également profitables.

Bon, très bien. Mais qu'est-ce qui rend au juste la création de branches si puissante pour la livraison continue ?

Grâce aux branches, la branche principale reste propre et peut être mise à disposition

Nous avons constaté que les branches éphémères étaient un excellent moyen pour les développeurs de collaborer sur un projet ou une fonctionnalité sans se marcher sur les pieds. Mais, plus important encore pour la livraison continue, le fait d'isoler toutes les tâches en cours sur les branches de développement permet de maintenir la branche principale et toutes les branches de version stables à un état propre. Vous pouvez ainsi effectuer des livraisons quand bon vous semble.

Cela signifie que vous pouvez exécuter toute votre batterie de tests automatisés sur les branches de développement afin que les développeurs reçoivent des signaux forts sur la qualité de leur code et puissent décider en toute confiance quand leurs changements sont prêts à être mergés. (Si vous n'avez pas encore opté pour les tests automatisés, consultez ce billet de RebelLabs dans lequel vous retrouverez une discussion ludique et des recettes pour écrire vos premiers tests unitaires.)

Il s'agit également d'utiliser les pull requests de Git comme une forme de revue de code afin que l'ensemble de votre équipe ait confiance en la maintenabilité du code et son interopérabilité avec les autres parties de la base de code. Oui, le travail initial est plus important que ce que prévoient les modèles de livraison traditionnels. Et oui, ça en vaut la peine.

Le succès de la livraison continue dépend de la propreté de vos branches de version.

À titre d'exemple, toutes les équipes de développement d'Atlassian ont un accord selon lequel aucun commit n'est effectué directement sur la branche principale ou sur les branches stables. Tout le monde travaille sur des branches. En fait, nous sommes tellement favorables à la création de branches que nous avons pris l'habitude de créer une branche distincte pour chaque ticket Jira auquel nous nous attaquons, mais nous y reviendrons plus tard.

Quoi qu'il en soit, cela signifie que chacun est libre de faire autant de tests et de dégâts qu'il le souhaite sur ses branches ! La branche principale reste dans un état qui nous permet d'effectuer des livraisons et à partir duquel vous pouvez créer des branches sans hériter d'un tas de code non fonctionnel. C'est une belle victoire pour la livraison continue et la productivité générale des développeurs (sans parler de leur moral).

Les branches vous aident à accepter les contributions provenant de l'extérieur de l'équipe

La facilité avec laquelle Git permet de créer des branches, et notamment de forker des dépôts entiers, simplifie la prise en compte des contributions de personnes extérieures à l'équipe immédiate : sous-traitants, développeurs d'entreprises partenaires et d'autres unités commerciales, etc. Inutile de perdre le sommeil parce que vous vous inquiétez de voir des personnes qui ne connaissent pas votre base de code apporter bon gré mal gré des changements à des branches critiques et compromettre votre capacité à livrer du nouveau code.

Là encore, des tests automatisés rigoureux sur leurs branches ou leurs dépôts forkés sont la clé d'une collaboration fructueuse. Vous voudrez examiner les résultats de leurs builds et de leurs tests avant d'approuver tout merge dans votre ligne de code principale.

Conseil de pro : les gestionnaires de dépôts comme Bitbucket vous permettent d'utiliser des hooks Git pour appliquer les normes de qualité. Par exemple, vous pouvez définir une règle selon laquelle tous les builds de branches doivent être réussis avant qu'une demande de pull ne puisse être acceptée et mergée.

Branches bien faites = suivi de projet limpide

La tendance actuelle : créer une branche de développement pour chaque story, correction de bug ou tâche (c'est-à-dire chaque ticket Jira) que vous implémentez. Chez Atlassian, nous avons adopté ce modèle de branche par ticket il y a quelques années, et nous ne l'avons pas regretté ! Il est même devenu populaire auprès de nos clients.

La création d'une branche pour chaque ticket facilite la sélection manuelle des changements à envoyer en production ou à regrouper dans une version. Puisque vous n'empilez pas les changements sur la branche principale, vous pouvez choisir ce qui entre dans celle-ci et quand. Vous pouvez livrer le MVP d'une epic accompagné d'une seule fonctionnalité souhaitable, au lieu d'attendre que toutes les fonctionnalités souhaitables soient prêtes. Vous pouvez également livrer une seule correction de bug, et le faire dans le cadre d'une livraison normale. Même si la correction est urgente, inutile d'avoir recours à un tour de passe-passe, comme annuler d'autres changements qui ne sont pas encore prêts à être livrés juste pour que ce seul changement puisse avoir lieu.

Et cette facilité à livrer un seul changement du code est l'essence même de la livraison continue.

Non seulement cette approche permet d'éviter que du code non approuvé n'apparaisse dans la branche principale, mais lorsque vous incluez la clé du ticket Jira et le nom ou les initiales du développeur dans le nom de la branche, l'état d'avancement du développement de chaque ticket est parfaitement clair.

Capture d'écran des commits de dépôts Git par Bitbucket | CI/CD Atlassian

Regardez la convention de dénomination utilisée dans l'image ci-dessus : il s'agit de la clé unique du ticket Jira en cours d'implémentation, suivie d'une description courte et parfaitement intelligible de l'objet de ce ticket. Ainsi, en tant que responsable des livraisons ou autre partie prenante, vous pouvez consulter le dépôt présenté ci-dessus et savoir d'un seul coup d'œil que la user story suivie par AMKT-13952 est prête pour la livraison, car vous pouvez voir qu'elle a été mergée dans la branche principale. Voilà comment vous obtenez une traçabilité sans effort manuel !

Alors, comment fonctionne le workflow de livraison continue associé à Git ?

Heureuse que vous me posiez la question ! Je vais expliquer dans ce billet les grandes lignes de ce processus, car d'autres articles sur ce site abordent chaque phase de manière plus approfondie.

  • Créez une branche pour le ticket sur lequel vous allez travailler. Incluez la clé du ticket Jira dans le nom de la branche pour que l'on sache clairement à quoi elle est destinée. Et si vous utilisez d'autres outils Atlassian comme Bitbucket ou Bamboo, ils reprendront ce ticket et créeront des liens entre le ticket, votre branche, tous vos commits, vos builds, vos pull requests et vos déploiements liés à ce ticket. En d'autres termes, les clés de ticket sont magiques.
  • Effectuez vos changements sur la branche. Vous êtes dans votre propre petit monde ici, alors soyez fous. Essayez de nouvelles choses. Cassez des trucs. Cela n'a aucune importance, car vous allez également...
  • Passer votre branche en intégration continue (CI). (Bamboo le fait automatiquement pour vous, d'ailleurs.) C'est à vous et à votre équipe de décider si vous voulez exécuter des tests spécialisés comme des tests de charge ou des tests de bout en bout basés sur l'interface utilisateur, et si vous voulez déclencher automatiquement un test chaque fois que vous apportez des changements à votre branche. Les équipes Atlassian exécutent généralement les tests au niveau des unités et de l'intégration sur les branches de développement. Elles laissent le développeur choisir la fréquence d'exécution de ces tests afin de préserver les ressources de build et de s'assurer que la file d'attente n'est pas inutilement encombrée.
  • Mettez régulièrement à jour votre branche avec la dernière version de la branche principale. Vous pouvez utiliser un rebase ou un commit de branche pour ce faire. C'est vous qui décidez. (Mais n'oubliez pas de ne pas faire de rebase sur une branche que vous partagez avec d'autres développeurs. Cela pourrait les mettre en rogne.) De toute façon, vous tomberez sur des conflits d'intégration avant de merger, ce qui permet de garder la branche principale propre.
  • Créez un pull request lorsque vous êtes prêt à merger en amont. Cela signifie que l'implémentation est terminée, que vous avez fait un pull des changements de vos coéquipiers et résolu tous les conflits qui en résultent, et que tous les tests de votre branche ont réussi.
  • Mergez en amont et déployez quand bon vous semble. Certaines équipes préfèrent livrer automatiquement chaque changement dès qu'il est mergé dans la branche principale et que tous les tests ont réussi. Il s'agit du modèle de déploiement continu. D'autres équipes préfèrent décider elles-mêmes quels changements livrer et à quel moment. C'est à vous et à votre équipe de décider.

Automatisation de la CI Git | CI/CD Atlassian

Voilà, vous avez compris. Les workflows de création de branches simplifient la livraison continue, et Git élimine les maux de tête liés à la création de branches. Poursuivez votre lecture pour découvrir comment configurer votre dépôt Git pour qu'il soit compatible avec la livraison continue et comment mettre toutes ces idées en pratique à l'aide de vos outils Atlassian. Rendez-vous sur la page suivante !