Je viens de recevoir un appel rétro où les développeurs ont exprimé leur inquiétude quant à l'intégration de leurs histoires dans la branche principale à chaque sprint. Les développeurs codent tous dans leur propre branche et vers la fin du sprint, ils fusionnent tous dans une branche principale.
Ensuite, il reste à un développeur (généralement le même) la tâche de s'assurer que tout s'est bien intégré au code des autres développeurs (la plupart des modifications sont sur la même page. Par exemple, une histoire d'affichage de données, une histoire de filtrage de données et a SLA).
Comment pouvons-nous réduire ce fardeau et faciliter la fusion de notre code? De mon point de vue, demander au PO ou au SM de hiérarchiser les histoires de manière plus efficace afin que nous n'ayons pas ce type de dépendances dans le même sprint peut résoudre certains des problèmes. Comment tout le monde aborde-t-il cela? Ou est-ce juste une partie du processus?
Si vous utilisez Git, chaque développeur tirera de la branche develop
dans sa propre branche de fonctionnalité afin de s'assurer qu'il n'aille pas trop loin de la ligne de base actuelle. Ils peuvent le faire quotidiennement, de sorte que les tâches qui prennent plus de quelques jours restent synchronisées et que les problèmes de fusion soient résolus alors qu'ils sont encore petits.
Lorsque le développeur a terminé son travail, il crée un pull request. Une fois approuvé, il est fusionné dans la branche develop
.
La branche develop
doit toujours avoir du code fonctionnel et être prête à être publiée à tout moment. Lorsque vous effectuez réellement une version, vous fusionnez develop
dans master
et le marquez.
Si vous disposez d'un bon serveur d'intégration continue, il créera chaque branche lorsque les modifications seront archivées, en particulier pour les demandes d'extraction. Certains serveurs de build s'intègrent à votre serveur Git pour approuver ou refuser automatiquement une demande d'extraction si la build échoue ou que les tests automatisés échouent. C'est une autre façon de trouver des bogues d'intégration potentiels.
J'ai travaillé dans une équipe où nous avons eu du mal avec le même problème. Nous avons constaté que moins nous avions de temps avant l'intégration, moins cela devenait difficile. Je sais que la plupart des gens qui enseignent l'intégration continue parlent d'engager toutes les quelques minutes - nous nous sommes probablement engagés toutes les heures environ.
Nous avons également constaté que la construction ne suffisait pas. Nous avions besoin d'un bon niveau de couverture de test afin de nous assurer que nous ne rompions pas accidentellement le code des autres.
Vous n'avez même pas besoin de vous abonner à TDD pour celui-ci. Tout ce dont vous avez besoin, ce sont des tests qui prouvent que les fonctionnalités de vos développeurs fonctionnent correctement. Il peut s'agir de tests unitaires et de tests d'intégration, mais il s'agira idéalement de deux tests automatisés de bout en bout des fonctionnalités critiques. Trucs de pack de régression standard.
Ensuite, une fois votre fusion terminée, vous pouvez vérifier ensemble le rapport de test d'automatisation et vérifier que tout a bien été intégré.
Je suis d'accord avec l'une des autres réponses où l'auteur a déclaré que les PR Git résoudraient ce problème en amenant chaque développeur à fusionner son propre travail.
Un autre point qui, à mon avis, est suffisamment important pour rester jusqu'au dernier paragraphe. Je vous suggère d'exécuter des tests manuels sur vos versions nocturnes, plutôt que d'attendre la fin du sprint. Les développeurs doivent fusionner dès que la fonctionnalité est terminée afin qu'elle puisse être intégrée, déployée et testée dès que possible.
Ne pas
Selon votre langue et les fichiers que vous modifiez, il peut ne pas être judicieux pour chaque développeur de les modifier sur sa propre branche. Par exemple, en C #, j'ai trouvé qu'il était préférable qu'une seule personne modifie des fichiers de concepteur d'interface utilisateur à la fois. Ce sont des fichiers générés automatiquement, et donc le code est parfois déplacé sans raison apparente - et cela fait des ravages sur la plupart des outils de fusion.
Cela signifie que certaines histoires peuvent bloquer d'autres histoires jusqu'à ce que le travail de l'interface utilisateur soit terminé. Et/Ou, une nouvelle histoire est créée pour simplement mettre en page l'interface utilisateur, avec les autres histoires implémentant des fonctionnalités. Ou, peut-être qu'un développeur fait tout le travail de l'interface utilisateur tandis que d'autres implémentent la fonctionnalité de cette interface utilisateur.
Sur une note connexe, si vous savez que plusieurs histoires toucheront toutes le (s) même (s) fichier (s), vous voudrez peut-être simplement éviter de les travailler toutes en même temps. Ne les tirez pas tous dans le même sprint, ou ne commencez pas à tous les travailler avant d'en avoir terminé un ou plusieurs.
Une autre approche possible pour éviter les fusions tardives et importantes est les indicateurs de fonctionnalité : vous protégez vos modifications avec un indicateur configurable (idéalement dynamiquement) qui les empêche de devenir actifs avant prévu.
Cela vous permet de fusionner rapidement vos modifications dans master
ou votre branche de développement conjoint sans rien casser. D'autres développeurs peuvent ensuite fusionner ces modifications dans leurs branches de fonctionnalités (ou rebaser leurs branches en conséquence).
Comme les autres réponses l'ont déjà souligné, cela devrait être combiné avec une solution d'intégration continue.
Les indicateurs de fonctionnalité présentent des avantages supplémentaires (par exemple, ils facilitent les tests A/B). Voir cet article de Martin Fowler pour plus d'informations.
Nous suivons une approche de branche de développement distincte pour chaque fonctionnalité, puis nous fusionnons les branches en une branche QA pour les tests dans l'environnement de test d'intégration.
Une fois les tests de régression et d'intégration terminés, nous déplaçons facilement les fonctionnalités prêtes à l'emploi, dans la branche de publication.
Si tout se passe bien, nous fusionnons la branche release vers la branche master.
En termes simples, la validation et la fusion réduisent souvent la fenêtre d'opportunité des conflits de fusion et réduisent considérablement les conflits. L'autre partie est en effet la planification par le chef de file, qui peut en outre garantir le bon déroulement du travail.
Les autres réponses donnent un excellent aperçu des meilleures pratiques pour les validations et simplement en les suivant, vous réduirez probablement la grande majorité de vos problèmes de fusion. Plus de fusions sont presque certainement une nécessité, mais pour une équipe plus petite, votre approche branche par personne fonctionne probablement assez bien. Bien sûr, cela ne fait pas de mal (beaucoup) de se lancer dans des pratiques plus extensibles!
Cependant, personne ne semble avoir répondu à l'une de vos questions les plus importantes - que faire lorsque vous touchez tous les mêmes zones de code. C'est là qu'il est utile d'avoir un responsable connaissant la base de code et capable de reconnaître les dépendances de différentes tâches. S'ils n'orchestrent pas le calendrier du travail et les validations, vous vous retrouverez probablement avec des conflits de fusion et une résolution ligne par ligne. Organiser les tâches\le calendrier est beaucoup plus difficile avec une équipe plus grande, mais avec une petite équipe, il est possible d'identifier ces tâches conflictuelles. Le chef de file pourrait alors même confier toutes les tâches connexes au même ingénieur, pour éviter complètement le conflit.