Trois hooks Git pour une intégration continue

Découvrez comment les hooks Git appliquent des builds propres sur les branches de fonctionnalités, et plus encore.

Sarah Goff-Dupont Sarah Goff-Dupont

Si vous utilisez Git depuis un certain temps, vous avez probablement entendu parler des hooks Git. Peut-être les avez-vous même déjà utilisés. Les hooks Git sont exceptionnels dans le contexte de l'intégration continue. Dans cet article, je vais donc examiner trois cas d'usage et vous indiquer des hooks prêts à l'emploi que vous pouvez ajouter à votre workflow. Si vous débutez avec les hooks Git, pas de souci : nous commencerons par les bases.

Comprendre les hooks Git

Les hooks constituent le mécanisme natif de Git pour déclencher des scripts personnalisés avant ou après des opérations, tels qu'un commit et un merge. Considérez-les comme le système de plug-in de Git. Si vous regardez dans le répertoire .git de n'importe quel dépôt Git, vous verrez un sous-répertoire intitulé « hooks » qui contient un ensemble d'exemples de scripts de hook.

.git/hooks

L'installation de hooks Git est simple et bien documentée, donc je n'aborderai pas le sujet.

Il existe deux grandes classes de hooks : côté client et côté serveur. Les hooks côté client s'exécutent sur votre poste de travail local, tandis que les hooks côté serveur s'exécutent sur votre serveur Git.

Vous pouvez également catégoriser les hooks avec le préfixe pre- ou post-. Les hooks pre-receive sont invoqués avant certaines opérations Git et peuvent annuler une opération si nécessaire. Ils agissent comme des videurs qui gardent votre dépôt derrière une corde en velours, empêchant ainsi les membres de l'équipe de commiter un code erroné. Les hooks post-receive s'exécutent après la fin d'une opération et ne permettent donc pas de l'annuler. Au lieu de cela, les hooks post-receive automatisent des éléments de votre workflow de développement.

Utiliser des hooks #Git, c'est comme avoir de petits robots à votre service pour réaliser tous vos souhaits (mouah-ah-ah !).

Les hooks Git automatisent des actions telles que

  • Vérifier que vous avez inclus la clé de ticket Jira associée dans votre message de commit
  • Appliquer des conditions préalables au merge
  • l'envoi de notifications au groupe de discussion de votre équipe ;
  • la configuration de votre espace de travail après le passage à une autre branche.

Appliquer des buils propres sur des branches de fonctionnalité

Les hooks pré-réception côté serveur complètent efficacement l'intégration continue, car ils peuvent empêcher les développeurs de pusher du code dans la branche principale, sauf si le code remplit certaines conditions (ce sont en quelque sorte des ninjas d'élite qui le protègent du mauvais code).

Les développeurs sont généralement assez consciencieux pour ne pas merger dans la branche principale lorsque leur branche présente des tests incomplets. Mais ils oublient parfois de vérifier. En outre, lorsque nous partageons une branche avec d'autres personnes, des changements supplémentaires sont parfois effectués depuis la dernière vérification du build de branche… ce sont des choses qui arrivent.

Vous pouvez donc ajouter un hook côté serveur qui recherche les merges entrants dans la branche principale. Lorsqu'il en trouve un, le script vérifie le dernier build sur votre branche, et si des tests ont échoué, le merge est rejeté. Tim Petterson, mon collègue et défenseur des développeurs Atlassian, a écrit un script de hook à cet effet, conçu pour fonctionner avec Bamboo, et l'a mis à disposition sur Bitbucket. Vous pouvez le récupérer, le personnaliser et l'ajouter à votre dépôt.

Protéger votre couverture de code difficilement obtenue

Beaucoup d'équipes éprouvent des difficultés à maintenir la couverture de code. Souvent, elles doivent couvrir rétroactivement leur base de code avec des tests. De plus, il est réellement frustrant de voir que la couverture durement obtenue disparaît à mesure que d'autres fonctionnalités sont ajoutées, sans tests pour les soutenir. Tim a donc également écrit un hook pré-réception côté serveur pour protéger la branche principale contre une diminution de la couverture de code.

Ce hook recherche également les merges entrants dans la branche principale. Il appelle ensuite le serveur d'intégration continue pour vérifier la couverture de code actuelle sur la branche principale, ainsi que la couverture sur la branche. Si la branche présente une couverture inférieure, le merge est rejeté.

La plupart des serveurs d'intégration continue n'exposent pas les données de couverture de code via leurs API distantes, de sorte que le script extrait le rapport de couverture de code. Pour ce faire, le build doit être configuré pour publier le rapport en tant qu'artefact partagé, à la fois sur la branche principale et sur le build de la branche. Une fois le dernier rapport de couverture publié, vous pouvez le récupérer depuis la branche principale en appelant le serveur d'intégration continue. Pour la couverture de branche, vous récupérez le rapport à partir du dernier build ou pour les builds liés au commit mergé.

Soyons clair, tout cela suppose que vous exécutiez déjà une couverture de code. Le hook ne peut pas l'exécuter comme par magie, il recherche simplement les données de couverture dans les résultats de votre build. Il fonctionne également avec Bamboo par défaut, ainsi que Clover (outil de couverture de code d'Atlassian pour Java et Groovy). Mais il peut être personnalisé pour s'intégrer à n'importe quel serveur de build ou outil de couverture de code.

Vérification de l'état des builds de branche

Les vrais amis ne vous laisseront pas faire un check-out des branches non fonctionnelles.

Voici l'occasion d'utiliser les hooks Git côté client : un script de hook post-checkout (également écrit par Tim) qui expose l'état du build de branche directement dans votre fenêtre de terminal. Le script obtient le numéro de révision d'en-tête de la branche à partir de votre copie locale, puis interroge le serveur d'intégration continue pour voir si cette révision a été créée et, si oui, si le build a réussi.

Supposons que vous souhaitiez créer une branche à partir de la branche principale. Ce hook vous indiquera si le commit head sur la branche principale a été créé avec succès, ce qui signifie qu'il s'agit d'un commit « sûr » pour créer une branche de fonctionnalité. Autre cas de figure : imaginons que le hook indique que le build pour cette révision a échoué, mais que le wallboard de l'équipe montre un build fonctionnel pour cette branche (ou vice versa). Cela signifie que votre copie locale est obsolète. Ce sera à vous de décider si vous voulez faire un pull des mises à jour ou continuer de travailler sur la copie locale dont vous disposez.

L'utilisation de ce hook a épargné d'innombrables maux de tête aux développeurs Atlassian. Si vous n'arrivez pas à convaincre votre équipe d'adopter les hooks côté serveur décrits ci-dessus, installez au moins celui-ci sur votre poste de travail local. Vous ne le regretterez pas.

Tous les hooks Git d'intégration continue que j'ai présentés fonctionnent avec Bamboo, Clover, et Bitbucket par défaut. Gardez toutefois à l'esprit que les hooks Git sont neutres vis-à-vis des fournisseurs. Vous pouvez donc les personnaliser pour fonctionner avec la suite de votre choix. L'automatisation pour le bénéfice de tous !