Quantcast
Channel: Publicis Sapient Engineering – Engineering Done Right
Viewing all articles
Browse latest Browse all 1865

Gitflow : est-il le workflow dont j’ai besoin ?

$
0
0

Introduction

En général, on ne fait pas trop attention au gestionnaire de sources (SCM) utilisé dans nos projets, mais il est toujours là. Bien connaitre les possibilités fournies par son SCM est très important pour mener à bien nos projets. Dans cet article nous allons voir les particularités de GitFlow, un workflow Git qui mérite le détour et qui fait débat.

Avant de te préoccuper de la route, inquiète-toi du compagnon

Dicton oriental

Nous, les développeurs, quelle que soit notre spécialité, avons toujours un ami qui nous accompagne pour le meilleur et pour le pire, jusqu’à ce que la mort – ou le changement de projet – nous sépare : le gestionnaire de sources. Notre SCM est le gardien du bien le plus précieux d’un projet, notre code source, et est la pierre angulaire sur laquelle le travail en équipe va reposer. C’est pour cela que bien connaitre son SCM est vital pour mener à bien nos projets. Néanmoins, toutes les équipes ou organisations n’ont pas les mêmes besoins.

  • Doit-on gérer plusieurs versions de notre application en même temps ?
  • Une fonctionnalité peut-elle être développée par plusieurs personnes au même moment ?
  • A-t-on une plateforme CI/CD (Continuous Integration / Continuous Deployment) à notre disposition pour tester rapidement les évolutions de notre application ?

Pour donner une réponse aux spécificités de chaque projet, la communauté des utilisateurs de Git propose plusieurs workflows que nous pouvons adapter à nos besoins. Dans cet article, nous allons approfondir l’un d’entre eux : Gitflow. Dans un premier temps, on introduira théoriquement le workflow pour ensuite creuser et essayer de cerner ses avantages et inconvénients (qui sont vite oubliés dans la plupart des articles sur le sujet). Pour finir, on introduira quelques billes pour faciliter la mise en place de ce workflow sur un projet.

Le but de cet article n’est pas de présenter en détail le fonctionnement de Gitflow. Si vous voulez approfondir sur ce sujet, je vous encourage à consulter les articles suivants :

  • A successful Git branching model : Article original de Vincent Driessen dans lequel il présente Gitflow
  • Gitflow Workflow : Article de la société Atlassian dans lequel Gitflow est présenté d’une manière très graphique. Dans la page consacrée à Git, on peut trouver d’autres workflows ainsi qu’un tutoriel
  • Git-flow cheatsheet : Extensions Git pour mettre en place plus facilement Gitflow

Les schémas utilisés dans cette article sont issus de l’article d’Atlassian. Ces images ont été publiées sous licence Creative Commons Attribution 2.5 Australia License.

Gitflow en quelques mots

Gitflow sépare sur des branches isolées le code en cours de développement et le code validé et testé. Pour cela, il s’appuie sur la création de plusieurs branches dont le cycle de vie est bien défini. Voici une table contenant leurs noms, leurs cycles de vie et leurs fonctions :

Branche Nombre Branche d’origine Durée de vie Fonction
master Unique Permanente Code stable, testé et validé potentiellement éligible pour une MEP (Mise En Production)
feature Plusieurs develop Développement d’une feature Code en cours de développement qui implémente une fonctionnalité à embarquer dans la prochaine version de l’application
develop Unique master Permanente Code de la prochaine version de l’application. Une fois que le développement d’une fonctionnalité (feature)est fini, le code est fusionné sur cette branche
release Unique develop Recette Branche sur laquelle on corrigera les bugs détectés pendant la phase de recette
hotfix Aucune/Plusieurs master Correction d’un bug Branche où on fait les corrections des bugs sur le code présent sur la branche master (production)

 Afin de visualiser l’interaction de toutes ces branches, vous pouvez trouver un schéma ci-dessous :

Comme vous pouvez le constater, ce workflow est une extension du Feature Branch workflow avec quelques branches en plus. Bon, assez de théorie pour aujourd’hui. Parlons des faits !

Les avantages

Branch all the things!

L’un des avantages de Git par rapport aux autres SCM comme SVN est la simplicité et la rapidité lors de la création/changement des branches. Cela a permis l’apparition de plusieurs workflows multibranches comme par exemple le Feature Branch workflow ou le Gitflow workflow. Cette approche a de multiples avantages que l’on va énumérer ci-dessous :

