Comment réaliser une transition en douceur du modèle d'organisation «le seul grand référentiel VCS pour tous les produits» au modèle «de nombreux petits référentiels VCS»?

15

C'est un scénario courant que la base de code d'un produit détenu par un dans un système VCS évolue à un point où cette base de code peut sans doute être considérée comme contenant plusieurs produits. La division de la base de code entre plusieurs référentiels VCS, chacun dédié à un seul produit, peut tirer parti de plusieurs avantages (voir Avantages d'avoir un produit par référentiel VCS par rapport au modèle de référentiel gonflé ci-dessous). Sur le plan technique, le fractionnement de la base de code est une étape assez facile car la plupart des VCS prennent en charge cette opération. La scission pourrait toutefois soulever des problèmes d'ingénierie liés aux tests automatisés, à la livraison continue, à l'intégration ou à la surveillance des services (voir Problèmes soulevés par la scission.) Les organisations qui envisagent d'effectuer une telle division doivent donc savoir comment effectuer cette transition aussi facilement que possible, c'est-à-dire sans interrompre leur livraison et leur pipeline de surveillance. La première étape consiste probablement à mieux comprendre la notion de projet et comment délimiter la scission dans une base de code monolithique.

Dans les réponses à ces questions, j'aimerais voir:

  1. Une tentative de donner une définition pratique de ce qu'est un produit, qui donne des critères pratiques pour délimiter réellement des produits dans une base de code existante.

  2. Selon cette définition de travail, élaborez un plan qui effectue réellement la scission. Nous pouvons faire l'hypothèse simplificatrice que la base de code est traitée par un entièrement automatisé implémentant et . En d'autres termes, chaque branche est validée par une suite de tests automatisée implémentée dans la base de code actuelle et chaque fusion avec une branche «magique» génère qui sont testés et déployés. ( Les artefacts du produit sont, par exemple , les archives tar sources, la documentation, les progiciels binaires, les images Docker , les AMI, les unikernels.)

  3. Un tel plan est satisfaisant s’il explique comment contourner le

Problèmes soulevés par la scission

  1. Quel est le lien entre les procédures de test automatisées et le référentiel monolithique préexistant et les référentiels fractionnés?

  2. Comment les procédures de déploiement automatisé sont-elles liées au référentiel monolithique préexistant et aux référentiels fractionnés?

  3. Où est stocké le code des procédures de déploiement automatisées elles-mêmes?

  4. Où se trouvent l' stockée , la et stratégies de ?

  5. Comment s'assurer qu'un développeur n'a besoin que d'une seule base de code à la fois (mais utilise éventuellement des artefacts provenant d'autres bases de code).

  6. Comment un outil comme git-bissect


Note marginale: Avantages d'avoir un produit par référentiel VCS par rapport au modèle de référentiel de ballonnement

Le fait d'avoir plusieurs petits référentiels contenant la base de code pour un produit spécifique présente les avantages suivants par rapport à l'approche du «référentiel gonflé»:

  1. Avec un référentiel gonflé, il est difficile d'annuler une version lorsqu'un produit est instable, car l'historique est mélangé avec un autre historique de produit.

  2. Avec un référentiel pléthorique, il est difficile de revoir l'historique ou les pulls du projet, avec de petits référentiels, nous sommes plus susceptibles de lire ces informations. (Cela peut être spécifique à VCS comme git, où contrairement à svn, nous ne pouvons pas extraire les sous-arbres!)

  3. Avec un dépôt de ballonnement, nous devons faire beaucoup plus de branch-dance lorsque nous nous développons. Si nous avons N référentiels, nous pouvons travailler en parallèle sur N branches, si nous n'avons qu'un seul référentiel, nous ne pouvons travailler que sur une seule branche, ou avoir une charge de copies de travail qui sont également très compliquées à gérer.

  4. Avec plusieurs petits référentiels, les journaux donnent une carte thermique du projet. Ils peuvent même être utilisés comme proxy de diffusion des connaissances dans l'équipe de développement: si je ne me suis pas engagé dans le repo X depuis 3 mois, il pourrait être bon de m'affecter dans une équipe travaillant sur le repo X pour que je reste au courant des développements dans ce composant.

  5. Avec de petits référentiels, il est plus facile d'avoir une vue d'ensemble claire d'un composant. Si tout se passe dans un seul grand référentiel, il n'y a pas d'artefact tangible délimitant chaque composant, et la base de code peut facilement dériver vers la grosse boule de boue .

  6. Les petits référentiels nous obligent à travailler sur les interfaces entre les composants. Mais comme nous voulons avoir une bonne capsulation, c'est un travail que nous devons faire de toute façon, donc je considérerais cela comme un avantage pour les petits référentiels.

  7. Avec plusieurs petits référentiels, il est plus facile d'avoir plusieurs propriétaires de produits.

  8. Avec plusieurs petits référentiels, il est plus facile d'avoir des normes de code simples qui sont pertinentes pour un référentiel complet et qui peuvent être vérifiées automatiquement.

Michael Le Barbier Grünewald
la source
1
Un élément clé d'une telle solution est un référentiel d'artefacts décent (par exemple artificiel), qui vous permet de découpler les composants dépendants du même référentiel. IOW au lieu de partager du code (un dépôt), publier et consommer des bibliothèques construites (artefacts). C'est aussi un bon endroit pour commencer un tel effort, car vous pouvez refactoriser / extraire vos modules un par un.
Assaf Lavie
C'est définitivement le cas. :)
Michael Le Barbier Grünewald
1
Nous examinons actuellement un problème très similaire au travail. L'approche que nous envisageons est d'avoir un référentiel maître sans code dédié et d'autres référentiels attachés en tant que sous-modules. Mais nous devons encore trouver le bon outillage et l'intégration du processus pour le faire. Je vais composer une réponse détaillée lorsque nous trouverons les détails.
Jiri Klouda
1
Les choses peuvent devenir un peu plus compliquées si les produits partagent du code (indépendant de la plateforme / du produit). Ou s'il existe un code commun par famille de produits. Ce n'est pas que le fractionnement ne serait pas une bonne idée, seule la gestion des pièces et la liste des avantages et des inconvénients seraient en quelque sorte différentes.
Dan Cornilescu
2
Je pense que votre 6ème puce avec git-bissect manque quelque chose. Je me demande si cela ne devrait pas être divisé en questions distinctes car il s'agit plus ou moins de demander un livre. Comme la définition d'un produit est très subjective (et peut varier), je pense que c'est en fait un peu trop élevé pour une question sur un site SE. Soit trop large, soit trop basé sur l'opinion.
Tensibai

Réponses:

9

C'est une question fascinante pour laquelle de vraies réponses peuvent ne pas exister réellement; J'apprécie que, bien que vous ayez essayé de contextualiser la question sur le VCS, elle s'est naturellement étendue à la conception de l'infrastructure et à la planification de la mise en œuvre.

Cependant, il semble que beaucoup d'entre nous travaillent sur ce type de transition, qui peut être excitant, mais en même temps si frustrant et douloureux; et je voudrais partager mes expériences et points de vue, en essayant de ne pas être pédant, et juste parce que je ne suis peut-être pas un si bon ingénieur, aussi de ne pas être ennuyeux.

Conception

L'infrastructure et l'architecture doivent aller de pair pour écrire un logiciel moderne. Étroitement couplé, si vous le souhaitez. Cela peut sembler étrange d'utiliser ces mots, mais nous ne parlons certainement pas du code lui-même ici: je veux dire qu'ils doivent faire partie du même plan. Quand les nuages ​​sont arrivés et que les gens ont commencé à écrire des logiciels pour eux, combien de personnes ont réalisé qu'en mettant les boules de boue là, ce seraient juste les mêmes boules de boue dans un endroit différent (?) Peut-être que quelques personnes avant-gardistes pourraient prévoir cela, et ils travaillent probablement en devops aujourd'hui. Comme devops n'est qu'un mot à la mode avec tant de significations différentes pour différentes personnes, j'ai vu des endroits où l'équipe devops siégeait à chaque réunion d'architecture; d'autres endroits dans lesquels est l'automatisation uniquement. Pour réaliser ce type de transformation, nous devons nous battre pour nous asseoir là.

Confiance

La transition doit être maintenue isolée, en ce sens qu'il doit exister une coupe cohérente de l'histoire, qui assure la transition elle-même et elle-même uniquement, sans autre changement (après plusieurs mois de préparation). Avec quelle confiance on l'approuverait et pousserait le bouton rouge?

Je veux dire que la base de code doit changer pour s'adapter à la nouvelle structure VCS, et il sera très difficile de la maintenir fusionnée pendant le développement. (pour ce problème, il peut y avoir des stratégies de facilitation, j'en parlerai plus tard, qui peuvent aider à paralléliser un peu le développement).

Eh bien, je parie que le seul moyen est de tester le comportement, et la même suite de tests de comportement devrait être lancée pour vérifier l'ancien avec la nouvelle base de code. Nous ne vérifions pas que l'application se comporte comme prévu ici, mais que la transition ne modifie pas le comportement. Avoir échoué aux tests peut être une bonne chose! S'ils continuent d'échouer!

En fait, il est très rare que les boules de boue soient bien testées; généralement, le code est très étroitement couplé, et probablement, pour la plupart des anciens codes, il n'a pas été développé avec une approche pilotée par les tests, pas même les tests unitaires.

Si un tel code de test manque, il doit être écrit en premier.

Stratégie

Oui, la transition doit être isolée; mais en même temps intégré. Je sais que je peux sembler fou ici, mais je ne trouverais pas d'autres mots pour décrire comment la confiance peut tenir la route. Très peu, voire pas du tout, d'entreprises voudraient arrêter le développement d'une grande base de code monolithique, pour faire de la place à cette transition, et nous ne faisons pas en sorte que cela se produise simplement en un rien de temps. Peut-être que des centaines de développeurs pourraient contribuer en permanence à la base de code (j'utiliserais le mot de falsification ici, de notre POV). Alors que notre travail doit porter sur un instantané spécifique pour assurer la confiance, nous devons nous garder rebasés (pas dans un sens génial ici), pour éviter de prendre du retard pour toujours.

