Monorepository's: alsjeblieft, moet

Monorepository's: alsjeblieft, moet

Vertaling van het artikel voorbereid voor cursisten "DevOps-praktijken en tools" in het OTUS-onderwijsproject.

U moet een monorepository kiezen, omdat het gedrag dat het in uw teams bevordert transparantie en gedeelde verantwoordelijkheid is, vooral naarmate teams groeien. Hoe dan ook, je zult in tooling moeten investeren, maar het is altijd beter als het standaardgedrag het gedrag is dat je in je opdrachten wilt.

Waarom hebben we het hierover?

Matt Klein schreef het artikel "Monorepos: Alsjeblieft niet!"  (noot van de vertaler: vertaling op Habré “Monorepositories: alsjeblieft niet”). Ik vind Matt leuk, ik denk dat hij erg slim is en je zou zijn standpunt moeten lezen. Hij plaatste de enquête oorspronkelijk op Twitter:

Monorepository's: alsjeblieft, moet

Vertaling:
Deze nieuwjaarsdag ga ik discussiëren over hoe belachelijk monorepository's zijn. 2019 begon rustig. In het kader hiervan bied ik u een enquête aan. Wie zijn de grote fanatici? Supporters:
- Monorepo
- Roest
- Onjuiste enquête / beide

Mijn antwoord was: "Ik ben letterlijk beide mensen." Laten we, in plaats van te praten over hoe Rust een medicijn is, eens kijken waarom ik denk dat hij ongelijk heeft wat betreft monorepositories. Een klein stukje over jezelf. Ik ben de CTO van Chef Software. We hebben ongeveer 100 ingenieurs, een codebasis die ongeveer 11-12 jaar teruggaat, en 4 hoofdproducten. Een deel van deze code bevindt zich in een polyrepository (mijn startpositie), een ander deel bevindt zich in een monorepository (mijn huidige positie).

Voordat ik begin: elk argument dat ik hier maak, is van toepassing op beide soorten repository's. Naar mijn mening is er geen technische reden waarom je het ene type repository boven het andere zou moeten kiezen. Je kunt elke aanpak laten werken. Ik praat er graag over, maar ik ben niet geïnteresseerd in kunstmatige technische redenen waarom de een superieur is aan de ander.

Ik ben het eens met het eerste deel van Matt's punt:

Omdat op grote schaal een monorepository dezelfde problemen oplost als een polyrepository, maar u tegelijkertijd dwingt uw code nauw aan elkaar te koppelen en ongelooflijke inspanningen vergt om de schaalbaarheid van uw versiebeheersysteem te vergroten.

U zult dezelfde problemen moeten oplossen, ongeacht of u voor een monorepository of een polyrepository kiest. Hoe breng je releases uit? Wat is uw benadering van updates? Achterwaartse compatibiliteit? Afhankelijkheden tussen projecten? Welke bouwstijlen zijn acceptabel? Hoe beheert u uw bouw- en testinfrastructuur? De lijst is eindeloos. En je zult ze allemaal oplossen naarmate je groeit. Er bestaat geen gratis kaas.

Ik denk dat het argument van Matt vergelijkbaar is met de opvattingen die worden gedeeld door veel ingenieurs (en managers) die ik respecteer. Dit gebeurt vanuit het perspectief van de ingenieur die aan het onderdeel werkt of het team dat aan het onderdeel werkt. Je hoort dingen als:

  • De codebase is omvangrijk - ik heb al deze rommel niet nodig.
  • Het is moeilijker om te testen omdat ik al deze rommel moet testen die ik niet nodig heb.
  • Het is moeilijker om met externe afhankelijkheden te werken.
  • Ik heb mijn eigen virtuele versiebeheersystemen nodig.

Natuurlijk zijn al deze punten gerechtvaardigd. Dit gebeurt in beide gevallen - in de polyrepository heb ik mijn eigen rommel, naast degene die nodig is voor de build... Ik heb misschien ook andere rommel nodig. Dus ik maak ‘gewoon’ tools die het hele project controleren. Of ik maak een nep-monorepository met submodules. We zouden hier de hele dag rond kunnen lopen. Maar ik denk dat Matt's argument de belangrijkste reden mist, die ik behoorlijk zwaar heb verdraaid ten gunste van de monorepository:

