web-dev-qa-db-fra.com

Monorepo vs multi-repo pour un grand projet avec plusieurs livraisons partielles

Je cherche des options pour lisser notre pipeline de livraison et de sortie, et j'apprécierais des conseils sur le meilleur moyen de structurer le code source.

C'est un projet assez important, qui consiste en environ 30 microservices. Les microservices ici sont un terme très lâche, mais pour la question de la question est suffisamment proche. Actuellement, tout cela est stocké dans un seul repo.

Le flux de travail interne est structuré comme suit:

1 mois de sprints où tout le code est engagé dans une branche de développement. À la fin du mois, toutes les tâches qui devraient être déplacées dans des tests sont fusionnées dans la branche "Prochaine principale publication" et toutes les tâches critiques/bogues sont fusionnées dans la branche "Livraison active" et testées avant d'être choisi sélectivement sur les clients. .

Tous les clients ne veulent pas le dernier et le plus grand, car ils souhaitent que peu de modifications que possible pour atténuer les risques liés au changement.

Donc, à la fin du mois, nous avons ce qui suit:
[.____] 1 DIRECTION DE DEV DE DATE DATE
[.____] 1 Test en partie à jour/Direction de la livraison suivante
[.____] 1 Direction de la production

et ceci est ensuite déployé sur des clients comme celui-ci:
Client a
- Production installée version 11
[.____] * Microservice suréviché 3 de la branche de production 11.4
[.____] * Microservice suréviché 5 de la branche de production 11.1
[.____] * ...

Client b
[.____] - Production installée version 11.6
[.____] * Microservice suréviché 7 de la branche de production 11.14
[.____] * Microservice suréviaire 15 de la branche de production 11.7

Client c
[.____] - Production installée version 11.3

Changerait-il à une configuration multiples pour mieux répondre à notre pipeline de livraison clairement insensée? Je considère un représentant pour chaque service, puis un repo pour chaque client.

Code Repo:
[.____] - Microservice 1
[.____] - Microservice 2
[.____] - Microservice 3

Repos de clients:
[.____] - Lien vers Microservice 1 - Version 1.5
- Lien vers Microservice 2 - Version 2.5
[.____] - Lien vers Microservice 3 - Version 1.7
- Les fichiers de données spécifiques au client (ils ne sont pas sous la version de version de la version maintenant ...)

Je pense que cela améliorerait grandement notre flux de travail et nous ramènerait à la piqûre de la peine d'avoir une branche. Il devrait nous donner un meilleur contrôle de ce qui est réellement libéré à un client, nous donne la capacité de reproduire en réalité leur environnement et, surtout, il devrait supprimer le besoin de fusionner une fois par mois.

Je apprendrais considérablement de faire des commentaires à ce sujet.

EDIT: L'API est assez stable entre les services, mais les libs partagés sont un peu un sac mélangé. Le produit a atteint environ 25 ans, de sorte que le noyau est stable, mais comme vous pouvez l'image à un grand besoin de nettoyer, car le département technique a progressé lentement.

J'ai essentiellement deux problèmes que j'essaye de résoudre/améliorer

  1. La journée de fusion est l'enfer, la succursale de production peut aller jusqu'à une année de plus que la succursale de Dev, avec seulement un sous-ensemble de ce qui est dans la fusion de Dev ramassée. Si une nouvelle fonctionnalité est ajoutée dans Dev, qui ne doit pas être dans la version actuelle, cela n'est pas déplacé vers la production. Tous les correctifs dans Dev qui utilise le code de ceci entraîneront des problèmes énormes si elles doivent être déplacées. Mon idée est que plusieurs répétitions plus petits rendront cela plus facile.

  2. Disons qu'il y a un bogue sur un serveur pour obtenir des données client. Le bogue est dans certaines libres partagée et je le répare, construisez le CustDataServer et tous les autres serveurs que je pense être influencés par cela, puis déployez alors sur le système client/clients. Cela signifie que la prochaine fois que quelqu'un effectue une correction de bogues, qui arrive à utiliser mon dernier correctif de bogue, puis ils ont essentiellement involontairement que dans la production sans signification. La plupart du temps c'est bien, mais je me sens comme si nous n'avons aucun contrôle sur ce qui est en train de fonctionner en production. Servera est construit avec SharedLiba et SharedLibB, tandis que Serverb est en construction avec les mêmes libs partagées, mais d'autres versions. J'ai l'impression qu'une approche multi-repo donnerait au moins plus de contrôle dans ce cas.