Développer isolément une nouvelle fonctionnalité

Travailler en équipe, c’est bien mais chacun a besoin de son propre espace. Lorsqu’on développe une nouvelle fonctionnalité, c’est essentiel de s’isoler des modifications non-liées à la fonctionnalité sur laquelle on travaille. Pourquoi ? Parce que lorsqu’on développe, notre code peut engendrer des régressions. Et si l’on travaille tous sur la même branche, on aura du mal à trouver l’origine de la régression. Est-ce suite à notre développement, ou à celui d’un collègue? Ceci peut nous faire perdre beaucoup de temps.

Un autre avantage lié à cette approche est que l’on peut écarter une fonctionnalité si elle sort du scope du sprint courant sans impacter le reste des fonctionnalités et sans perdre le code généré. Ceci peut arriver quand, par exemple, on s’est rendu compte que la fonctionnalité n’est pas bien définie ou quand on ne finit pas à temps pour la fin du sprint. Voici un schéma montrant ceci :

Comme on peut le constater, la deuxième branche feature n’a pas été fusionnée sur la branche develop. Par conséquent, on pourrait la merger pour la prochaine version.

Expérimentation

Avez-vous envie de tester la nouvelle version de votre framework préféré et évaluer l’impact sur votre application ? Voulez-vous changer vos pom.xml pour optimiser vos builds ? Pas de souci ! Vous pouvez créer une branche d’expérimentation pour travailler tranquillement. Et tout cela sans risquer l’intégrité de l’application et sans déranger vos collègues.

Bugfix for Dummies

La gestion des bugs en production est assez ennuyeuse en règle générale. Gitflow permet de gérer cette situation très facilement. Voici un petit exercice de mise en situation :

(Lundi 9h du matin). Développeur lambda arrive au bureau avec une envie irréfrénable de café quand tout à coup il reçoit un coup de fil de son product owner

Product Owner: Qu’est-ce que vous avez foutu lors de la dernière MEP ? J’ai reçu plusieurs mails d’utilisateurs fous furieux car il y a un bug bloquant qui les empêche de travailler ! A CORRIGER ASAP !

Dev lambda: Ne vous inquiétez pas. Je gère

Product Owner: Je l’espère bien. Tenez-moi au courant -raccroche-

Dev lambda panique. Il n’a pas beaucoup d’expérience et tous les autres développeurs sont en congé

En général, les développeurs n’aiment pas travailler sous pression. Encore moins quand ils n’ont pas encore bu leur café. Malheureusement, ce genre de situation est fréquente et il faut savoir comment réagir. Dans notre cas, comment notre développeur va-t-il s’en sortir ? Pas de panique ! Gitflow a la solution à notre problème. Comme vous le savez, la branche  master contient le code de la dernière MEP réalisée, par conséquence, on n’a qu’à créer une branche nommée hotfix-bug-du-lundi-matin à partir de la branche master. Voici un schéma concernant le cycle de vie de la branche hotfix :

Comment on peut constater, lorsque un bug est corrigé, la branche créée pour le résoudre est mergée sur deux branches différentes :

  • master : Pour faire ensuite une nouvelle release et faire une MEP dès que possible
  • develop : Pour s’assurer que la version en cours embarquera la correction du bug

(Lundi 11h du matin). Développeur lambda appelle son responsable

Dev lambda: Bonjour monsieur, j’ai trouvé le bug et je l’ai corrigé sur la branche bugfix-bug-du-lundi-matin. On a créé un nouveau test unitaire pour que cette situation ne se répète plus. Tous les test sont au vert et la branche bugfix a été mergée sur la branche master. On est prêt pour la release

Product Owner: C’est fabuleux. N’oubliez pas de merger aussi sur la branche develop pour que la modification soit embarquée dans la version en cours de développement

Dev lambda: C’est fait

Product Owner: Magnifique ! Faites la release

Le superpouvoir de la branche release