La stratégie de mise en œuvre ici peut donner différentes expériences. Une ligne de développement commune consiste à encapsuler / adapter (exposer les points de terminaison avec des schémas éventuellement réarrangés) les nouvelles branches d'implémentation (enfin, vivant dans d'autres référentiels dans ce cas), lorsqu'elles doivent interagir avec le noyau. La transition avec une stratégie comme celle-ci, avec le refactoring, peut en même temps offrir un scénario POC pour la transition VCS, et plus tard une approche étape par étape. Voyez-le comme sculpter la boule de boue. Ouais, la vie offre tellement de choses plus drôles.

Dette technique

Les sphères de gestion d'entreprise ont commencé à comprendre la dette technique et à la tenir en considération. Non, grattez ça, pas vrai. S'il est de plus en plus courant de collecter des mesures et des données de qualité, en termes d'analyse de code statique, de révision de code, de résultats de tests comportementaux et de performances, et de générer de bons rapports et tout ... il reste incroyablement difficile de faire accepter par l'entreprise une approche continue approche de refactoring. La valeur commerciale de celui-ci. "Nous suivons un processus agile, et cela n'apportera aucune amélioration aux fonctionnalités, n'est-ce pas?" . Fondamentalement, ce faisant, ils nient l'existence d'une dette technique. Je vois cela comme l'étape nécessaire manquante commune pour pouvoir commencer toute transition des architectures monolithiques aux microservices.

Réagrégation

Après tout cela, vous souhaiterez peut-être toujours fournir une seule vue de type référentiel dans laquelle vous pouvez créer plusieurs produits. Pour toute raison, c.-à-d. Curr / prochaine version, multimarques, builds client Des outils comme Google Repo peuvent aider dans ce cas. Je n'en ai jamais utilisé moi-même, mais je sais que j'en aurai besoin un jour.

Test d'intégration

Avec les microservices, les tests d'intégration supposent un contexte différent, celui de "tester sa propre API". Des couches supérieures de tests, fonctionnels ou de performance, peuvent exister et existeront, mais signifient-elles beaucoup sans tests d'intégration appropriés? Ce serait comme avoir des tests d'intégration sans tests unitaires. Bien sûr que non. C'est pourquoi, si vous avez besoin de git bissect, vous l'exécuterez dans une branche de référentiel de microservices, oubliez de l'exécuter dans le référentiel mudball.

PS. c'est un brouillon, mon anglais est mauvais et je vais le réparer un jour

ᴳᵁᴵᴰᴼ
la source