La puissance des workflows git

L’outil n’est pas la méthode

OVH UX Labs
8 min readMar 23, 2017

Si vous lisez ces lignes, c’est que comme nous, vous travaillez en équipe sur un ou plusieurs projets. Et vous êtes parfois confronté à l’enfer des conflits git. La diabolique réécriture d’historique. Les rebases du désespoir. Git rerere des abysses… Il est donc crucial d’avoir un bon workflow, répondant au mieux à nos besoins, car connaître git c’est bien. L’utiliser correctement c’est mieux !

De ce fait, il faut d’abord déterminer nos besoins. De facto je dirais :

[ ] Coder en évitant que le ciel nous tombe sur la tête
[ ] Tester les nouvelles fonctionnalités avant la mise en production
[ ] Gestion des urgences en tout genre
[ ] Livraison continue
[ ] Visée «open source»
[ ] Release maîtrisée

Des besoins somme toute classiques, il existe donc probablement des solutions clefs-en-main pour y répondre. Voyons ensemble les plus connues.

Git flow, l‘artillerie lourde.

Git flow est le plus populaire des workflows git. Dans un contexte d’équipes grandissantes, de méthode agile et de livraison continue, les principes de base sont en effet séduisants.

2 branches principales :

master : La branche dite de «production», la stable. Elle porte les tags et très peu de commits.

develop : La branche de base pour tous les développeurs. Tout part de là. Chaque branche de travail est tirée de celle-ci pour préparer les features et les releases.

Les branches de bases de git flow

3 branches de «second» niveau :

feature/XYZ : Ces branches permettent de commencer une nouvelle fonctionnalité. Chacune d’entre elles doit correspondre à une fonctionnalité. Elles n’interagissent jamais avec la branche master.

Création des branches de fonctionnalités

release/XYZ : Elles permettent de lier la branche develop à branche master. Elle contient les commits pour préparer les nouvelles releases. Seuls des bugfixes seront pushés sur cette branche. Une fois prête, la version est fusionnée dans master et étiquetée avec le numéro de version. Il faut également fusionner dans develop une fois master taggé.

Création de la branche de release

hotfix/XYZ : La branche de la catastrophe. Elle permet de publier rapidement un fix depuis master. Il s’agit de la seule branche qui peut directement être tirée de master. Une fois le fix terminé, il faut la merger dans master en taggant le patch, puis merger dans develop.

Création d’une branche hotfix

Il est vrai que cela fait de nombreuses branches à gérer. Voyons concrètement ce que cela donne en pratique de développer une nouvelle fonctionnalité :

Si elle n’existe pas encore, il faut tout d’abord créer la branche develop :

$ git branch develop
$ git push -u origin develop

A présent chaque développeur peut cloner le repo afin de travailler :

$ git clone ssh://user@host/path/to/repo.git
$ git checkout -b develop origin/develop

Maintenant, imaginons Jean-Cyril désirant commencer une nouvelle fonctionnalité. Il doit créer une branche séparée pour chaque fonctionnalité :

$ git checkout -b feature/awesome-feature develop

Il développe de son côté :

$ git add <files>
$ git commit

Une fois que la feature est terminée, Jean-Cyril envoie une pull-request à l’équipe ou, s’il a les droits merge, directement sur develop :

$ git pull origin develop
$ git checkout develop
$ git merge feature/awesome-feature
$ git push
$ git branch -d feature/awesome-feature

Jean-Cyril peut préparer la release, si il a assez de features et qu’il n’a plus de bug :

$ git checkout -b 0.0.1 develop

Et la publier :

$ git checkout master
$ git merge 0.0.1
$ git push
$ git checkout develop
$ git merge 0.0.1
$ git push
$ git branch -d 0.0.1
$ git tag -a 0.0.1 -m "Initial public release" master
$ git push --tags

La feature de Jean-Cyril est maintenant disponible pour nos utilisateurs.

Cela en fait des commandes git à exécuter ! Heureusement il existe quelques outils pour vous simplifier la vie comme git-flow. Malgré cet outil, ce workflow ne remplit pas l’ensemble de nos besoins et fait ressortir certaines problématiques :

  • Où se passe la phase de test ?
  • Un bug est détecté rapidement sur la branche release/XYZ, mais hors de notre périmètre (Infrastructure, matériel, API) la mise en production reste-t-elle bloquée pour les autres fonctionnalités ?
  • Comment commencer une nouvelle fonctionnalité sans embarquer les bugs déjà mergés sur develop ?
  • Ce workflow n’est-il pas trop contraignant pour la communauté open source ?

Reprenons notre check list et voyons ce qu’il en est :

[X] Coder en évitant que le ciel nous tombe sur la tête
[X] Tester les nouvelles fonctionnalités avant la mise en production
[X] Gestion des urgences en tout genre
[ ] Livraison continue
[ ] Visée «open source»
[X] Release maîtrisée

Pour nos besoins, git flow n’était pas une solution à retenir. Et fût clairement un échec malgré nos outils d’industrialisation. Je pense cependant que dans une équipe fonctionnant en scrum, la mise en place de git flow est efficace chaque branche feature étant une représentation de user stories.

Plus personnellement, je le trouve inutilement complexe par rapport à d’autres workflows et nous avons décidé de choisir quelque chose de plus «simple» pour voir ce qu’il en est.

Keep It simple, Stupid

Github flow, la simplicité.