Het lokt communicatie uit en laat problemen zien

Wanneer we opslagplaatsen scheiden, creëren we de facto een coördinatie- en transparantieprobleem. Dit komt overeen met de manier waarop wij over teams denken (vooral de manier waarop individuele leden over hen denken): wij zijn verantwoordelijk voor een bepaald onderdeel. Wij werken in relatieve isolatie. De grenzen liggen vast voor mijn team en de component(en) waaraan we werken.

Naarmate architectuur complexer wordt, kan één team het niet langer alleen beheren. Er zijn maar weinig ingenieurs die het hele systeem in hun hoofd hebben. Stel dat u een gedeeld onderdeel A beheert dat wordt gebruikt door Teams B, C en D. Team A is bezig met refactoring, het verbeteren van de API en het wijzigen van de interne implementatie. Als gevolg hiervan zijn de wijzigingen niet achterwaarts compatibel. Welk advies heb je?

  • Vind alle plaatsen waar de oude API wordt gebruikt.
  • Zijn er plekken waar de nieuwe API niet gebruikt kan worden?
  • Kun jij andere componenten repareren en testen om er zeker van te zijn dat ze niet kapot gaan?
  • Kunnen deze teams uw wijzigingen nu testen?

Houd er rekening mee dat deze vragen onafhankelijk zijn van het repositorytype. Je zult teams B, C en D moeten vinden. Je zult met ze moeten praten, de tijd moeten achterhalen en hun prioriteiten moeten begrijpen. Wij hopen dat in ieder geval.

Niemand wil dit echt doen. Dit is een stuk minder leuk dan alleen het repareren van die verdomde API. Het is allemaal menselijk en rommelig. In een polyrepository kun je eenvoudig wijzigingen aanbrengen, deze ter beoordeling aan de mensen die aan dat onderdeel werken (waarschijnlijk niet B, C of D) geven, en verder gaan. Teams B, C en D kunnen voorlopig gewoon bij hun huidige versie blijven. Ze worden vernieuwd als ze je genialiteit beseffen!

In een monorepository wordt de verantwoordelijkheid standaard verschoven. Team A verandert hun component en breekt, als ze niet oppassen, onmiddellijk B, C en D. Dit leidt ertoe dat B, C en D aan de deur van A verschijnen en zich afvragen waarom team A de montage heeft verbroken. Dit leert A dat ze mijn lijstje hierboven niet kunnen overslaan. Ze moeten praten over wat ze gaan doen. Kunnen B, C en D bewegen? Wat als B en C dat wel kunnen, maar D nauw verwant was aan een bijeffect van het gedrag van het oude algoritme?

Dan moeten we praten over hoe we uit deze situatie zullen komen:

  1. Ondersteuning voor meerdere interne API's en markeert het oude algoritme als verouderd totdat D het niet meer kan gebruiken.
  2. Ondersteuning voor meerdere releaseversies, één met de oude interface, één met de nieuwe.
  3. Stel de vrijgave van de wijzigingen van A uit totdat B, C en D deze tegelijkertijd kunnen accepteren.

Laten we zeggen dat we 1, meerdere API's hebben geselecteerd. In dit geval hebben we twee stukjes code. Oud en nieuw. In sommige situaties best handig. We controleren de oude code opnieuw, markeren deze als verouderd en komen een verwijderingsschema overeen met het team van D. In wezen identiek voor poly- en mono-repository's.

