Il y a pas mal de discussions sur la toile autour des branches fonctionnelles (feature branches). Le débat est généralement axé sur les pratiques agiles et la question de l’utilisation des branches fonctionnelles dans le cadre de l’intégration continue. On remarquera notamment l’article de james McKay qui se demande pourquoi Martin Fowler, l’un des auteurs du manifeste agile, ne comprend pas les branches fonctionnelles.
Les branches fonctionnelles consistent à dupliquer, isoler et dédier le code source d’un programme à un utilisateur ou bien une fonctionnalité à développer. La création de branches de ce type est utilisée depuis longtemps, notamment avec le cycle en V / cascade. Dédier une branche à une fonctionnalité ou un développeur donne une impression de grande liberté, et sépare la responsabilité de développement de celle d’intégration (ce ne sont parfois pas les mêmes personnes qui interviennent sur le développement et l’intégration). Dans une organisation où plusieurs équipes sont amenées à travailler sur le même projet, un système complexe de gestion de branches peut apparaître. On peut également trouver un cadre où les branches sont crées sans vraiment de cible d’intégration: la fonctionnalité est développée mais on ne sait pas encore dans quelle version on l’intégrera.
Le cycle en V, modèle qui a très bien fonctionné lors des dernières décennies, est de moins en moins utilisé. Dave Rooney en fait l’éloge dans cet article en terminant par:
Oui, le cycle en V fonctionne – vous pouvez livrer un logiciel de cette manière. Cependant, notre vision de la manière dont doit être développé un logiciel a été affinée ces dernières decennies et les avancées technologiques nous permettent d’avancer de manière plus itérative et incrémentale pour livrer un logiciel. Pour conclure, ce n’est pas le cycle en V qui ne fonctionne pas, c’est tout simplement que nous n’en avons plus besoin.
Depuis quelques années, les pratiques agiles ont le vent en poupe. Elles recommandent l’intégration continue car il n’y a aujourd’hui plus aucune raison de s’en priver: la technologie nous offre aujourd’hui la possibilité de tester unitairement certaines portions de code, de tester largement un logiciel en simulant un contexte de production et de construire le logiciel en produisant des rapports à chaque étape (compilation, mesure de la qualité du code, de la complexité, etc.). L’intégration continue est elle même une étape indispensable à la livraison continue qui bénéfie d’outils éprouvés pour sa réalisation. Outre les outils, les pratiques ont beaucoup évoluées: elles encouragent notamment les cycles courts, sont axées sur la valeur et la définition de tests au plus tôt.
Pourquoi beaucoup d’équipes se sentent plus confortables avec les branches fonctionnelles malgré tous les avantages de l’intégration continue?
1) Jamais testé: pas facile de se lancer là dedans si personne dans l’équipe a déjà expérimenté l’intégration continue ou en perçoit les bénéfices. Qui pourra être enclencher un changement?
2) Mauvaise expérience: l’intégration continue necessite un ensemble de pratiques qui peuvent être assez lourdes à mettre en place, notamment l’automatisation de la compilation tout en la rendant auto-testante, et surtout les tests dans un environnement de production cloné. Les mauvaises experiences résident dans les échecs à avoir pu mettre en place la compilation ou les test automatiques, à faire adherer de l’équipe, à disposer d’un budget pour avancer dans cette direction, etc.
3) Intégré dans le modèle cycle en V: l’équipe a mis du temps pour trouver son équilibre, elle fonctionne plutôt bien, elle est habituée à livrer ses branches aux intégrateurs, qui sont eux mêmes habiles dans le processus d’intégration des fonctionnalités à la branche principale. Certes, le time to market est un peu long, mais ce n’est pas le problème de l’équipe de développement, le perçoit-elle d’ailleurs?
4) Objectif local vs objectif global: dans les cas extrêmes, les développeurs peuvent se voir amener sur un plateau une branche déjà crée avec la spécification de la fonctionnalité à développer. La provenance de la branche importe peu (de quelle version), de même que la cible (dans quelle version elle sera intégrée). A contrario, la vision du projet permet d’engager l’équipe sur un objectif commun. La perspective de la réussite du projet est plus importante que celle de la réalisation d’une fonctionnalité, si intéressante qu’elle soit.
5) Plusieurs équipes sur le même projet: l’approche classique correspond au cycle en V avec un stratégie de gestion de branches au niveau équipe et au niveau intégration. Pas facile d’opter pour l’intégration continue tant la gestion du changement est importante pour passer d’un modèle à l’autre. Il existe des stratégies pour minimiser les problèmes d’intégration, par exemple en mettant en place l’intégration continue à un niveau local, réservé à chaque équipe et minimiser les dépendances (avoir aussi l’article Large-Scale Agile)
6) Grosse fonctionnalité: on peut tomber sur une fonctionnalités assez conséquente, qui nécessite par exemple plusieurs itérations / semaines / mois pour être réalisée. Il semble alors naturel de lui dédier une branche afin de ne pas perturber la branche courante qui embarquerait en fin de sprint une fonctionnalité à moitié terminée. Ce n’est pas la seule possibilité, il faudrait voir si la grosse fonctionnalité ne pourrait pas être découpée en plus petites qui tiennent sur une itération. On peut aussi utiliser la technique du “Feature Toggle” pour activer une fonctionnalité à partir de la configuration (voir explications ici et là) ainsi que celle du “Branch by abstraction” afin de réaliser des changements structurels dans le code source pour, par exemple, accueillir une fonctionnalité concurrente et permettre la disparition à terme de l’ancienne au profit de la nouvelle.
7) Les gestionnaires décentralisés (DVCS): les DVCS encouragent les contributions (n’importe qui peut créer sa branche et emporter une communauté), l’expérimentation et proposent généralement un mode non-connecté très fiable. C’est un cas un peu à part et plutôt hors sujet ici. On peut trouver des discussion sur la toile où ce modèle est discuté pour son utilité en entreprise (voir article).
8) Intégration continue déguisée: qu’un développeur travaille sur la version locale de la branche principale ou bien une branche fonctionnelle revient à la même chose si la remontée du code s’effectue plusieurs fois par jour: c’est compatible avec l’intégration continue.
L’utilisation des branches fonctionnelles est-elle déjà obsolète? Non, bien-sur! Les modèles de branches fonctionnelles sont utilisées dans de nombreuses organisations. Ces modèles, bien rodés au fil des ans, ne doivent pas être sacrifiés sur le désir d’un seul homme. Ces modèles peuvent être adaptés si l’équipe, l’organisation en ressentent le besoin. L’intégration continue apporte son lot d’avantages mais elle n’est pas facile à mettre en place. Au delà des outils, c’est aussi l’organisation qui se trouve bousculée.