Si vous jetez à nouveau un coup d’œil sur le schéma général de Gitflow, vous allez sans doute vous poser des questions par rapport à la branche release. A quoi sert-elle ? Lorsqu’on a fini toutes les fonctionnalités, la phase de recette commence. Sauf catastrophe, il s’agit d’une étape assez tranquille pour les développeurs, seuls quelques ajustements sont normalement nécessaires. Pendant cette étape, Gitflow permet aux équipes de se scinder en deux :

  • Correcteurs de bugs : certains développeurs doivent corriger les bugs trouvés par les recetteurs. Ils vont travailler sur la branche release.
  • Développeurs : le reste de développeurs peuvent commencer, si possible, les features du sprint prochain. Pour cela, il faut qu’ils créent des branches feature à partir de la branche develop

La composition des deux équipes peut varier de manière dynamique selon le nombre de bugs détectés.

Une fois la recette terminée, on mergera la branche release sur la branche master pour tagger notre dépôt et sur la branche develop pour intégrer les dernières corrections sur la prochaine version.

Adapté aux méthodologies agiles…

Beaucoup de sociétés se sont rendues compte que si elles veulent réduire le « time to market » (TTM), les anciennes méthodes de conception logiciel ne sont plus valables. C’est pour cela que les méthodes agiles comme Scrum sont de plus en plus répandues. L’intégration de Gitflow au sein d’une équipe Scrum est assez naturelle car il y a une relation directe entre les artefacts Scrum et les branches du workflow :

Artifact Scrum Equivalence sur Gitflow
Fin de Sprint Release sur la branche master
User Story (US) Branche feature

et au déploiement en continu

La mise en place d’une démarche de déploiement en continu est assez simple car il y une liaison forte entre les types de branches et les envionnements cibles. Voici une table contenant les types de branches et leurs environnements :

Type de branche Environnement cible
feature Local ou environnement éphémère (Kubernetes)
develop Intégration
release Qualification / Recette
master Production

Cette relation permet d’établir des politiques de déploiement automatique spécifiques pour chaque environnement si nécessaire.

Ce que l’on ne dit pas

Malgré les avantages évidents de ce workflow, il y a des inconvénients qui se manifestent lors de sa mise en place. Voici quelques difficultés que l’on peut rencontrer :

Complexité

Lorsqu’on se penche la première fois sur ce workflow notre instinct nous dit qu’il est complexe. Et notre instinct ne ment pas ! D’ailleurs, ce framework génère des avis assez contraires en ce qui concerne sa complexité. Pour certains, le workflow est inutilement complexe car :

  • On doit appréhender les cycles de vie de 5 types de branches différentes: master, develop, feature, hotfixrelease
  • Dans le cadre de certains projets les branches master et develop sont redondantes
  • Dans certaines conditions, on ne doit pas faire un mais deux merges consécutifs sur des branches différentes (finalisation d’un hotfix ou finalitation d’une release). Voici un exemple :

En effet, ce workflow est complexe et il ne s’adapte pas très bien aux petits projets et aux projets menés par des personnes qui n’ont pas beaucoup d’expérience avec Git.

Historique difficile à suivre

Dans l’article d’origine de Gitflow, Vincent Driessen propose de merger les branches avec l’option -no-ff afin de créer des commits à chaque merge (même quand un fast-forward est possible). L’auteur jusitifie ce choix pour ne pas perdre l’historique des branches feature qu’ont été déjà mergées mais, dans la vie réelle, ceci peut générer un historique git difficilement lisible.

Régressions suite aux merges automatiques

Git est assez bon pour gérer les merges automatiquement. S’il n’est pas capable de faire le merge tout seul, il aura besoin d’une intervention humaine pour corriger les problèmes de merge manuellement. Git prévient dans ces cas avec un message d’erreur assez explicite.

CONFLICT (content): Merge conflict in <fileName>
Automatic merge failed; fix conflicts and then commit the result.

Néanmoins, dans certaines conditions git effectue des merges automatiques qui ne sont pas corrects. Et tout cela sans prévenir le développeur qui fait le merge ! En effet, ce n’est pas une situation courante mais cela arrive. Ceci est une source potentielle de régressions.

Workflow pas adapté aux toutes les applications