Je suis ouvert à toutes sortes d'idées sur la façon de nettoyer ce désordre.

EDIT : J'apprécie tout ce que les responsables sont jusqu'à présent. Je conviens que la sélection du style Repo n'est pas le problème ici.

Votre résumé est joli point de vue, appart depuis les repos de la mise en page. C'était quelque chose que j'avais envisagé d'introduire. Actuellement, les fichiers spesifiques clients (db et fichiers de configuration principalement) sont stockés sur le serveur client et ne sont sous aucune forme de contrôle de la source.

En ce qui concerne le cycle de publication, je suis d'accord avec vous que la libération de la libération est la meilleure idée. En outre, ne faites pas de rejets partiels. Tout ou rien. Le problème est que le cycle de libération est en dehors de mon contrôle. Je peux influencer beaucoup de choses, mais seulement des choses qui se trouvent au sein de l'entreprise. Extérieure, il est difficile de modifier. La raison des versions partielles et infrarquées est d'atténuer le risque de clients. L'idée est que moins cela change, plus il y a la chance de nouveaux bugs. Le logiciel est très critique et les bogues pourraient coûter des millions de dollars par jour en dommages-intérêts.

Et si nous essayions de faire cela l'autre moyen, je décris le système comme quelque chose à créer avec les contraintes qui existent, quel serait le moyen idéal de le structurer?

  • Grande base de code qui est logiquement divisé en plusieurs unités, mais sont (étroitement) couplées
  • Version annuelle de nouvelles fonctionnalités.
  • Les fonctionnalités sont un mélange entre les changements locaux et les nouvelles fonctionnalités du système.
  • Les bugs doivent être corrigés dès que possible, si critique en quelques heures.
  • Les clients ne veulent pas vouloir des versions complètes, ils veulent aussi peu de changement que possible. En fait, ils ne veulent souvent pas de la libération annuelle et de la traîner autant que possible
  • Logiciel critique, bug coûte cher

Quelle serait la meilleure façon de structurer le flux de travail interne pour limiter le nombre de points de douleur?

6
user1038502

Il me semble que l'un vs de nombreux repos n'est pas la racine de votre problème.

C'est votre stratégie de ramification.

  • Si vous le pouvez, passez à une stratégie de ramification reconnue telle que Gitflow.

  • Si vous écrivez une solution de bogue pour un problème de production. Faire une branche (hotfix) de la production. Pas votre branche de développement ou de prochaine version.

  • Si votre branche de "prochaine version" n'a pas été fusionnée depuis un an. N'essayez même pas de la fusionner. Laissez simplement le devenir la nouvelle branche de "production".

  • Arrêtez la fusion de la cueillette des cerises. Fusionner une branche entière ou pas du tout. Si vos différentes branches ont divergé autant que vous impliquez, vous devez probablement écrire cette solution de bogue séparément pour chaque branche.

En ce qui concerne les clients déployant différentes versions des micro-services. Cela ne devrait pas être un problème et cela ne devrait certainement pas être lié à votre contrôle source.

Enregistrez vos déploiements en version séparément à partir de votre commande source. Même si vous ne compilez pas de binaires, vous devez distinguer le code source et le produit.

Ne vous déployez pas en vérifiant le code du contrôle de la source. Faites un fichier ZIP avec le logiciel + CONFIG et un script de déploiement d'une sorte. Imaginez que vous devez le poster sur un CD.

Je m'attendrais à ce que les environnements vivants puissent avoir plusieurs versions déployées pour activer les déploiements de temps d'arrêt de zéro etc.

Tant que chaque version est testée et que vous indiquez quelles autres versions qu'il est compatible avec cela ne devrait pas être un problème.

3
Ewan

Comme @DocBrown a souligné dans les commentaires:

La question initiale

Monorepo vs multi-repo pour un grand projet avec plusieurs livraisons partielles

peut-être pas la vraie question ici.

Plus au milieu, vous écrivez

Changerait-il à une configuration multiples pour mieux répondre à notre pipeline de livraison clairement insensée?

qui conduit à la question:

Comment gérer notre pipeline de livraison insensé.

Premièrement, j'essaie de rassembler des faits pour mieux comprendre votre situation actuelle:

  • Vous avez un référentiel source qui représente en quelque sorte l'état actuel de votre produit

  • Votre code est logiquement divisé en plusieurs unités, qui sont (étroitement) couplés

  • Vous avez différentes branches

    • faire devenir
    • suivant
    • production
  • Plusieurs "mises en page" (repos) pour différents clients
  • Sprint de 1 mois de longueur

