Cycle de sortie de société étrange: Go Distributed Source Control?

13

Désolé pour ce long post, mais je pense que ça vaut le coup.

Je viens de commencer avec une petite boutique .NET qui fonctionne un peu différemment des autres endroits où j'ai travaillé. Contrairement à mes positions précédentes, le logiciel écrit ici est destiné à plusieurs clients et tous les clients ne reçoivent pas la dernière version du logiciel en même temps. En tant que tel, il n'y a pas de «version de production actuelle». Lorsqu'un client obtient une mise à jour, il obtient également toutes les fonctionnalités ajoutées au logiciel depuis sa dernière mise à jour, ce qui pourrait être il y a longtemps. Le logiciel est hautement configurable et les fonctionnalités peuvent être activées et désactivées: ce que l'on appelle des «basculements de fonctionnalités». Les cycles de publication sont très serrés ici, en fait ils ne sont pas planifiés: lorsqu'une fonctionnalité est terminée, le logiciel est déployé chez le client concerné.

L'an dernier, l'équipe est passée de Visual Source Safe à Team Foundation Server. Le problème est qu'ils utilisent toujours TFS comme s'il s'agissait de VSS et appliquent des verrous Checkout sur une seule branche de code. Chaque fois qu'un correctif de bogue est mis sur le terrain (même pour un seul client), ils construisent simplement tout ce qui se trouve dans TFS, teste le bogue a été corrigé et déploie le client! (Moi-même issu d'un arrière-plan de logiciels pharmaceutiques et d'appareils médicaux, c'est incroyable!). Le résultat est que le code de développement à moitié cuit est mis en production sans même être testé. Les bogues glissent toujours dans les versions, mais souvent un client qui vient de recevoir une version ne verra pas ces bogues s'il n'utilise pas la fonctionnalité dans laquelle il se trouve. Le directeur sait que c'est un problème car la société commence à se développer tous d'un coup avec l'arrivée de gros clients et d'autres plus petits.

On m'a demandé d'examiner les options de contrôle des sources afin d'éliminer le déploiement de bogues ou de code inachevé, mais de ne pas sacrifier la nature quelque peu asynchrone des versions des équipes. J'ai utilisé VSS, TFS, SVN et Bazaar dans ma carrière, mais TFS est l'endroit où la plupart de mon expérience a été.

Auparavant, la plupart des équipes avec lesquelles j'ai travaillé utilisent une solution à deux ou trois branches de Dev-Test-Prod, où pendant un mois les développeurs travaillent directement dans Dev et ensuite les modifications sont fusionnées dans Test puis Prod, ou promues "quand c'est fait" plutôt que sur un cycle fixe. Des versions automatisées ont été utilisées, à l'aide du régulateur de vitesse ou de la constitution d'équipe. Dans mon travail précédent, Bazaar était utilisé assis sur le dessus de SVN: les développeurs ont travaillé dans leurs propres petites branches de fonctionnalités, puis ont poussé leurs changements vers SVN (qui était lié à TeamCity). C'était bien car il était facile d'isoler les changements et de les partager avec les branches d'autres peuples.

Avec ces deux modèles, il y avait une branche centrale de développement et de production (et parfois de test) à travers laquelle le code était poussé (et des étiquettes étaient utilisées pour marquer les builds dans la prod à partir desquelles les versions étaient faites ... et celles-ci étaient transformées en branches pour corriger les bogues) vers les versions et fusionné en dev). Cependant, cela ne convient pas vraiment à la façon de travailler ici: il n'y a pas d'ordre quand différentes fonctionnalités seront publiées, elles sont poussées lorsqu'elles sont terminées.

Avec cette exigence, l'approche «d'intégration continue» telle que je la vois se décompose. Pour sortir une nouvelle fonctionnalité avec une intégration continue, elle doit être poussée via dev-test-prod et qui capturera tout travail inachevé dans dev.

Je pense que pour surmonter cela, nous devrions descendre dans un modèle ramifié fortement doté de PAS de branches dev-test-prod, plutôt que la source devrait exister sous la forme d'une série de branches de fonctionnalités qui, lorsque le travail de développement est terminé, sont verrouillées, testées, fixes, verrouillées , testé puis publié. D'autres branches de fonctionnalités peuvent saisir les modifications d'autres branches quand elles en ont besoin / veulent, donc finalement toutes les modifications sont absorbées par tous les autres. Cela correspond très bien à un pur modèle Bazaar de ce que j'ai vécu lors de mon dernier emploi.

Aussi flexible que cela puisse paraître, il semble étrange de ne pas avoir de branche de tronc de développement ou de production quelque part, et je crains que les branches ne se réintègrent jamais, ou que de petites modifications tardives ne soient jamais transmises à d'autres branches et que les développeurs se plaignent fusionner des catastrophes ...