Lorsqu’on a parlé du Gitflow, on a dit que le code de la branche master est le code qui est prêt pour passer en production. Ceci est très intéressant quand les clients utilisent toujours la dernière version de notre logiciel, mais qu’est-ce qui se passe quand on doit supporter plusieurs versions de notre application comme dans le cas d’un framework Dans le cas où on a une version 2 – toujours utilisée par certains clients – et une version 3 de notre logiciel et on découvre un bug sur la version 2, comment fait-on ?
Dans ce cas, Gitflow n’est pas une solution satisfaisante. Néanmoins, on pourrait adapter ce workflow en ajoutant une nouvelle branche nommée supportL’article de Nathanaël Charrier explique comment gérer plusieurs versions avec GitFlow.

Astuces pour réussir

Après avoir discuté des avantages et inconvénients de ce workflow, on doit se poser la question, ce workflow est-il pour moi ? Malgré ses inconvénients, Gitflow répond d’une manière élégante à la plupart des problèmes de la vie des développeurs. Voici quelques astuces pour une mise en place sereine de Gitflow.

Sensibilisation de l’équipe

C’est vrai, Gitflow est un peu complexe si on le compare avec d’autres workflows. Parfois, on est tenté de trouver des raccourcis pour avancer plus vite. Un exemple flagrant qu’on peut constater est de ne pas faire des merges mais de cherrypicker les commits. Il est très important de respecter les règles du workflow. Si l’équipe n’est pas mûre, il est nécessaire de trouver un développeur plus expérimenté pour se porter garant du suivi du workflow pendant la montée en compétences du reste de l’équipe.

Definition of Done (DoD)

L’engagement de tous les membres de l’équipe est fondamental pour conduire un projet vers la réussite.

Au sein d’une équipe, le développeur doit être responsable du code qu’il produit. Par conséquent, c’est à lui d’assurer que le code fait par ses soins est correct. Gitflow n’impose aucune action spéciale avant de merger une branche feature sur develop. Voici quelques recommandations :

  • Vérifier que tous les tests unitaires et d’intégration sont au vert
  • Lancer l’application en local et vérifier manuellement si le fonctionnement est en accord avec la demande du product owner
  • Réaliser un analyse en local du nouveau code à l’aide d’un outil de détection de défauts comme Sonarqube. Cet outil peut s’intégrer directement sur l’IDE de notre choix à l’aide des plugins comme SonarLint.
  • Demander systématiquement à un collègue de faire une code review de votre code avant de merger sur develop. Cette pratique va permettre d’avoir un avis extérieur du code modifié et peut permettre à l’équipe de mieux contrôler la dette technique du projet. Sur certains outils comme GitLab cela peut être fait sous la forme d’une merge request.

Installation des extensions Git Gitflow

Voici le premier postulat de The three great virtues of a programmer de Larry Wall :

1 Laziness: The quality that makes you go to great effort to reduce overall energy expenditure. It makes you write labor-saving programs that other people will find useful and document what you wrote so you don’t have to answer so many questions about it

Il ne faut pas sous-estimer la vérité qui se cache derrière cette phrase. Nous les développeurs, on est paresseux par définition mais il ne faut pas cupabiliser, c’est notre esprit d’ingénieur. Afin d’automatiser au maximum la gestion des branches, on peut installer des extensions git qu’on peut trouver ici.

Intégration continue et dette technique

Dans n’importe quel projet, il est recommandé d’avoir une plateforme d’intégration continue. Ceci permet d’intégrer automatiquement les modifications réalisées sur le code et de notifier les développeurs lorsqu’un test ne passe plus. Une autre bonne pratique est l’intégration avec un outil de détection de la dette technique comme Sonarqube par exemple.

Comme on a vu précédemment, Git peut introduire des régressions dans notre code lors d’un merge automatique. C’est vital de détecter rapidement ce genre de situations. Pour faire ceci, on peut s’appuyer sur deux aspects : la couverture de tests et le build automatique des branches clé. Voici une mise en situation : suite à plusieurs merges des features sur la branche master, git introduit une régression sans notifier personne.

  • Jenkins détecte un changement sur la branche master. Il lance donc un build
  • Le build échoue car un ou plusieurs tests ne marchent plus.
  • Jenkins notifie l’équipe du problème via mail, slack, etc.
  • L’équipe traite ce problème en priorité et corrige le problème

Pour que cette démarche fonctionne, on ne doit pas désactiver les tests. Interdit d’utiliser @Ignore 

Voici une table contenant une proposition de configuration des branches sur Jenkins :

