
Eine Übersetzung des Artikels wurde für Studenten des DevOps Practices and Tools- Kurses im OTUS- Bildungsprojekt erstellt.
Sie sollten ein Mono-Repository auswählen, da das Verhalten, das es in Ihren Teams fördert, Transparenz und kollektive Verantwortung ist, insbesondere wenn Teams wachsen. In jedem Fall müssen Sie in Tools investieren, aber es ist immer besser, wenn das Standardverhalten das Verhalten ist, das Sie in Ihren Befehlen sehen möchten.
Warum reden wir darüber?
Matt Klein schrieb einen Artikel: "Monorepos: Bitte nicht!" (Kommentar des Übersetzers: Übersetzung auf einem Hub "Monorepositories: bitte nicht" ). Ich mag Matt, ich denke er ist sehr schlau und du solltest seinen Standpunkt lesen. Er hat ursprünglich die Umfrage getwittert:

Übersetzung:
An diesem Neujahrstag werde ich darüber streiten, wie lächerlich die Monorepositories sind. 2019 begann unbemerkt. In diesem Sinne biete ich Ihnen eine Umfrage an. Wer sind die großen Fanatiker? Unterstützer:
- Monorepository
- Rost
- Falsche Umfrage / sowohl diese als auch diese
Meine Antwort war: "Ich bin buchstäblich beide diese Leute." Anstatt darüber zu sprechen, welche Art von Rust-Droge wir haben, wollen wir herausfinden, warum er meiner Meinung nach in Bezug auf Mono-Repositories falsch liegt. Ein bisschen über dich. Ich bin der CTO von Chef Software. Wir haben ungefähr 100 Ingenieure, eine Codebasis von ungefähr 11-12 Jahren und 4 Hauptprodukte. Ein Teil dieses Codes befindet sich im Polyrepository (meine Startposition), ein Teil im Monorepository (meine aktuelle Position).
Bevor ich anfange: Jedes Argument, das ich hier zitiere, wird auf beide Arten von Repositorys angewendet. Meiner Meinung nach gibt es keine technischen Gründe, warum Sie den einen oder anderen Repository-Typ wählen sollten. Sie können jeden Ansatz zum Laufen bringen. Ich bin froh darüber zu sprechen, aber ich interessiere mich nicht für die künstlichen technischen Gründe, warum einer dem anderen überlegen ist.
Ich stimme dem ersten Teil von Matts Standpunkt zu:
Denn im großen Maßstab löst das Monorepository dieselben Probleme, die das Polyrepository löst, provoziert Sie jedoch gleichzeitig zu einer starken Kohärenz Ihres Codes und erfordert unglaubliche Anstrengungen, um die Skalierbarkeit Ihres Versionskontrollsystems zu verbessern.
Sie müssen dieselben Probleme lösen, unabhängig davon, ob Sie ein Monorepository oder ein Polyrepository auswählen. Wie veröffentlichen Sie Releases? Wie gehen Sie mit Updates um? Abwärtskompatibel? Projektübergreifende Abhängigkeiten? Welche Baustile sind akzeptabel? Wie verwalten Sie Ihre Build- und Testinfrastruktur? Die Liste ist endlos. Und Sie werden sie alle lösen, wenn Sie wachsen. Es gibt keinen freien Käse.
Ich denke, Matts Argument ähnelt den Ansichten vieler Ingenieure (und Manager), die ich respektiere. Dies geschieht aus Sicht des Ingenieurs, der an der Komponente arbeitet, oder des Teams, das an der Komponente arbeitet. Sie hören Dinge wie:
- Die Codebasis ist umständlich - ich brauche diesen ganzen Müll nicht.
- Dies ist schwieriger zu testen, da ich all diesen Müll überprüfen muss, den ich nicht brauche.
- Es ist schwieriger, mit externen Abhängigkeiten zu arbeiten.
- Ich benötige meine eigenen virtuellen Versionskontrollsysteme.
Natürlich sind alle diese Punkte vernünftig. Dies passiert in beiden Fällen - im Polyrepository habe ich meine eigenen Sachen, außer denen, die für die Montage benötigt werden ... Ich brauche möglicherweise auch andere Sachen. Daher erstelle ich "nur" Tools, die das gesamte Projekt auschecken. Oder erstelle ich ein gefälschtes Mono-Repository mit Submodulen? Wir könnten den ganzen Tag herumlaufen. Aber ich denke, Matts Argumentation verfehlt den Hauptgrund, den ich so ziemlich zugunsten des Monorepositorys umgedreht habe:
Es provoziert Kommunikation und zeigt Probleme.
Wenn wir Repositories gemeinsam nutzen, entsteht de facto ein Koordinierungs- und Transparenzproblem. Dies entspricht der Art und Weise, wie wir über Teams denken (insbesondere wie einzelne Teilnehmer über sie denken): Wir sind für eine bestimmte Komponente verantwortlich. Wir arbeiten relativ isoliert. Die Grenzen sind für mein Team und die Komponente (n) festgelegt, an denen wir arbeiten.
Aufgrund der Komplexität der Architektur kann ein Team sie nicht mehr alleine verwalten. Nur sehr wenige Ingenieure behalten das gesamte System im Kopf. Angenommen, Sie steuern eine gemeinsame Komponente A, die von den Befehlen B, C und D verwendet wird. Team A überarbeitet die API, verbessert die API und ändert auch die interne Implementierung. Änderungen sind daher abwärtskompatibel. Welchen Rat würden Sie geben?
- Finden Sie alle Stellen, an denen die alte API verwendet wird.
- Gibt es Orte, an denen die neue API nicht verwendet werden kann?
- Können Sie andere Komponenten reparieren und testen, um sicherzustellen, dass sie nicht kaputt gehen?
- Können diese Teams Ihre Änderungen jetzt überprüfen?
Bitte beachten Sie, dass diese Fragen unabhängig von der Art des Repositorys sind. Sie müssen die Teams B, C und D finden. Sie müssen mit ihnen sprechen, die Zeit herausfinden und ihre Prioritäten verstehen. Zumindest hoffen wir, dass Sie es tun.
Niemand will das wirklich tun. Das macht viel weniger Spaß als nur die verdammte API zu reparieren. Das alles ist menschlich und verwirrt. Im Repository können Sie einfach Änderungen vornehmen, denjenigen, die an dieser Komponente arbeiten (wahrscheinlich nicht B, C oder D), eine Überprüfung geben und fortfahren. Die Teams B, C und D können einfach auf ihrer aktuellen Version bleiben. Sie werden aktualisiert, wenn sie Ihr Genie erkennen!
In einem einzelnen Repository wird die Verantwortung standardmäßig verschoben. Team A ändert seine Komponente und bricht, wenn es nicht vorsichtig ist, sofort B, C und D. Dadurch erscheinen B, C und D an Tür A und fragen sich, warum Team A die Baugruppe gebrochen hat. Dies lehrt A, dass sie meine Liste oben nicht überspringen können. Sie sollten darüber sprechen, was sie tun werden. Können sich B, C und D bewegen? Was ist, wenn B und C können, aber D eng mit einem Nebeneffekt des alten Algorithmus verbunden war?
Dann müssen wir darüber sprechen, wie wir aus dieser Situation herauskommen:
- Unterstützung für mehrere interne APIs, während der alte Algorithmus als veraltet markiert wird, bis D ihn nicht mehr verwenden kann.
- Unterstützung für mehrere Versionen von Releases, eine mit der alten Schnittstelle, eine mit der neuen.
- Verzögerte Freigabe von Änderungen an A, bis sowohl B, C als auch D dies akzeptieren können.
Angenommen, wir wählen 1, mehrere APIs aus. In diesem Fall haben wir zwei Codeteile. Alt und neu. In manchen Situationen ziemlich praktisch. Wir geben den alten Code zurück, markieren ihn als veraltet und vereinbaren mit dem Befehl D einen Zeitplan für das Entfernen. Er ist im Wesentlichen für Poly und für das Mono-Repository identisch.
Um mehrere Versionen freizugeben, benötigen wir einen Zweig. Jetzt haben wir zwei Komponenten - A1 und A2. Die Teams B und C verwenden A2 und D A1. Wir benötigen jede Komponente, um zur Veröffentlichung bereit zu sein, da möglicherweise Sicherheitsupdates und andere Fehlerkorrekturen erforderlich sind, bevor D fortfahren kann. Im Repository können wir es in einem langlebigen Zweig verstecken, der sich gut anfühlt. Im Mono-Repository erzwingen wir den Code im neuen Modul. Team D muss noch Änderungen an der "alten" Komponente vornehmen. Jeder kann die Kosten sehen, die wir hier bezahlen - wir haben jetzt doppelt so viel Code, und alle Fehlerbehebungen, die für A1 und A2 gelten, sollten auf beide angewendet werden. Mit dem Ansatz, Zweige in einem Repository zu verwenden, ist dies hinter Cherry-Pick verborgen. Wir betrachten die Kosten als geringer, da es keine Doppelarbeit gibt. Aus praktischer Sicht sind die Kosten gleich: Sie erstellen, veröffentlichen und verwalten zwei im Grunde identische Codebasen, bis Sie eine davon löschen können. Der Unterschied besteht darin, dass dieser Schmerz im Monorepository direkt und sichtbar ist. Das ist noch schlimmer und gut.
Schließlich kamen wir zum dritten Punkt. Verzögerung freigeben. Es ist möglich, dass die von A vorgenommenen Änderungen das Leben von Team A verbessern. Es ist wichtig, aber nicht dringend. Können wir einfach durchhalten? Im Repository drängen wir darauf, um das Artefakt zu konsolidieren. Natürlich sprechen wir über dieses Team D. Bleiben Sie einfach bei der alten Version, bis Sie aufholen! Dies schafft ein Feiglingsspiel. Team A arbeitet weiter an seiner Komponente und ignoriert die Tatsache, dass Team D eine zunehmend veraltete Version verwendet (dies ist ein Problem für Team D, sie sind dumm). In der Zwischenzeit spricht Team D schlecht über die nachlässige Haltung von Team A gegenüber der Codestabilität, wenn überhaupt. Monate vergehen. Schließlich beschließt das D-Team, sich die Upgrade-Option anzusehen, aber es gibt nur weitere Änderungen an A. Team A erinnert sich kaum daran, wann und wie sie D gebrochen haben. Die Aktualisierung ist schmerzhafter und dauert länger. Was es weiter unten im Prioritätsstapel sendet. Bis zu diesem Tag, bis wir ein Sicherheitsproblem in A haben, das uns zwingt, eine Niederlassung zu gründen. Team A muss in der Zeit zurückgehen, den Moment finden, in dem D stabil war, das Problem dort beheben und es für die Veröffentlichung vorbereiten. Dies ist de facto die Wahl, die die Menschen treffen, und es ist bei weitem die schlimmste. Dies scheint sowohl für Team A als auch für Team D gut zu sein, solange wir uns gegenseitig ignorieren können.
Im Monorepository ist das dritte wirklich keine Option. Sie sind gezwungen, auf zwei Arten mit der Situation umzugehen. Sie müssen die Kosten für zwei Release-Zweige sehen. Erfahren Sie, wie Sie sich vor Updates schützen, die die Abwärtskompatibilität beeinträchtigen. Aber Hauptsache: Sie können ein schwieriges Gespräch nicht vermeiden.
Nach meiner Erfahrung ist es nicht mehr möglich, das gesamte System im Auge zu behalten, wenn Teams groß werden, und dies ist der wichtigste Teil. Sie müssen die Sichtbarkeit von Meinungsverschiedenheiten im System verbessern. Sie müssen aktiv daran arbeiten, dass Teams ihre Augen von ihren Komponenten abwenden und die Arbeit anderer Teams und Verbraucher betrachten.
Ja, Sie können Tools erstellen, mit denen versucht wird, das Problem der Polyrepositorys zu lösen. Meine Erfahrung im Unterrichten von kontinuierlicher Bereitstellung und Automatisierung in großen Unternehmen zeigt mir jedoch Folgendes: Das Standardverhalten ohne Verwendung zusätzlicher Tools ist das Verhalten, das Sie erwarten. Das Standardverhalten des Repositorys ist Isolation, das ist der springende Punkt. Das Standardverhalten eines Mono-Repositorys ist gemeinsame Verantwortung und Transparenz. Das ist der springende Punkt. In beiden Fällen werde ich ein Werkzeug erstellen, das scharfe Ecken glättet. Als Führungskraft werde ich jedes Mal ein Mono-Repository auswählen, da die Instrumente die von mir gewünschte Kultur stärken müssen und die Kultur aus winzigen Entscheidungen und der täglichen Arbeit des Teams resultiert.