Question

Lors de la livraison d'une nouvelle version, notre politique consiste à créer une branche dans notre VCS et à la gérer pour notre équipe d'assurance qualité. Lorsque ce dernier donne son feu vert, nous étiquetons et publions notre produit. La branche est conservée pour recevoir (uniquement) les corrections de bugs afin que nous puissions créer des versions techniques. Ces corrections de bogues sont ensuite fusionnées sur le coffre.

Pendant ce temps, le coffre voit le travail de développement principal et est potentiellement sujet à des modifications de refactoring.

Le problème est qu’il existe une tension entre la nécessité de disposer d’une jonction stable (pour que la fusion des corrections de bogues réussisse). Cela ne peut généralement pas se produire si le code a été extrait, par exemple, vers une autre méthode, ou déplacé vers une autre. classe) et la nécessité de la refactoriser lors de l’introduction de nouvelles fonctionnalités.

La politique à notre place est de ne pas refactoriser avant que le temps imparti soit écoulé et que la succursale soit suffisamment stable. Dans ce cas, on peut commencer à refactoriser les modifications sur le tronc et les corrections de bugs doivent être validées manuellement sur le tronc et la branche.

Mais cela signifie que les développeurs doivent attendre longtemps avant de valider sur le tronc tout changement de refactoring, car cela pourrait interrompre la fusion ultérieure de la branche au tronc. Et avoir à porter manuellement les bogues de la branche dans le coffre est douloureux. Il me semble que cela entrave le développement ...

Comment gérez-vous cette tension?

Merci.

Était-ce utile?

La solution

C’est un vrai problème pratique. La situation empire si vous avez plusieurs versions à prendre en charge et que vous avez créé une branche pour chacune d’elles. Pire encore si vous avez également une véritable branche R & D.

