Automatiser la vérification du commit
Automatiser la vérification du commit avec commitlint
Sommaire
Connaissez-vous le "git workflow" ? Si ce n'est pas le cas, je vous invite à lire cet article http://nvie.com/posts/a-successful-git-branching-model
Je vais mettre ci-dessous l'image pour bien l'avoir en tête :
"Git workflow. source: http://nvie.com/posts/a-successful-git-branching-model"
Ce schéma est intéressant, cependant, il manque une réponse à une question : comment faire pour annuler une fonctionnalité depuis la branche release ?
Ce flux de travail suppose que toutes les fonctionnalités en develop soient recettées par le product owner et validées. Mais si une fonctionnalité n'est pas validée, alors qu'elle est en *develop *: nous sommes un peu coincés. La branche release permet de préparer la mise en production. Il faut donc l'utiliser pour fixer les éventuels bogues et annuler les fonctionnalités non validées. C'est sur ce dernier point que l'article va se concentrer.
Posons le décor : nous avons une branche master qui sera utilisée pour la mise en production, une branche develop pour toutes les nouvelles fonctionnalités du sprint en cours, et enfin une branche de release pour préparer la mise en production.
Ça donne ceci :
Un développeur créé une nouvelle fonctionnalité. Il va créer sa branche depuis develop et la nommer "feat-my-awesome-feature". Des fichiers sont créés, il y a un commit et la branche est poussée.
git checkout develop git checkout -b feat-my-awesome-feature # faire des modifications git add -A git commit -m "create some awesome code" git push origin feat-my-awesome-feature
La code review est ok, les tests passent, la branche est fusionnée dans develop pour être déployée en environnement d'intégration. Lors d'une pull request, le merge est fait en no-ff (no fast forward). Cela signifie qu'il y a un commit de merge dans l'historique. C'est important car il sera utilisé plus tard.
git checkout develop
git merge --no-ff feat-my-awesome-feature
git push origin develop
Je refais de même avec une seconde fonctionnalité : feat-killer-feature
git checkout develop
git checkout -b feat-killer-feature
# faire des modifications
git add -A
git commit -m "create killer code"
git push origin feat-killer-feature
Et je merge.
git checkout develop
git merge --no-ff feat-killer-feature
git push origin develop
Voilà, mon décor est posé. Petite vue en mode terminal.
Notre sprint va bientôt s'achever, préparons la branche de release. Mais au dernier moment, un product owner affolé voit que la fonctionnalité n'est pas valide. Il ne faut pas passer cette fonctionnalité en production.
Il faut gérer cette situation !
Faisons avancer release vers develop.
git checkout release git merge develop --no-ff
Il est important de faire un merge --no-ff car cela va permettre de garder une trace dans l'historique sur cette annulation.
Cette fonctionnalité n'est pas si géniale que ça (selon le product owner), je vais donc l'annuler de la branche release, mais je veux pouvoir la garder en develop pour l'améliorer dans le prochain sprint.
Je vais donc faire un revert.
git checkout release git revert -m 1 <commit de merge de feat-my-awesome-feature>
Si je fais un git log, je vais retrouver mon commit de merge correspondant : 184a372a608b632636f20a1ab7c64027cc9eecc2
En appliquant cette commande, un nouveau commit va être créé : un commit de revert. Cela va permettre d'indiquer qu'il y a eu revert et donc une annulation de l'ensemble des modifications de ce commit.
Mon historique indique bien un commit de revert avec en commentaire une explication:
commit 15c3c27a603263d1e59f5b137e7acfc6dcad5ce0
Author: Thierry Thuon <thierry.thuon.ext@francetv.fr>
Date: Fri Feb 19 12:49:07 2016 +0100
Revert "Merge branch 'feat-my-awesome-feature' into develop"
This reverts commit 184a372a608b632636f20a1ab7c64027cc9eecc2, reversing
changes made to 59596dd37699742262fc5a2705e2b9396540af77.
Je pousse ma branche release et la merge dans master. Il faut toujours pousser en --no-ff pour avoir un commit de merge, et donc avoir la possibilité de faire un revert.
git push origin release git checkout master git merge release --no-ff
Depuis master, je vois que j'ai bien la fonctionnalité feat-killer-feature uniquement.
Maintenant, une autre problématique se pose : si je merge de nouveau develop dans release, git considère qu'il n'y a aucune modification. C'est à cause du commit de revert dans la branche release. Pour cela, il faut annuler ce commit de revert (en gros, annuler une annulation x) ).
Je vais tout d'abord mettre à jour develop.
git checkout develop git merge release
Ici je n'ai pas besoin de faire un --no-ff, j'applique les modifications directement en fast-forward.
Depuis develop, je cherche mon commit de revert : 15c3c27a603263d1e59f5b137e7acfc6dcad5ce0
Et j'applique un revert sur ce commit.
git revert <commit de revert>
Un nouveau commit s'ajoute : il annule un commit d'annulation ("revert the revert").
commit b7f210da78305284f72edc2e671e5be1f167faad
Author: Thierry Thuon <thierry.thuon.ext@francetv.fr>
Date: Fri Feb 19 13:01:53 2016 +0100
Revert "Revert "Merge branch 'feat-my-awesome-feature' into develop""
This reverts commit 15c3c27a603263d1e59f5b137e7acfc6dcad5ce0.
Je retrouve bien les modifications de ma branche feat-my-awesome-feature. Et lors de la prochaine release, si tout est ok, elle pourra passer en master. Sinon, il faudra faire de nouveau un revert dans release.
Pour conclure, cette solution permet d'avoir la rigueur du git workflow, tout en ayant la souplesse et la possibilité d'annuler une fonctionnalité complète juste avant une mise en production. L'exemple montré ici est un cas nominal, mais la plupart du temps il peut y avoir un risque de conflit. Cette technique fonctionne bien pour des fonctionnalités isolées. De plus, il est important de bien faire les merge vers release et master en no fast forward (--no-ff). Enfin, il ne faut pas oublier les commit de revert lors de la mise à jour de develop.
Je vous mets en lien la démo: https://github.com/eleven-labs/cancel-story-before-deploying-prod/network
Auteur(s)
Thierry T.
Super Data Boy
Vous souhaitez en savoir plus sur le sujet ?
Organisons un échange !
Notre équipe d'experts répond à toutes vos questions.
Nous contacterDécouvrez nos autres contenus dans le même thème
Automatiser la vérification du commit avec commitlint
Dans le domaine de la data, la qualité de la donnée est primordiale. Pour s'en assurer, plusieurs moyens existent, et nous allons nous attarder dans cet article sur l'un d'entre eux : tester unitairement avec Pytest.
Le domaine de la data est présent dans le quotidien de chacun : la majorité de nos actions peut être traduite en données. Le volume croissant de ces données exploitables a un nom : "Big Data". Dans cet article, nous verrons comment exploiter ce "Big data" à l'aide du framework Apache Spark.