Pratiquement tous les systèmes de contrôle de version prennent désormais en charge les branches, c'est-à-dire des lignes de code indépendantes qui proviennent d'une base de code centralisée. Selon votre système de contrôle de version, la branche principale s'appellera mainline, default ou trunk. Les développeurs peuvent créer leurs propres branches à partir de la branche de code principale et les utiliser de façon indépendante.
Pourquoi les branches sont-elles importantes ?
La création de branches facilite, pour les équipes de développeurs, la collaboration au sein d'une même base de code centralisée. Lorsqu'un développeur crée une branche, le système de contrôle de version crée une copie de la base de code à ce moment précis. Les changements apportés à la branche n'affectent pas les autres développeurs de l'équipe. Tout cela est évidemment positif, dans le sens où les fonctionnalités en cours de développement peuvent générer de l'instabilité, ce qui serait extrêmement perturbant si tout le travail était effectué sur la ligne de code principale. Toutefois, les branches n'existent pas en vase clos. Les développeurs peuvent facilement récupérer les changements d'autres développeurs afin de collaborer sur les fonctionnalités et s'assurer que leur propre branche ne s'éloigne pas trop de la principale.
Les branches ne servent pas uniquement à travailler sur les fonctionnalités. Elles peuvent mettre l'équipe à l'abri de changements d'architecture importants, tels que la mise à jour des frameworks, des bibliothèques communes, etc.
Trois stratégies de création de branches pour les équipes agiles
Les modèles de création de branches diffèrent souvent d'une équipe à l'autre. De nombreux débats animent la communauté des développeurs à ce sujet. L'un des thèmes majeurs concerne la quantité de travail qui doit demeurer au sein d'une branche avant de faire l'objet d'un merge dans la branche principale.
Création de branches de livraisons
L'idée sous-jacente à la création de branches de version est qu'une livraison est entièrement contenue dans une branche. Cela signifie que, vers la fin du cycle de développement, le Release Manager créera une branche à partir de la branche principale (par exemple, « branche de développement 1.1 »). Tous les changements apportés pour la livraison 1.1 doivent être appliquées deux fois : une fois à la branche 1.1, puis une fois à la branche principale. L'utilisation de deux branches représente du travail supplémentaire pour l'équipe, et il est facile d'oublier le merge des deux branches. Les branches de version peuvent être complexes et difficiles à gérer, étant donné que beaucoup de personnes travaillent sur les mêmes. Nous avons tous été confrontés à la difficulté de devoir merger un grand nombre de changements différents dans une même branche. Si vous devez créer une branche de version, créez-la en restant aussi proche que possible de la version actuelle.
La création de branches de version est une composante importante de la prise en charge de logiciels versionnés. Un même produit peut compter plusieurs branches de version (par exemple, 1.1, 1.2, 2.0) pour prendre en charge son développement permanent. Gardez à l'esprit que les changements apportés aux livraisons antérieures (par exemple, 1.1) devront peut-être faire l'objet d'un merge avec les branches de version ultérieures (par exemple, 1.2, 2.0). Découvrez notre webinaire ci-dessous pour en savoir plus sur la gestion des branches de version grâce à Git.
Création de branches de fonctionnalités
Les branches de fonctionnalité sont souvent associées à des feature flags, à savoir des « interrupteurs » qui activent ou désactivent une fonctionnalité dans un produit. Cela simplifie le déploiement du code dans la branche principale et permet de contrôler à quel moment la fonctionnalité est activée. Le code peut ainsi être facilement déployé avant que la fonctionnalité ne soit présentée à l'utilisateur final.
L'autre avantage des flags de fonctionnalité réside dans le fait que le code peut rester dans le build, mais demeurer inactif tant qu'il est en développement. Si quelque chose tourne mal alors que la fonctionnalité est activée, un administrateur système peut inverser le flag de fonctionnalité et revenir à un état identifié et satisfaisant, plutôt que de déployer un nouveau build.
Création de branches de tâches
Chez Atlassian, nous nous concentrons sur un workflow de type « une branche par tâche ». Chaque entreprise, de façon naturelle, divise le travail en tâches individuelles dans un outil de suivi des tickets, tel que Jira. Les tickets deviennent alors le point de contact central de l'équipe pour ce travail. La création de branches de tâche, également connue sous le nom de création de branches de ticket, relie directement ces tickets au code source. Chaque ticket est implémenté dans sa propre branche, la clé du ticket étant incluse dans le nom de la branche. Vous pouvez donc facilement déterminer quel code implémente quel ticket : il suffit de regarder la clé de ticket incluse dans le nom de la branche. Avec un tel niveau de transparence, il est plus simple d'appliquer certains changements propres à la branche principale ou à toute branche de version plus ancienne.
La méthodologie Agile étant centrée sur les user stories, les branches de tâche se combinent parfaitement avec le développement Agile. Chaque user story (ou correction de bug) se trouve sur sa propre branche. Il est donc facile de visualiser les tickets en cours et ceux qui sont prêts pour la livraison.
Et maintenant, le double maléfique de la création de branches : le merge
Nous avons tous déjà souffert en tentant d'intégrer plusieurs branches dans une même application. Traditionnellement, les opérations de merge ont toujours été très douloureuses à cause des systèmes centralisés de contrôle des livraisons, tels que Subversion. En revanche, les systèmes plus récents de contrôle des livraisons, comme Git ou Mercurial, adoptent une approche différente en matière de suivi des versions de fichiers évoluant dans différentes branches.
Les branches ont tendance à avoir une durée de vie limitée. Leur merge est donc plus facile et elles sont plus flexibles sur l'ensemble de la base de code. Entre la possibilité de merger, de façon fréquente et automatique, des branches dans le cadre de l'intégration continue (CI) et le fait que les branches, dont la durée de vie est courte, contiennent tout simplement moins de changements, « l'enfer du merge » appartient au passé pour les équipes qui utilisent Git et Mercurial.
C'est ce qui fait l'ingéniosité de la création de branches de tâche !
Validez, validez, validez
Le système de contrôle de version ne peut pas aller plus loin dans la validation du résultat d'un merge. Les tests automatisés et l'intégration continue sont essentiels également. La plupart des serveurs d'intégration continue peuvent tester automatiquement les nouvelles branches, ce qui réduit considérablement le nombre de « surprises » concernant le merge final. Cela contribue également à la stabilité de la ligne de code principale.