Que pensent les gens à ce sujet?

Une deuxième dernière question: je suis quelque peu confus quant à la définition exacte du contrôle de source distribué: certaines personnes semblent suggérer qu'il s'agit simplement de ne pas avoir de référentiel central comme TFS ou SVN, certains disent qu'il s'agit d'être déconnecté (SVN est déconnecté à 90% et TFS a un mode hors ligne parfaitement fonctionnel) et d'autres disent qu'il s'agit de la fonction Branching et de la facilité de fusion entre les branches sans relation parent-enfant (TFS a également une fusion sans fondement!). C'est peut-être une deuxième question!

MrLane
la source
Lecture suggérée VSS: dangereux à n'importe quelle vitesse .
Spencer Rathbun

Réponses:

5

Qu'est-ce qui définit un DVCS?

Le distribué dans DVCS signifie que chaque clone d'un référentiel possède toutes les informations nécessaires pour valider, mettre à jour, créer une branche, fusionner ou rechercher une révision dans ce référentiel, sans jamais toucher à un serveur . La seule chose que vous pouvez faire hors ligne svnest en fait de modifier les fichiers - vous avez besoin d'un accès au serveur pour presque toutes les svncommandes, y compris faire quelque chose d'aussi simple que de saluer svn log, donc il est en fait plus proche de 0% que de 90%!

Tout référentiel central faisant autorité que vous pourriez configurer dans un flux de travail DVCS n'est qu'un autre clone , et la seule fois où vous devez interagir avec celui-ci est lorsque vous tirez vers le bas les mises à jour d'autres personnes ou lorsque vous appuyez sur vos propres modifications afin que d'autres personnes puissent les voir , à peu près tout le reste peut être fait hors ligne.

Quel modèle de branchement est approprié?

J'ai été dans la situation dans laquelle vous vous trouvez en ce moment. De tels systèmes peuvent être une vraie douleur, mais vous devez comprendre les raisons pragmatiques pour lesquelles ils sont devenus ainsi et réaliser qu'ils ne sont pas au-delà de la rédemption . De nombreux outils ont été développés qui peuvent aider à gérer ce type de complexité .

Tout d'abord, quoi que vous fassiez, ne montrez pas aux gens le modèle de branchement git réussi , cela les confondra et les désactivera. Au lieu de cela, développez votre propre modèle qui reflète votre flux de travail existant , tout en résolvant les problèmes avec votre flux de travail existant .

Certaines ressources que vous voudrez peut-être envisager incluent des éléments comme les sous-modules git qui permettront à différentes versions client de spécifier différentes combinaisons de configuration client, de modules d'application et de bibliothèques. Une autre option serait l'utilisation d'un système de gestion des correctifs pour appliquer des files d'attente de correctifs spécifiques au client / produit.

Ces deux options offriront une flexibilité, une transparence et une sécurité beaucoup plus grandes que votre flux de travail actuel, et pourraient être plus faciles à utiliser qu'une stratégie de branche encore plus complexe. Je souhaiterais certainement avoir accès à ces outils lorsque j'étais dans votre situation.

Pour plus d'informations sur ces options, consultez mes réponses à Stratégie pour utiliser le contrôle de version sur un système modulaire , Comment utiliser le référentiel Subversion dans le référentiel Git? et contrôle de source / version pour l'application utilisée par plusieurs sociétés .

En fin de compte, c'est vraiment quelque chose que vous devrez développer avec le reste de l'équipe. Si vous avez la vision de proposer quelque chose qui fonctionne mieux que ce que vous avez déjà et qui peut obtenir l'adhésion de vos collègues développeurs, alors vous aurez beaucoup plus de facilité.

Le plus important est de montrer à vos collègues comment ce que vous proposez leur facilitera la vie . Une fois qu'ils sont convaincus, vous avez de bien meilleures chances que la direction abandonne son investissement dans TFS et commence à utiliser un modèle plus adapté à vos méthodes de travail.

Mark Booth
la source
1
+1 pour trouver le modèle de branchement git réussi qui fonctionne pour vous
jcmeloni
1
+1 pour "leur faciliter la vie". C'est le principal facteur de motivation.
5

Premièrement, DVCS est un redoutable pour les problèmes que vous rencontrez - l'outil de contrôle de version utilisé n'est pas à l'origine des problèmes à résoudre. Il se peut que certains aspects des solutions DVCS soient «meilleurs» que TFS, mais ce n'est pas ce qui doit être corrigé à ce stade.