Branche Build automatique Analyse SonarQube
master Oui A chaque modification
develop Oui Une fois par jour
release Oui Non
hotfix Oui Non
feature Si possible Analyse en local

Tout ça c’est bien mais, comment je peux configurer tout ça sur ma plateforme CI ? Si on utilise Jenkins, on peut utiliser le plugin pipeline multibranch de Jenkins. Voici quelques liens contenant des informations concernant ce plugin Jenkins et son utilisation dans le cadre de Gitflow :

Déploiement automatique

Si on part du fait que l’on a déjà une plateforme d’intégration continue fonctionnelle, l’étape suivante est d’automatiser les déploiements sur les différents environnements. Comme vu lors de la présentation des avantages de Gitflow, il y a un lien fort entre les types de branches et les environnements que l’on a normalement à disposition. Ne serait-il pas génial de pouvoir lancer un déploiement sur l’environnement de développement à chaque modification de la branche develop ? Le déploiement en continu présente beaucoup d’avantages mais il s’agit d’un processus long, périlleux et dans la plupart des cas frustrant pour différentes raisons :

  • L’automatisation des déploiements est une tâche longue qui n’aporte pas de la valeur au produit dans un premier temps. Il s’agit d’un investissement à long terme.
  • Automatiser un déploiement est une tâche complexe qui nécessite des gens formés et motivés.
  • Pour donner le pouvoir aux développeurs pour faire des déploiements à la demande, un changement de mentalité est nécessaire. Pour faire ceci, il faut que les développeurs et les opérationnels se rapprochent pour collaborer ensemble d’une manière plus fluide est naturelle. Cette organisation est connue sous le nom de DevOps. La mise en place d’une stratégie DevOps est spécialement difficile dans les grandes structures où les différents départements ont des objectifs différents et dans la plupart des cas contraires.

Bien définir le concept de « hotfix »

Qu’est-ce que c’est un hotfix ? C’est une question assez « philosophique » mais très importante qui peut générer de fervents débats au sein d’une équipe. C’est pour cela que l’on doit bien le définir et de respecter ce choix. Dans le cas du Gitflow c’est particulièrement pertinent.
Comme on peut le constater sur le schéma de Gitflow, les branches du type hotfix partent et sont mergées directement sur la branche master. Ceci est dû au fait qu’elles ont été conçues pour aborder des problèmes dont la correction est simple (par exemple : fichier de configuration incorrect ou manquant, petit bug au niveau du code, etc.). Si le problème à corriger est plus complexe, comme par exemple une feature non-conforme, il faudra envisager de créer une nouvelle branche feature à partir de la branche develop.

Bien tester les features avant le merge sur develop :

Qu’est-ce que le merge d’une branche feature veut dire ? Lorsqu’on merge une branche feature sur la branche develop, on indique que la fonctionnalité est terminée et prête pour la recette. Qu’est-ce que « prête » veut dire ? Cela dépend de la DoD accordé sur chaque projet.

L’un des principes du software craftsmanship est que les développeurs doivent être responsables du code qu’ils produisent. C’est pour cela qu’un développeur doit s’assurer que la fonctionnalité implémentée réponde au besoin du Product Owner. Néanmmoins, une fois la fonctionnalité terminée, on doit pouvoir tester on-live. On peut tester en local mais un avis exterieur est nécessaire car, en règle générale, c’est une mauvaise pratique qu’une fonctionnalité soit testée par la même personne qui l’a développée.

Dans ce contexte, une question se pose, comment peut-on faire mieux ? Ne serait-il pas génial de mettre à disposition des recetteurs des environnements pour chaque feature pour qu’ils testent au fur et à mesure que les fonctionnalités aboutissent ? Beaucoup d’évolutions se sont produites dans ce sens-là ces derniers années avec l’apparition des outils comme Docker ou Kubernetes. Il y a même des SCM comme Gitlab qui proposent le concept de review apps permettant la création et le déploiement des applications à partir d’une branche. Ce type de solutions sort du cadre de cet article mais on peut trouver quelques liens intéressants ci-dessous :

Bien entendu, même si on arrive à mettre en place une solution de ce genre, une phase de recette sera nécessaire lorsque toutes les branches feature seront mergées. Cependant, la plupart des bugs seront déjà corrigés.


Viewing all articles
Browse latest Browse all 1865

Trending Articles