Vous avez deux points de douleur majeurs:

1) Fusionner la journée

2) plus de contrôle sur ce qui va dans la production


Bien sûr, il est difficile de donner ici une solution unique et une solution de boule en verre, car même si vous donnez une description relativement bonne de votre statu quo, il est peut-être plus compliqué que la vue 30000ft, vous avez donné ici.

Ce que je pourrais offrir ici, ce sont des pensées/idées:

Objectif global: avoir une base de code actuelle pour tous les clients

i) Travailler sur le cycle de sortie

Je ne sais pas pour quelles raisons il y a une telle grande dérive entre la version de production et la version de développement.

Y a-t-il une chance de libérer votre produit plus souvent. Plus vous libérez souvent, plus la dérive est petite, plus la fusion devrait être plus facile.

ii) Travailler sur la configuration de votre application

D'après ce que vous écrivez, il n'est pas évident quelles sont les différences entre les versions. Est-ce en quelque sorte possible de rendre l'application plus configurable? Pour que le client obtiendrait toujours la version actuelle du produit - mais peut-être une fonctionnalité rétrogradée pour ses besoins.

Bien sûr, je comprends que, plus les options de configuration vous avez plus complexes que vous devez gérer. Cela ne nécessite pas que votre vie facilite votre vie - mais je vois l'avantage d'avoir une cohérence et plus faciles à gérer/unified CodeBase en tant que victoire dans votre situation.

iii) Lorsque vous avez une base de code, qui fonctionne sur tous nos serveurs de nos clients, vous savez ce qui est en production et ce qui n'est pas; Donc, le deuxième point de douleur devrait disparaître.

Mais:

Honnêtement, je ne sais pas à quel point ces idées sont réalisables et combien d'efforts vous devez mettre en place ou si l'ensemble vaut l'effort.

Puisque vous avez de bons clients payants et que votre produit est en cours d'exécution (fondamentalement) pendant 25 ans - et peut-être peut-être pour une autre bande d'années - vous devriez prendre de petites étapes pour gagner la course dans le long terme.

En tant que point de départ, vous pouvez tester, combien d'efforts il s'agit d'utiliser chaque client d'exécuter une version d'un service actuel avec des options configurables. Et combien le coût de la complexité de la configuration est.


En ce qui concerne votre question initiale:

Rester avec un monorepo. Si les choses sont aussi étroitement couplées car elles semblent être, ce sera mieux.


Éditer:

Peut-être devez-vous interpréter le mot "libération" un peu plus créatif. Release est un point fixe de votre représentant où sur la branche de déverrouillage est un ensemble de travail de chaque composant dans autant de configurations que vous avez.

Cela signifie que certains clients reçoivent une libération (BI) d'autres d'autres personnes plus fréquentes, mais les clients d'une fenêtre de libération obtiennent le même code d'exécution. Votre objectif est alors: avoir à chaque fois une version actuelle prête à l'attente de déployer.

Je comprends que les clients sont intéressés par la stabilité et favorisent de petits changements, car ils supposent que le nombre de défauts introduits est également petit.

Mais d'autre part: le client attend un produit de travail et aussi longtemps que vous pouvez garantir cela - par exemple. Avec une suite de test serrée - je ne vois aucun problème à faire de grandes mises à jour. n ° 1 La préoccupation est d'avoir aussi peu de défauts que possible et de fixer tout (jusqu'au point de la libération).

Misté : J'ai travaillé pour les 2,5 dernières années dans des conditions qui n'étaient pas aussi difficiles que les vôtres, mais similaires. 6 clients, 6 saveurs différentes de l'application sous-jacente. L'application sous-jacente elle-même était composée de plus de 7 applications séparées qui étaient dans leur propre repo - mais dans le recul et si j'avais été dans le projet depuis le début, je voterais pour un monorepo pour tout cela, en raison de l'accouplement serré. Nous avons eu au moins des versions mensuelles. Mais les choses empilées et des versions pour tout était trop difficile. J'ai suggéré la stratégie d'avoir des "libérations" indépendantes de les avoir déployés ou activés, de sorte que tous les projets soient toujours exécutés de "courant".

J'ai constaté que cette stratégie a apporté un peu de soulagement aux développeurs.

1
Thomas Junk