Les feature-branches, une fausse fausse-bonne-idée

By on 11 January 2014, in Blog, Development, Method

Quelques pistes de réponse à une vraie question soulevée dans le lab.

Je confirme l’hypothèse que vous émettez : la durée de vie limitée d’une feature-branch doit être une caractéristique intrinsèque. On fait de l’agile, non ? Release early, release often.

Une feature qui est autonome trop longtemps a-t-elle été bien découpée ? Vous dites « on risque qu’elle ne soit jamais activée ». A-t-elle été suffisament bien discutée/définie avec le PO, pour qu’il ne l’accepte pas pendant tout ce temps ? Les priorités peuvent changer certes.

Mais toujours dans un contexte agile, ça ne choquera personne qu’une fonctionnalité soit « incomplète », tel que vous l’évoquez. Je n’ai pas dit « bugguée à mort ». Ce qui est sûr c’est quelle est WIP (Work In Progress) : ça permet de valider rapidement un prototype ou faire évoluer le design sur les itérations suivantes… Du coup la complexité due à la fonctionnalité introduite est moindre :

  • si elle est validée, on continue, la complexité fait alors partie du projet.
  • Si elle est refusée, on la désactive, et on peut supprimer le code sans heurt, puisque les tests ont pris en compte l’activation ou non de la fonctionnalité.

Petite remise dans le contexte

On est en 2014. Certaines features déjà en production n’ont pas nécessairement vocation à être accessibles à tous les utilisateurs (staff, groupes, etc). Le mécanisme d’activation conditionnel peut faire partie des pré-requis de l’architecture du projet.

C’est devenu quasi un standard, vu le nombre de softs/projet existants –  et encore, j’ai limité à Django – dédiés à l’activation progressive de nouvelle features. Ça traite les accès en pourcentage ou groupes d’utilisateurs, les possibilités de rollback, et d’autres spécificités. Hé, ça ferait presque de ces modules une fonctionnalité vendable. Concernant la complexité, le module est externe et maintenu par la communauté.

Cela permet aussi de désactiver les features qui arrivent en fin de vie, ou celles qui doivent être désactivées temporairement pour des questions variées (exploitation, légal, sécurité…) sans devoir faire une hotfix (donc un run de CI + mise en prod) pour désactiver le code correspondant.

Ça oblige aussi – dans la mesure du possible – à correctement segmenter le code de la fonctionnalité pour éviter les spaghettis et favoriser la compréhension par les futurs relecteurs. Il y a un vieux singe dans l’équipe pour qui la rigueur de segmentation est un gage de qualité (ça va de pair avec les meaningful-patches). Si ce n’est pas moi, alors je suis d’accord avec lui.

Donc, notre feature incomplète…

Revenons à notre brebis.

Dès qu’elle est suffisament mûre pour ne pas casser la CI, elle rentre dans develop avec une activation conditionnelle. C’est finalement le même mécanisme que celui décrit précédemment, mais appliqué à une feature incomplète. Elle n’est pas visible par tous les utilisateurs, mais pour autant l’intéraction avec le PO est grandement favorisée : il a accès à un proto de manière anticipée ! C’est pas hyper-bankable, ça ?

Autre gain: notre nouvelle feature est maintenant refactoring ready : puisqu’elle est dans develop, elle fait officiellement partie du projet. Elle peut dont évoluer avec lui sans le ralentir. Ses évolutions individuelles peuvent potentiellement avoir lieu dans de nouvelles feature-branches, en fonction de la complexité de la story initiale ou des décisions du PO.

Gérer la contre-productivité

Au jour le jour la contre-productivité induite par l’isolation peut être compensée – ou à défaut, très fortement réduite – relativement aisément avec un git merge develop régulier. Ceci réintègre les autres features & hotfixes validées entre temps, tout en maintenant l’isolation de la nouvelle feature en cours de conception.

J’insiste sur la régularité : d’expérience, j’effectue un git merge develop dans les features-branches une à deux fois par jour – quelque fois plus – en concertation avec le release manager et le reste de l’équipe. Après une hotfix, c’est sain. Quand une autre feature est terminée, c’est très sain. Le refactoring ayant lieu vraissemblablement dans une autre feature-branch, c’est un cas à part : les fusions entre deux feature-branches sont tout à fait possible, mais c’est peut-être plus indiqué de progresser par petites releases successives ; ça depend des gens.

Quel que soit le sujet, c’est le planning intra-itération mais surtout la communication intra-équipe qui prime pour la réussite de l’opération.

Le code a bien moins d’importance que l’équipe

Plus la communication sur l’état d’avancement des autres features/hotfixes est conscientisé au sein de l’équipe – et donc plus les fusions-réintégrations sont régulières et rapprochées – moins l’overhead des features-branches est important, et plus les dépendances au paracétamol & à la caffeïne sont réduites – j’ai pas dit qu’il faut arrêter les discussions autour de la machine à café.

Sans compter les avantages “initiaux” pour lesquels ont les mets en place : la branche develop est toujours release-ready. Donc hotfix- et security-patch-ready aussi :-)

Les dévs font des trucs bien, les marketeux peuvent markéter, le PO est heureux. C’est pas l’amérique ?

On se fait une bouffe pour troller ?