Om meerdere versies uit te brengen, hebben we een branch nodig. Nu hebben we twee componenten: A1 en A2. Teams B en C gebruiken A2 en D gebruikt A1. We hebben elk onderdeel nodig om klaar te zijn voor release, omdat beveiligingsupdates en andere bugfixes nodig kunnen zijn voordat D verder kan. In een polyrepository kunnen we dit verbergen in een tak met een lange levensduur die goed voelt. In een monorepository dwingen we af dat de code in een nieuwe module wordt aangemaakt. Team D zal nog wijzigingen moeten aanbrengen in het "oude" onderdeel. Iedereen kan de kosten zien die we hier betalen - we hebben nu twee keer zoveel code, en eventuele bugfixes die van toepassing zijn op A1 en A2 moeten op beide van toepassing zijn. Bij de vertakkingsaanpak in een polyrepository gaat dit schuil achter de ‘cherry-pick’. Wij achten de kosten lager omdat er geen sprake is van dubbel werk. Vanuit praktisch oogpunt zijn de kosten hetzelfde: je bouwt, geeft uit en onderhoudt twee grotendeels identieke codebases totdat je er één kunt verwijderen. Het verschil is dat bij een monorepository deze pijn direct en zichtbaar is. Dit is nog erger, en dat is goed.

Uiteindelijk kwamen we bij het derde punt. Vertraging vrijgave. Het is mogelijk dat veranderingen die door A worden aangebracht de levens van team A zullen verbeteren. Belangrijk, maar niet urgent. Kunnen we gewoon uitstellen? In een polyrepository pushen we dit om het artefact vast te zetten. Natuurlijk vertellen we dit aan Team D. Blijf gewoon bij de oude versie totdat je het inhaalt! Dit zorgt ervoor dat je de lafaard speelt. Team A blijft aan hun component werken en negeert het feit dat Team D een steeds verouderde versie gebruikt (dat is het probleem van Team D, ze zijn dom). Ondertussen praat Team D slecht over de onzorgvuldige houding van Team A ten aanzien van codestabiliteit, als ze er al over praten. Maanden gaan voorbij. Ten slotte besluit Team D om te kijken naar de mogelijkheid tot updaten, maar A heeft alleen maar meer wijzigingen. Team A herinnert zich nauwelijks wanneer of hoe ze D kapot hebben gemaakt. De upgrade is pijnlijker en zal langer duren. Wat het verder naar beneden stuurt op de prioriteitsstapel. Tot de dag dat we een beveiligingsprobleem hebben in A dat ons dwingt een filiaal te maken. Team A moet terug in de tijd gaan, een punt vinden waarop D stabiel was, het probleem daar oplossen en het klaar maken voor release. Dit is de feitelijke keuze die mensen maken, en het is veruit de slechtste. Het lijkt goed te zijn voor zowel team A als team D, zolang we elkaar maar kunnen negeren.

In een monorepository is de derde echt geen optie. Je wordt gedwongen om op twee manieren met de situatie om te gaan. Je moet de kosten zien van het hebben van twee release-takken. Leer uzelf te beschermen tegen updates die de achterwaartse compatibiliteit verbreken. Maar het belangrijkste: je kunt een moeilijk gesprek niet vermijden.

Mijn ervaring is dat wanneer teams groot worden, het niet langer mogelijk is om het hele systeem in gedachten te houden, en dat is het belangrijkste. U moet de zichtbaarheid van onenigheid in het systeem verbeteren. Je moet er actief aan werken om teams weg te laten kijken van hun componenten en naar het werk van andere teams en consumenten te kijken.

Ja, u kunt tools maken die het polyrepository-probleem proberen op te lossen. Maar mijn ervaring met het lesgeven in continue levering en automatisering in grote ondernemingen leert mij dit: het standaardgedrag zonder het gebruik van aanvullende tools is het gedrag dat u verwacht te zien. Het standaardgedrag van een polyrepository is isolatie, dat is het hele punt. Het standaardgedrag van een monorepository is gedeelde verantwoordelijkheid en transparantie, dat is het hele punt. In beide gevallen ga ik een hulpmiddel maken dat de ruwe randen gladstrijkt. Als leider zal ik elke keer een monorepository kiezen omdat de tools de cultuur moeten versterken die ik wil, en cultuur komt voort uit kleine beslissingen en het dagelijkse werk van het team.

Alleen geregistreerde gebruikers kunnen deelnemen aan het onderzoek. Inloggen, Alsjeblieft.

Wie zijn de grootste fanatici? Supporters:

  • Monorepo

  • Roest

  • Onjuiste enquête / beide

33 gebruikers hebben gestemd. 13 gebruikers onthielden zich van stemming.

Bron: www.habr.com

Voeg een reactie