Vous avez identifié que vous avez besoin d'une structure de branchement fonctionnelle qui convient à votre organisation - je pense que vous constaterez que vous avez toujours un tronc, lorsqu'une fonctionnalité est terminée, elle est réintégrée dans le tronc et fermée. Il existe également de bonnes réflexions sur la façon dont vous implémentez les dépendances communes.

Vous devez également faire fonctionner l'intégration en continu (aucune raison de ne pas avoir de build automatisé pour chaque branche active pour vous donner l'assurance que vous pouvez construire cette branche et qu'elle réussit les tests appropriés). Je suis mal à l'aise lorsqu'un commit (ou au moins un "push") ne déclenche pas de build pour moi.

Et vous devez commencer par des tests automatisés à tous les niveaux, mais surtout des tests unitaires et des tests d'intégration pour commencer à réduire les risques de nouveaux bogues qui s'échappent dans la nature. Ce dernier est énorme et quelque chose avec lequel je lutte toujours, mais il est clair qu'une fois que vous savez que vous pouvez construire des choses, cela aura le plus de valeur.

Vous devez combiner cela en vous assurant que vos packages de déploiement proviennent de votre serveur de génération et que le déploiement est automatisé autant que possible (vous devriez pouvoir passer de l'artefact du serveur de génération au code déployé en direct avec un minimum d'effort et un minimum de stress).

Hmm, j'ai supposé qu'il y avait une bonne configuration de suivi des problèmes bien ordonnée ... vous en avez besoin aussi et pour être sûr qu'elle est utilisée correctement. Idéalement, vous souhaitez que vos applications en direct répercutent automatiquement les erreurs sur ce système (ou pour le triage).

Enfin, n'essayez pas de résoudre tous vos problèmes à la fois - la construction et le test me semblent être les endroits sur lesquels vous devriez vous concentrer en premier.

Murph
la source
Il y a une partie de moi qui est d'accord pour dire que le DVCS peut aussi être un redingue: je suis certainement d'accord que le problème concerne le processus plus qu'autre chose. Je pense que l'intégration continue peut être un tronçon ici et que les tests unitaires ne vont tout simplement pas se produire car cela sera considéré comme trop de travail. La base de code n'est pas testable de toute façon car c'est un système monolithique étroitement couplé et tout est basé sur des types conrete: pas d'interfaces.
MrLane
@MrLane - Je sais que ça va être difficile d'expliquer cela aux gens, mais depuis que j'ai commencé à développer de manière TDD , je suis de plus en plus convaincu que je n'ai pas le temps de ne pas écrire de tests.
Mark Booth
1

La deuxième question est plus simple et plus courte, je vais donc essayer de partir de là

