Oversættelsen af artiklen er forberedt til studerende på kurset i uddannelsesprojektet OTUS.
Du skal vælge et monorepo, fordi den adfærd, det fremmer i dine teams, er gennemsigtighed og kollektivt ansvar, især når teams vokser. Uanset hvad, vil du være nødt til at investere i værktøjer, men det er altid bedre, når standardadfærden er den adfærd, du ønsker at se i dine teams.
Hvorfor taler vi om dette?
Matt Klein har skrevet en artikel (note fra oversætteren: oversættelse på Habré ). Jeg kan godt lide Matt, jeg synes, han er meget intelligent, og du bør læse hans synspunkt. Han offentliggjorde oprindeligt en afstemning på Twitter:
Oversættelse:
På denne nytårsdag vil jeg argumentere for, hvor absurde monorepos er. 2019 startede stille. I denne ånd vil jeg foreslå dig en afstemning. Hvem er de store fanatikere? Tilhængere:
— Monorepo
— Rust
— Forkert afstemning / begge dele
Mit svar var: «Jeg er bogstaveligt talt begge de mennesker». I stedet for at tale om, hvorvidt Rust er en afhængighed, lad os undersøge, hvorfor jeg tror, at han tager fejl med hensyn til monorepos. Lidt om mig selv. Jeg er teknisk direktør for Chef Software. Vi har omkring 100 ingeniører, en kodebase, der strækker sig over omkring 11–12 år, og 4 primære produkter. En del af denne kode findes i et polyrepo (min startposition), og en del i et monorepo (min nuværende position).
Før jeg starter: hvert argument, jeg fremfører her, vil gælde for begge typer af repositories. Efter min mening er der ingen tekniske grunde til, at du skal vælge den ene eller den anden type repository. Du kan få enhver tilgang til at fungere. Jeg er glad for at tale om dette, men jeg er ikke interesseret i kunstige tekniske grunde til, at den ene overgår den anden.
Jeg er enig i den første del af Matts synspunkt:
Fordi et monorepo i stor skala vil løse alle de samme problemer, som et polyrepo gør, men samtidig provokerer dig til at have en stærk sammenhæng i din kode og kræver utrolig indsats for at øge skalerbarheden af dit versionskontrolsystem.
Du står over for de samme problemer, uanset om du vælger et monorepo eller et polyrepo. Hvordan frigiver du versioner? Hvad er din tilgang til opdateringer? Bagudkompatibilitet? Krydsafhængigheder mellem projekterne? Hvilke arkitekturstile er acceptable? Hvordan håndterer du din bygg- og testinfrastruktur? Listen er uendelig. Og du vil tackle dem alle, efterhånden som du vokser. Der findes ikke gratis ost.
Jeg tror, at Matts argument minder om de synspunkter, mange ingeniører (og ledere) jeg respekterer, deler. Det kommer fra en ingeniørs perspektiv, der arbejder på en komponent, eller et team, der arbejder på en komponent. Du hører ofte ting som:
- Kodebasen er klodset - jeg har ikke brug for alt det skrammel.
- Det er sværere at teste, fordi jeg skal tjekke alt det skrammel, jeg ikke har brug for.
- Det er sværere at arbejde med eksterne afhængigheder.
- Jeg har brug for mine egne versionsstyringssystemer.
Bestemt er alle disse punkter rimelige. Det sker i begge tilfælde - i polyrepoet har jeg mit skrammel, ud over det der er nødvendigt for bygningen... Jeg kan også få brug for noget andet skrammel. Derfor skaber jeg "bare" værktøjer, der checkout'er hele projektet. Eller jeg opretter et falsk monorepo med submoduler. Vi kunne bruge hele dagen på det. Men jeg tror, at Matts argument overser den grundlæggende årsag, som jeg har vendt kraftigt til fordel for monorepoet:
Det fremmer kommunikation og afslører problemer.
Når vi deler repositoryer, skaber vi de facto et koordinerings- og gennemsigtighedsproblem. Det svarer til, hvordan vi tænker på teams (især hvordan de enkelte medlemmer tænker om dem): vi har ansvaret for en bestemt komponent. Vi arbejder i relativ isolation. Grænserne er fastlagt omkring mit team og den(r) komponent(er), vi arbejder på.
Når arkitekturen bliver mere kompleks, kan ét team ikke længere håndtere det alene. Meget få ingeniører har hele systemet i tankerne. Antag, at du administrerer en fælles komponent A, der bruges af teamene B, C og D. Team A refaktorerer, forbedrer API'et og ændrer også den interne implementering. Som et resultat er ændringerne bagudkompatible. Hvilket råd vil du give?
- Find alle steder, hvor det gamle API bruges.
- Er der steder, hvor det nye API ikke kan bruges?
- Kan du rette og teste de andre komponenter for at sikre, at de ikke går i stykker?
- Kan disse teams teste dine ændringer lige nu?
Bemærk, at disse spørgsmål ikke afhænger af typen af repository. Du bliver nødt til at finde teamene B, C og D. Du skal tale med dem, finde ud af tidsrammen, forstå deres prioriteter. I det mindste håber vi, at du gør det.
I virkeligheden ønsker ingen at håndtere dette. Det er langt mindre spændende end simpelthen at rette det forbandede API. Alt dette er menneskeligt og indviklet. I et polyrrepository kan du bare lave ændringer, få dem til gennemgang af dem, der arbejder på denne komponent (sandsynligvis ikke B, C eller D), og komme videre. Teams B, C og D kan bare blive på deres nuværende version. De opdaterer, når de indser din genialitet!
I et monorepository skifter ansvaret som standard. Team A ændrer sin komponent og, hvis de ikke er forsigtige, bryder de straks B, C og D. Det fører til, at B, C og D står ved døren til A og undrer sig over, hvorfor team A brød bygningen. Det lærer A, at de ikke kan springe min liste over. De skal tale om, hvad de planlægger at gøre. Kan B, C og D bevæge sig? Hvad hvis B og C kan, men D var tæt knyttet til de uønskede effekter af den gamle algoritmes adfærd?
Så skal vi tale om, hvordan vi kommer ud af denne situation:
- Understøttelse af flere interne API'er, mens den gamle algoritme mærkes som forældet, indtil D ikke længere kan bruge den.
- Understøttelse af flere versionsudgivelser, én med det gamle interface, én med det nye.
- Forsinkelse af A's ændringsudgivelse, indtil B, C og D samtidigt kan acceptere det.
Lad os sige, vi har valgt 1, flere API'er. I så fald har vi to stykker kode. Den gamle og den nye. Det er ret praktisk i nogle situationer. Vi returnerer den gamle kode tilbage, markerer den som forældet (deprecated), og koordinerer en tidsplan for dens fjernelse med team D. I det væsentlige er det identisk for poly og mono-repositoriet.
For at udgive flere versioner har vi brug for en gren. Nu har vi to komponenter — A1 og A2. Teams B og C bruger A2, mens D bruger A1. Vi har brug for, at hver komponent er klar til udgivelse, fordi før D kan komme videre, kan der være behov for sikkerhedsopdateringer og rettelser af andre fejl. I poly-repositoriet kan vi skjule dette i en langlivet gren, der fungerer godt. I mono-repositoriet skaber vi tvangsmæssigt koden i et nyt modul. Team D skal stadig foretage ændringer i den „gamle“ komponent. Alle kan se prisen, vi betaler her — vi har nu dobbelt så meget kode, og enhver fejlrettelse, der anvendes på A1 og A2, skal anvendes på begge. Med tilgangen til at bruge grene i poly-repositoriet er dette skjult bag cherry-pick. Vi betragter omkostningen som mindre, fordi der ikke er nogen duplikering. Rent praktisk set er omkostningen den samme: I vil oprette, udgive og vedligeholde to stort set identiske kodebaser, indtil I kan fjerne en af dem. Forskellen er, at smerten i mono-repositoriet er direkte og synlig. Det er endnu værre, og det er godt.
Endelig er vi nået til det tredje punkt. Udgivelsesforsinkelse. Det er muligt, at de ændringer, som team A har foretaget, vil forbedre situationen for team A. Vigtigt, men ikke presserende. Kan vi bare udsætte det? I monorepoet skubber vi dette hen imod en fastlæggelse af artefakten. Selvfølgelig taler vi om dette med team D. Bare hold jer til den gamle version, indtil I indhenter! Dette skaber en situation, hvor vi spiller sikkert. Team A fortsætter med at arbejde på deres komponent og ignorerer, at team D bruger en stadigt mere forældet version (det er team Ds problem, de er dumme). Imens taler team D dårligt om det uansvarlige forhold, som team A har til stabiliteten af koden, hvis de overhovedet taler om det. Måneder går. Endelig beslutter team D at se på at opdatere, men der er kun kommet flere ændringer i A. Team A kan næppe huske, hvornår og hvordan de ødelagde D. Opdateringen bliver mere smertefuld og vil tage længere tid. Hvilket sender det længere ned ad prioriteringslisten. Indtil den dag, vi får et sikkerhedsproblem i A, der tvinger os til at lave en gren. Team A skal tilbage i tiden, finde det øjeblik, hvor D var stabilt, rette problemet der og gøre det klar til udgivelse. Dette er de facto et valg, som folk træffer, og det er bestemt det værste. Det ser ud til at være godt for både team A og team D, så længe vi kan ignorere hinanden.
I et monorepo er det tredje reelt ikke en mulighed. Du er nødt til at håndtere situationen på en af to måder. Du skal forstå omkostningerne ved at have to udgivelsesgrene. Lære at beskytte dig mod opdateringer, der bryder bagudkompatibiliteten. Men vigtigst af alt: du kan ikke undgå en svær samtale.
Efter min erfaring, når teams vokser, bliver det umuligt at holde hele systemet i hovedet, og det er den vigtigste del. Du skal forbedre synligheden af uoverensstemmelserne i systemet. Du skal aktivt arbejde på at få teams til at tage blikket væk fra deres komponenter og se på arbejdet fra andre teams og forbrugere.
Ja, du kan oprette værktøjer, der forsøger at løse problemet med polirepositorier. Men min erfaring med kontinuerlig levering og automatisering i store virksomheder fortæller mig følgende: Standardadfærden uden brug af ekstra værktøjer er den adfærd, du forventer at se. Standardadfærden for et polirepositorium er isolation, det er hele pointen. Standardadfærden for et monorepositorium er fælles ansvar og gennemsigtighed, det er hele pointen. I begge tilfælde vil jeg skabe et værktøj, der kan glatte de skarpe kanter. Som leder vil jeg vælge et monorepositorium hver gang, fordi værktøjer skal styrke den kultur, jeg ønsker, og kulturen kommer fra de små beslutninger og det daglige arbejde i teamet.
Kun registrerede brugere kan deltage i undersøgelsen. , please.
Hvem er de større fanatikere? Tilhængere:
Monorepo
Rust
Forkert afstemning / begge dele
33 brugere stemte. 13 brugere afholdt sig.
Kilde: habr.com