Partant de l’échec de la mise en place de git flow. Nous nous sommes intéressés à github flow. Nous possédons un rythme très soutenu de mise en production ( plusieurs fois par jour ). Et la simplicité de ce workflow semble être un atout à cette hyper agilité.

Github flow repose sur 6 points fondamentaux :

  • Tout ce qui est sur master est stable et déployable
  • Pour travailler sur quelque-chose, la branche doit avoir un nom significatif. Comme : feature/add-menu…
  • Il faut commiter sur cette branche localement et régulièrement pusher sur une branche du même nom sur le serveur
  • Une fois le développement terminé, ouvrir une pull request sur master pour recueillir du feedback et des tests.
  • Une fois les feux au vert, merger sur master.
  • Déployer directement après le merge

Cela paraît assez simple. Voyons à présent la pratique.

Jean-Cyril désire développer une nouvelle fonctionnalité. Il doit tout d’abord cloner le repo si ce n’est déjà fait, puis créer une branche :

$ git clone ssh://user@host/path/to/repo.git
$ git checkout -b feature/XYZ origin/master

Il développe de son côté :

$ git add <files>
$ git commit -m "feature(menu) : add items"
$ git pull origin master
$ git push origin feature/XYZ

Une fois le développement terminé, Jean-Cyril ouvre une pull request, et envoie en test sa branche. Une fois mergée, la branche est supprimée et master part directement en production.

Les étapes de github flow

La simplicité de github flow est un atout indéniable pour faciliter la mise en place de l’open source sans intimider la communauté par un lourd workflow.

De plus, le principe «Tout ce qui est sur master est stable et déployable» permet d’assurer un déploiement continu. Nous perdons cependant la notion de release qui dans le cas de grosses fonctionnalités est nécessaire.

Jetons donc un coup d’œil à notre checklist :

[X] Coder en évitant que le ciel nous tombe sur la tête
[X] Tester les nouvelles fonctionnalités avant la mise en production
[X] Gestion des urgences en tout genre
[X] Livraison continue
[X] Visée «open source»
[ ] Release maîtrisée

Github flow n’est donc pas la solution ultime pour nos besoins. Cependant, et vu la simplicité de ce workflow, le compromis est acceptable. Mais peut-on faire mieux ?

be better

OVH UX Flow , notre solution.

Afin de répondre complètement à nos besoins, nous testons actuellement une solution hybride en tentant de prendre le meilleur des deux expériences.

ovh Ux Flowflow

Tout comme git flow, nous avons 2 branches principales :

master : Qui ne porte principalement que les tags et est le reflet de notre production.

develop : Qui sert de tampon pour les features et bugfix. Elle est stable et on peut y déclencher une production à n’importe quel instant. C’est un peu comme la branche release mais déjà stable. Le nom n’est donc probablement pas adéquat. Nous cherchons encore.

et 3 branches secondaires :

feature/XYZ : Similaire à celle de gitflow.

bugfix/XYZ : cette branche sert à corriger des bugs dont la criticité ne nécessite pas un hotfix, comme une mauvaise couleur, un alignement décalé etc.

hotfix/XYZ : Similaire à celle de gitflow. Elle permet de gérer les urgences depuis master.

Vous remarquerez l’apparition d’une branche bugfix et la disparition de la branche release.

La phase de stabilisation se fait donc sur les branches feature et bugfix. Le gros avantage est qu’à tout instant, un ensemble fonctionnel sur develop peut être mis en production. À l’inverse avec gitFlow, si 3 features se retrouvent sur develop, qu’on tire une release et que les tests invalident une des 3 features, c’est l’ensemble de la release qui se retrouve bloquée.

De plus, tout comme github flow, notre workflow repose sur quelques principes à respecter, trois en particulier :

  • Tout ce qui est sur develop est proddable
  • Pas de commit direct sur develop
  • Chaque branche de feature ou de bugfix subit une passe de qualité ( tests fonctionnels, code review).

Ceci nous permet d’assurer une cohérence sur l’ensemble du flow.

Regardons concrètement ce qu’il en est en pratique :

Si elle n’existe pas encore, il faut tout d’abord créer la branche develop :

$ git branch develop
$ git push -u origin develop

Maintenant, imaginons Jean-Cyril désirant commencer une nouvelle fonctionnalité. Il doit créer une branche séparée pour chaque fonctionnalité :

$ git checkout -b feature/awesome-feature develop

Il développe de son côté :

$ git add <files>
$ git commit -m "feature(menu) : add items"
$ git pull origin develop
$ git push origin feature/awesome-feature

Puis Jean-Cyril créée une Pull-Request et envoie en Quality Check. Une fois validé, son code sera mergé sur develop et mis en production via nos outils d’intégration continue ou, selon les projets : en appuyant sur le «gros bouton rouge» pour maîtriser la release.

Ainsi notre workflow est assez proche de git flow car c’est comme si une release de git flow ne contenait qu’une seule feature. Mais tout aussi proche de github flow, car la branche principale est proddable à tout instant.

Rappelons nous nos besoins initiaux et jetons un coup d’œil à notre checklist :

[X] Coder en évitant que le ciel nous tombe sur la tête
[X] Tester les nouvelles fonctionnalités avant la mise en production
[X] Gestion des urgences en tout genre
[X] Livraison continue
[X] Visée «open source»
[X] Release maîtrisée

Cela semble pas mal. Il s’agit d’une solution répondant à nos besoins dans notre contexte spécifique et la challengeons chaque jour. N’hésitez pas nous faire part de vos remarques et expériences sur les workflows git.

Sources

--

--