DVCS est un système où aucune source de code "faisant autorité" (sauf "sur accord", lorsqu'il est utilisé) et l'échange de données P2P est possible sans niveaux supplémentaires (définition personnelle et non canonique)

Sur le sujet la première question

Je crains que l'entreprise ne doive reconstruire le flux de travail et repenser le style afin d'obtenir un "code en quelque sorte géré et prévisible". Je ne peux pas dire à propos de TFS (sauf opinion personnelle et sentiment, qu'il s'agit d'un système faible dans la partie Contrôle de version / la fusion sans fondement est mauvaise /), mais pour tout VCS dans votre situation ("Produit" est un ensemble de "Modules" indépendants, chaque "Client" obtient des "Produits" différents - cette hypothèse est-elle correcte?) Je préférerai le développement fractionné des modules en branches distinctes, avoir le produit comme "Supermodule" (également branche?), chaque module étant lié à une révision spécifique du module- branch, module-development utilise le paradigme branch-per-task (et module-branch consiste uniquement en mergesets).

De cette façon, vous pouvez toujours savoir quelle "Collection" (c'est-à-dire l'ensemble de modules et leurs révisions correspondantes) forme chaque "Produit", avez la possibilité de faire du CI (pour les branches de tâches terminées et fusionnées ), des tests unitaires et des builds

Blaireau paresseux
la source
1

Question principale de l'annonce: je pense que ce dont vous parlez est exactement de quoi parle le modèle de branchement réussi git (et le flux d'aide git pour le soutenir). Avoir une branche principale, qui est toujours dans un état déployable et faire tout le travail sur les branches de fonctionnalités.

Vous pouvez également utiliser le processus utilisé par git lui-même, qui dérive du même principe de base. Dans le développement git-core, tout le travail se fait sur les branches de fonctionnalités. Les branches de fonctionnalités sont soumises à l'intégrateur, qui exécute un script pour les fusionner toutes afin de créer une branche nommée pu(mises à jour proposées). Diverses personnes prennent cette branche et travaillent avec elle pour la tester.

Au lieu d'intégrateur, vous pouvez demander au serveur d'intégration continue d'effectuer cette fusion au début d'une génération. De cette façon, chaque fois qu'un membre de l'équipe envoie des modifications au référentiel central en tant que branche de fonctionnalité (en utilisant probablement une convention de dénomination pour indiquer les branches à sélectionner).

Dans git, la branche de fonctionnalité se poursuit next, masterou maintselon la version sur laquelle elle cible (maint pour la correction de la version actuelle, master pour la version en cours de préparation et la suivante pour celle qui suit), mais vous n'en aurez pas autant.

Bien que les fonctionnalités soient présentes pu("cuisson" dans la terminologie de Git Maintenir), elles sont rembobinées et la pubranche est supprimée et recréée à chaque fois, ce qui la rend plus facile à examiner, mais ne convient pas pour baser d'autres travaux. Lorsque la branche de fonctionnalité est fusionnée dans l'une des lignes principales, elle est fermée pour les rembobinages et d'autres correctifs sont effectués en tant que nouveaux validations.

Personnellement, je recommanderais le gitmieux. C'est un peu plus difficile à apprendre au début, car il se développe plus organiquement, mais au final il semble le plus flexible. Mais l'un des trois systèmes distribués, git, mercurial et bazaar vous servira bien (et vous pouvez souvent même les mélanger, par exemple mercurial peut tirer et pousser vers / depuis le dépôt git et je pense que bazaar peut aussi).

Ad deuxième question: on m'a appris que "distribué", en général, signifie que vous pouvez déplacer des objets et qu'ils gardent leur identité. C'est exactement ce que fait le contrôle de version distribué: vous clonez le référentiel et il contient les mêmes commits et permet de faire les mêmes choses avec eux. La facilité de branchement et le fonctionnement déconnecté sont les principales fonctionnalités de niveau utilisateur qui découlent du principe de déplacement des commits et de la disposition de graphique dirigée qui le permet.

Jan Hudec
la source
1

Malheureusement, il n'y a pas de solution connue aux bugs dans le code :)

Donc, vous cherchez simplement à empêcher les enregistrements inachevés d'être rattrapés dans la version principale, et la seule réponse à cela est la fusion de travail de branche pour chaque développeur. Je l'ai fait dans une entreprise précédente utilisant Clearcase, cela fonctionnait assez bien (même si nous devions avoir une douzaine d'administrateurs clearcase).

Maintenant, je suppose également que vous effectuez la correction de bogues sur la version du produit que chaque client a actuellement ... vous avez donc un problème de fusion apportant des corrections de bogues de la version A à la version Z. Il n'y a pas de moyen facile de gérer cela, mais vous devrez avoir une branche pour chaque version livrée. La meilleure façon de résoudre ce problème est de conserver les branches de fonctionnalités uniquement sur la dernière version et de faire en sorte que les clients mettent à niveau pour obtenir les nouvelles fonctionnalités, en même temps, effectuer la correction de bogues directement sur la branche de publication et les fusionner vers le haut avec toutes les autres branches de version une fois terminé.

Pas trop sympa, mais ça peut fonctionner remarquablement bien. Vous gardez le code organisé et bien séparé. Il est également facile à comprendre pour les autres développeurs - de petites corrections de bugs directement sur "le code", rien de plus que quelques lignes sont effectuées sur une branche dédiée où elles peuvent prendre autant de temps qu'elles le souhaitent. (vous devrez trier les problèmes de fusion et les rassurer que tout va bien si 2 développeurs travaillent sur 2 fonctionnalités en même temps !!)

Après un certain temps, vous pouvez également introduire des branches de fonctionnalités sur les branches de publication, où les bugs sont corrigés puis fusionnés, mais à mon humble avis, cela représente généralement plus d'efforts que nécessaire. Si vous devez ajouter des fonctionnalités aux anciennes versions, vous devrez suivre cette approche - branchez une branche de version, puis fusionnez le code dans cette version et fusionnez la modification vers le haut vers les versions ultérieures également. Cela rendra votre équipe de test très mécontente car les versions seront fortement retardées en raison de la nécessité de tester plusieurs versions à plusieurs reprises, et l'équipe de développement mécontente car elle devra faire beaucoup de fusion avant de pouvoir commencer avec un nouveau code (dans mon entreprise actuelle). cela se produit, principalement en raison de la quantité de travail que nous avons qui doit toujours être terminée dès que possible).

DVCS:

Fondamentalement, un DVCS est l'endroit où chacun a sa propre copie du référentiel du serveur. Il présente certains avantages (en particulier dans les équipes distribuées avec une communication limitée), mais présente également des inconvénients, alors vérifiez-les avant de passer à un DVCS. Si vous êtes une boutique Windows, vous trouverez probablement que Mercurial est le meilleur DVCS pour vous.

gbjbaanb
la source