Ma préférence était de permettre au tronc principal de continuer à son rythme normal et de ne pas tenir le coup car, dans un environnement où les délais de publication étaient importants sur le plan commercial, je ne pouvais jamais prétendre que nous devrions laisser le code se stabiliser (& what; , vous voulez dire que vous l'avez publié dans un état instable? ").

La clé était de s’assurer que les tests unitaires créés pour les correctifs de bogues étaient transférés lors de la migration du bogue dans la branche principale. Si vos nouveaux changements de code ne sont vraiment que de la refonte, alors les anciens tests devraient fonctionner aussi bien. Si vos modifications sont telles qu'elles ne sont plus valides, vous ne pouvez pas simplement porter le correctif que vous corrigez et vous devrez demander à quelqu'un de réfléchir sérieusement à la correction dans le nouveau flux de code.

Après avoir passé de nombreuses années à gérer ce type de problème, j’ai conclu qu’il fallait probablement au minimum 4 flux de code pour fournir une assistance et une couverture appropriées, ainsi qu’un ensemble de processus assez rigoureux pour gérer le code. C'est un peu comme le problème de pouvoir dessiner n'importe quelle carte en 4 couleurs.

Je n'ai jamais trouvé de très bonne littérature sur ce sujet. Cela sera inévitablement lié à votre stratégie de publication et aux accords de niveau de service que vous signez avec vos clients.

Addendum: je devrais également mentionner qu'il était nécessaire d'écrire la branche fusionnée en tant que jalons spécifiques dans le calendrier de publication de la branche principale. Ne sous-estimez pas la quantité de travail qui pourrait être nécessaire pour rassembler vos branches si vous avez un ensemble de développeurs travaillant dur qui mettent en œuvre les fonctionnalités.

Autres conseils

Là où je travaille, nous créons des branches de travail temporaires, de courte durée (moins de quelques jours) pour chaque changement non trivial (ajout de fonctionnalité ou correction de bug). Le coffre est stable et (idéalement) potentiellement libérable à tout moment; seuls les éléments réalisés sont fusionnés dans celui-ci. Tout ce qui est commis du tronc est fusionné tous les jours dans les branches en activité; cela peut être en grande partie automatisé (nous utilisons Hudson, Ant et Subversion). (Ce dernier point, car il est généralement préférable de résoudre les conflits le plus tôt possible, bien entendu.)

Le modèle actuel que nous utilisons a été largement influencé par un excellent article ( Contrôle de version pour plusieurs équipes agiles .

(Dans notre cas, nous avons deux équipes Scrum travaillant sur une base de code, mais je pense que ce modèle peut être bénéfique même avec une seule équipe.)

Les ramifications et les fusions supplémentaires sont un peu fastidieux, mais pas vraiment, une fois que vous vous y êtes habitué et que vous vous êtes amélioré avec les outils (par exemple, svn merge --reintegrate est pratique) . Et non, je ne crée pas toujours de branche temporaire, par exemple. pour les refactorisations plus petites et à faible risque (sans lien avec les principaux éléments actuellement à l’étude) qui peuvent facilement être complétées avec un seul engagement dans le coffre.

Nous conservons également une branche de version plus ancienne dans laquelle les bogues critiques sont corrigés de temps à autre. Certes, il peut y avoir un travail de fusion manuel (parfois fastidieux) si une partie particulière du code a considérablement évolué dans le tronc par rapport à la branche. (Cela, espérons-le, devient moins problématique à mesure que nous progressons vers la libération continue d'incréments du coffre (en interne), et en laissant le marketing et la gestion des produits décider quand ils souhaitent effectuer une sortie externe.)

Je ne sais pas si cela répond directement à votre question ou si vous pouvez l'appliquer à votre environnement (avec l'équipe d'assurance de la qualité séparée et tous) - mais au moins, je peux dire que la tension que vous décrivez n'existe pas pour nous. et nous sommes libres de refactoriser à tout moment. Bonne chance!

Je pense que la tension peut être gérée en ajoutant les ingrédients suivants à votre processus de développement:

  1. Intégration continue
  2. Tests fonctionnels automatisés (je suppose que vous comptez déjà avec les tests unitaires)
  3. Livraison automatisée

Avec l'intégration continue, chaque commit implique une construction dans laquelle tous les tests unitaires sont exécutés et vous êtes averti en cas de problème. Vous commencez à travailler davantage avec head et vous êtes moins enclin à créer des branches dans la base de code.

Grâce aux tests fonctionnels automatisés, vous pouvez tester votre application en un clic. Généralement, comme ces tests prennent plus de temps, ils sont effectués tous les soirs. Avec cela, le rôle classique du contrôle de version commence à perdre de l'importance. Vous ne décidez pas du moment de la publication en fonction de la version et de sa maturité, mais plutôt de la décision commerciale. Si vous avez mis en œuvre des tests unitaires et fonctionnels et que votre équipe soumet du code testé, head doit toujours indiquer le statut pouvant être publié. Les bugs sont continuellement découverts et corrigés et libérés, mais ce n’est plus un processus cyclique, c’est le processus continu.

Vous aurez probablement deux types de détracteurs, car cela implique de changer certaines pratiques. Premièrement, le changement de paradigme de la distribution continue semble contre-intuitif aux gestionnaires. «Ne risquons-nous pas d’acheminer un bogue majeur?» Si vous jetez un coup d’œil aux distributions Linux ou Windows, c’est exactement ce qu’elles font: envoyer des communiqués aux clients. Et puisque vous comptez avec une suite de tests automatisés, les dangers sont encore réduits.

Ensuite, équipe ou service d’assurance qualité. (Certains diront que le problème est leur existence même!) Ils seront généralement hostiles à l'automatisation des tests. Cela signifie apprendre un nouvel outil parfois compliqué. Ici, le mieux est de prêcher en le faisant. Notre équipe de développement a commencé à travailler sur des intégrations continues et à rédiger simultanément une suite de tests fonctionnels avec Selenium . Quand l'équipe d'assurance qualité a vu l'outil en action, il était difficile de s'opposer à sa mise en œuvre.

Enfin, le processus que j’ai décrit n’est pas aussi simple qu’ajouter des ingrédients à votre processus de développement. Cela implique un changement profond dans la façon dont vous développez un logiciel.

Peut-être que Git (ou un autre DVCS) gère mieux les fusions en code mis à jour, car il gère (vraiment) les modifications plutôt que de simplement comparer des fichiers ... Comme Joel dit :

  

Avec le contrôle de version distribué, les fusions sont simples et fonctionnent bien. Vous pouvez donc avoir une branche stable et une branche de développement, ou créer des branches de longue durée pour votre équipe d'assurance de la qualité où elles testent des éléments avant le déploiement, ou vous pouvez créer des branches de courte durée pour tester de nouvelles idées et voir leur fonctionnement.

Pas encore essayé, cependant ...

Là où je travaille, nous gardons le refactoring dans la branche principale. Si les fusions deviennent difficiles, il suffit de les traiter de manière ponctuelle, elles sont toutes réalisables, mais prennent parfois un peu de temps.

Peut-être que notre problème vient du fait que nous avons des branches qui doivent avoir une longue vie (jusqu’à 18 mois) et que de nombreuses solutions doivent être apportées contre elles.

Faire en sorte de ne créer que des branches extrêmement codées nous aiderait probablement, mais ne serait pas si facile ...: (

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top