Isolation Continue : choisir librement l’ordre des mises en production

Un autre élément important sur notre chemin vers le Déploiement Continu

Jean-Pierre Lambert
Jean-Pierre Lambert's blog
7 min readSep 25, 2017

--

This article is also available in English.

J’ai parlé précédemment de comment nous priorisons l’ordre dans lequel nous mettons en productions les différentes fonctionnalités “done”.

Cela n’a été rendu possible que parce que nous nous sommes écartés du modèle de branche GitFlow pour adopter l’Isolation Continue.

Si par hasard vous ne comprenez pas la phrase précédente, j’ai justement essayé d’expliquer tout le contexte nécessaire en termes non-techniques :

L’équipe s’écarte de GitFlow et de l’Intégration Continue

Il existe d’autres manières de travailler au-delà de GitFlow et de l’Intégration Continue.

Sur notre route vers le Déploiement Continu, l’équipe a décidé de s’écarter de GitFlow et d’utiliser un autre modèle de branche.

Pourquoi arrêter GitFlow

Les contraintes de GitFlow

Avec GitFlow, les développeurs ajoutent des fonctionnalités dans la branche develop puis, à un moment donné, ils créent une branche de release à partir de develop qui sera mise en production et fusionnée dans master.

Cela implique que :

  1. Les fonctionnalités sont livrées par lots
  2. Planifier les releases est une bonne idée
  3. Les nouvelles fonctionnalités doivent être implantées dans un ordre compatible avec le plan de release
  4. Ne pas suivre le plan de release, c’est à dire ajouter dans la prochaine release une fonctionnalité qui n’était pas planifiée, va donner des maux de têtes à tout le monde (au grand minimum, il faudra retravailler le plan de release et le plan de test, et parfois même refaire le travail en double)

Bien entendu ces éléments ne sont pas des affirmations absolues. En particulier rien n’empêche de livrer des fonctionnalités une par une. Mais le modèle de branche GitFlow rendra ce mode de fonctionnement fastidieux.

Pourquoi ces contraintes ne nous convenaient pas

Que nous est-il arrivé ?

Voici un peu de contexte :

Nous étions au milieu d’un refactoring majeur. Ce n’était pas vraiment prévu, mais nous avions mis le doigt dans un engrenage et nous n’avions plus d’autre choix que d’aller jusqu’au bout.

C’est alors qu’une fonctionnalité mineure devait être livrée absolument avant une certaine date inflexible, pour le lancement en grande pompe d’un produit qui dépend de notre composant.

Répondre à cette demande était très compliqué parce que nous utilisions GitFlow. Le plan initial était de livrer la fonctionnalité après ou en même temps que le refactoring mais nous n’arrêtions pas de dériver et avions toujours besoin de plus de temps — jusqu’à ce que la deadline de la feature mineure devienne dangereusement proche.

Sans se mentir, même si nous terminions le refactoring avant la deadline, nous aurions changé tellement de code que le risque était énorme d’avoir cassé quelque chose lors du lancement du nouveau produit. Cette vision nous mettait mal à l’aise.

Alors plutôt que faire le pari que nous aurions terminé le refactoring avant le lancement, nous avons pris le code de la fonctionnalité mineure et l’avons délivrée comme un hot-fix, c’est à dire à partir de la branche avec le code de production (master) plutôt que depuis develop. Ainsi, nous avons pu livrer la fonctionnalité à temps et sans risque.

Faire ce genre de chose est compliqué pour les développeurs, car ils doivent extraire le code du contexte d’une branche pour l’appliquer à une autre branche.

Avec le recul, ce n’était pas très difficile mais le risque de commettre une erreur était réel. Plus important encore, cet épisode a semé les graines qui nous mèneront à un nouveau modèle de branche : serait-il possible de travailler ainsi pour n’importe quelle fonctionnalité, en la livrant à la demande, facilement et sans risque ?

L’équipe décida alors de s’écarter de GitFlow.

Notre nouveau modèle de branche

Dans le nouveau modèle de branche, on garde vivantes les branches de fonctionnalité jusqu’à ce qu’elles soient en production et fusionnées dans master. Il n’y a plus de branche develop.

On fusionne directement dans master, au dernier moment possible — ce qui a pour conséquence de donner du pouvoir au Product Owner

De cette manière, les nouvelles fonctionnalités peuvent être déployées dans n’importe quel ordre.

De toute évidence, cela veut également dire que tout le travail d’intégration est effectué au dernier moment. Ce changement de modèle de branche invalide également le fonctionnement de l’Intégration Continue — nous y reviendrons un peu plus tard.

Cependant, lorsque nous préparions une release avec GitFlow nous devions de toutes façons vérifier en profondeur que rien n’était cassé avant de pouvoir effectivement mettre en production. Il est bien possible que notre Intégration Continue ne disposait pas d’assez de tests automatisés pour disposer d’une couverture suffisante. Quoi qu’il arrive, nous devions passer beaucoup de temps à vérifier que tout allait bien.

Ce qui nous a mené à une autre observation.

Réduire la taille des releases et mettre en production souvent

Nous avions également remarqué que lorsque nous faisions des gros changements, nous passions beaucoup de temps à vérifier que rien n’était cassé. Malgré tous nos efforts nous rations souvent des choses et introduisions des régressions quand même. Alors qu’à côté de ça, lorsque nous travaillions sur des petits changements (principalement des hot-fixes) nous ne vérifions que quelques petites choses importantes, directement liées aux changements. Cela ne nous prenait que peu de temps, et pourtant nous cassions rarement quoi que ce soit.

Et si nous ne faisions plus que des releases les plus petites possibles ?

Cette idée était difficilement compatible avec GitFlow car cela nécessitait de passer beaucoup de temps sur la création, la gestion et la fusion des branches de release. Aucun problème lorsque vous ne mettez en production que de temps en temps, mais c’est un vrai ralentissement si vous le faites tous les jours.

De l’autre côté, cela ne posait aucun problème avec notre nouveau modèle de branche. À vrai dire, ce modèle de branche fonctionne même encore mieux ainsi.

En effet le problème de ce nouveau modèle de branche est que vous devez garder à jour toutes les branches de fonctionnalité. Aussi pour minimiser cette charge, vous devez essayer de fusionner les branches aussi vite que possible. En d’autres termes, garder les fonctionnalités aussi petites que possible, et mettre en production souvent. Exactement ce que nous cherchions !

Les nouveaux super-pouvoirs du Product Owner

Point important au-delà du fonctionnement technique de ce modèle de branche : cette manière de travailler donne de nouveaux super-pouvoirs au Product Owner, et au métier en général. En effet, le PO a toute latitude pour prioriser l’ordre dans lequel les fonctionnalités ‘done’ seront livrées aux utilisateurs.

Imaginons qu’une nouvelle fonctionnalité ou correctif urgent fait irruption : il est tout à fait possible de le prioriser devant tout le reste. Et ça ne pose problème à personne, ni dans l’équipe ni en dehors !

Il n’y a aucun tuyau rempli de travail en cours qu’il faut vider avant de pouvoir prendre en charge ces nouveaux besoins urgents.

Cette liberté donnée au Product Owner correspond à ce que je décrivais dans mon précédent article à propos du board de planning des MEP. Nous n’avons qu’à prioriser en Sprint Planning quelles fonctionnalités doivent sortir en production et dans quel ordre.

Tout cela n’aurait pas été possible, ou du moins pas aussi facilement, avec un modèle de branches comme GitFlow.

L’ordre de mise en production des fonctionnalités n’aurait pas été au choix du Product Owner ; ou alors pas avec un tel niveau de granularité.

Isolation Continue

L’intégration continue traditionnelle ne sert pas à grand-chose avec un tel modèle de branches. Tout le principe de l’intégration continue repose sur l’idée d’intégrer souvent des petits changements sur une branche commune ; alors que ce que nous faisons consiste à garder les branches vivantes le plus longtemps possible et de les fusionner au dernier moment possible. Une fois que la branche a été fusionnée, cela veut dire qu’elle est en production : il est déjà trop tard pour vérifier l’intégration.

Aussi nous pratiquons une variante à la place de l’intégration continue : l’isolation continue. On garde les branches isolées les unes des autres le plus longtemps possible ; néanmoins, nous voulons quand même nous assurer que ces branches fonctionnent, seules. Mieux encore, nous voulons aussi nous assurer que si nous fusionnions ces branches, alors elles fonctionneraient toujours — au minimum individuellement, ou peut-être toutes mélangées ensemble.

Pour faire court : si nous ne faisons pas de l’intégration continue au sens strict du terme, nous avons quand même un logiciel qui vérifie que tout fonctionne correctement, et qui effectue cette vérification aussi souvent que possible. Et cela marche, puisqu’il nous a déjà remonté à plusieurs occasions des feedbacks intéressants. (c’est à dire : pointer du doigt une branche cassée avant que nous ne perdions du temps en commençant les tests manuels)

Et ensuite ?

Même si aujourd’hui tout fonctionne sans hic, il est quand même évident que nous pourrions faire mieux.

Ainsi le taux de couverture du produit par des tests automatiques est toujours loin d’être satisfaisant. Nous avons dépensé énormément d’efforts mais ce n’est toujours pas suffisant ; idéalement nous n’effectuerions pratiquement aucun test de non-régression. Peut-être continuerions-nous d’effectuer des tests manuels, mais il serait plutôt question de tests exploratoires : apprendre des choses sur notre produit que nous ne savons pas déjà, trouver des choses qu’on pourrait difficilement prévoir.

Histoire à suivre…

Cet article fait partie d’une série sur le thème des mises en production. Cet article et les trois précédents (premier, second et troisième) se concentraient sur les outils de management visuel que nous avons mis en place ainsi que sur leur utilisation au quotidien.

Au programme à venir :

  • Détail du process de mise en production
  • Analyse de risque : formalisation et communication

Comme toujours, je suis friand d’avoir vos feedbacks !

Cet article vous a plu ?

Abonnez-vous à moi via le bouton Follow pour être notifié des autres articles !

Et n’oubliez pas de m’applaudir 👏 et de partager l’article ! N’oubliez pas que c’est votre amour 💓 qui me fait mettre autant de cœur à l’ouvrage.

Merci 😄

--

--

Software engineer with special interest in quality and business value, now a technical/Agile coach helping teams to deliver high-value, high-quality products.