Jan
12

Git Repositories: Monolithic / Single vs. Multiple

Vergleich für Kundenprojekte aus Sicht einer PHP - Webagentur

Jan
12

Git Repositories: Monolithic / Single vs. Multiple

Vergleich für Kundenprojekte aus Sicht einer PHP - Webagentur

Bei Neukunden-Projekten oder wenn Web-Agenturen ihre bestehenden Projekte zu Git migrieren kommt häufig die Frage auf, wie das Projekt Repository / die Repositories aufgebaut und strukturiert werden sollen. 

Soll nur ein einzelnes für das Gesamte Projekt verwendet werden oder sollte man für jedes Modul, Theme, Erweiterung etc ein eigenes Repository anlegen? Wie sollte die Verzeichnissstruktur innerhalb ausschauen?

Git Repositores sind im Vergleich zu beispielsweise SVN sehr schnell und machen branching kinderleicht (zumindest wesentlich leichter und vor allem weniger angsteinflößend als bei SVN) allerdings liest man oft (berechtigt) das Git Repositories klein gehalten und man für jedes (Teil-)Projekt ein einzelnes Repository anlegen sollte.

Während das für Open Soruce Projekte durchaus zutrifft, sieht es bei Kunden- / Agenturprojekten durchaus anders aus. Wir schauen uns die Vorteile und Nachteile von single monolith Repositories im Vergleich zum Multiple Repository Ansatz an.

Die meisten unserer Web- und e-commerce Projekte haben einen relativ ähnlichen Aufbau:

  • Kernapplikation (Contao, Magento, etc.)
  • Module (externe und Eigenententwicklung)
  • Theme(s)
  • Meta Files wie docs, gulp, docker files, etc.

Vor Git und Composer lagen diese Sachen alle zusammen in einem SVN Repository auf unserem eigenen, lokalen Server. Angebunden an jeweils eine Trac-Instanz auf die auch der Kunde Zugriff hatte um Issues zu erstellen.

Monolith Repository - Kundenprojektbeispiel

Git Repositories

Git Repositories sollen schlank gehalten werden, da sie bei großen und/oder (sehr) vielen Dateien schlecht skalieren. So gibt es z.B. keine partiellen Checkouts sondern immer nur das gesamte Repository auf einmal. Bei SVN konnte man beispielsweise auch einzelne Sub-Verzeichnisse auschecken und darin arbeiten.

And git obviously doesn't have that kind of model at all. Git fundamnetally never really looks at less than the whole repo. Even if you limit things a bit (ie check out just a portion, or have the history go back just a bit), git ends up still always caring about the whole thing, and carrying the knowledge around.

So git scales really badly if you force it to look at everything as one huge repository. I don't think that part is really fixable, although we can probably improve on it

Bei stackoverflow und ähnlichen Quellen wird häufig auf obiges Zitat von Linus Torvalds, dem Erfinder von Git verwiesen und die Verwendung von multiplen Repositories empfohlen.

So kommt man leicht zu der Annahme das man für jedes Modul, Plugin oder Theme eines Kundenprojektes auch ein eigenes Repository verwenden sollte. Während die Empfehlung für Open Source Projekte zutrifft sieht es in der Agenturwelt doch etwas anders aus.

Nachteile multipler Repositories aus Kunden- / Agentursicht

Während Entwickler wahrscheinlich kein großes Problem mit dem Einsatz mehrer Respositories für ein Kundenprojekt haben, so wird es aus Kundensicht relativ schnell benutzerunfreundlich und der Overhead im Projektmanagement steigt schnell an.

Integrierte PM Tools

Kollaborations-Systeme wie Gitlab, Github, Bitbucket, Jira, etc. bieten zwar Möglichkeiten Projekte zu gruppieren, trotzdem bleiben Probleme wie Multiple Issue Tracker und Wikis.
Diese Tools erlauben in der Regel nur ein Wiki oder Issue Tracker, etc. je Repository. Dies eben wegen jener Definition:

1 Repositoy = 1 (Teil)Projekt 

Einen Kunden zu erklären das er für seinen Magento Store mehrere Issue Tacker zu nutzen hat, ist in den meisten Fällen schon grenzwertig.
Alleine schon die Entscheidung in welchen Issue Tracker das aktuelle Problem bzw. die Aufgabe Aufgabe zu erfassen ist, stellt die meisten Kunden vor eine nicht lösbare Aufgabe. Woher soll der Kunde auch wissen welche Komponente das aktuelle Problem verursacht?

Da die meisten Kundenprojekte intern bzw. closed sind nehmen wir als Beispiel Contao 4 aus der Open Source Welt, wo der Entwickler quasi der Kunde ist. Aktuell besteht eine Standard Contao 4 Installation aus mehreren Contao Repositories:

Wenn man jetzt ein Problem findet muss man schon etwas genauer nach der Ursache forschen bevor man ein Ticket aufmacht.

Tool Splitting: Issue Tracker, Wikis, ...

Man könnte argumentieren, dass es kein wirklicher Nachteil ist und die Schuld den Tools geben. Natürlich kann man separate Issue Tracker verwenden die nicht repository gebunden sind. Es ist aber ein großer Vorteil sowohl für Kunden als auch Entwickler mit einer integrierten Plattform zu arbeiten die ein durchgängiges UI und UX bietet.

Dazu ein weiteres gutes (also schlechtes) Beispiel aus Open Source Welt mit phpbb:

  • Pull Requests via github
  • Jira Issue Tracker
  • Wiki via MediaWiki.
  • Releases via phpbb.com

Übersichtlich und vor allem Einheitlich sieht anders aus.

Management Overhead

Auch der interne Projektmanagement-Aufwand steigt schnell an. Die Übersicht geht nicht nur für den Kunden schnell verloren. Wenn man statt in einem Projekt in 5 (1 Theme, 4 Extensions) nach offenen, nicht zugewiesen Tickets suchen muss, multipliziert mit der Anzahl an Kunden insgesamt, wird das schnell zu einem nicht zu unterschätzenden Aufwand.

Ebenfalls steigt das Fehlerpotential. Alleine schon das Managen von Cross Referenzen bez. Tickets, Pull / Merge Requests, doppelten Issues, etc. kann schnell im Chaos enden.

Und nicht immer gibt es die korrekten Anlaufstellen. Was ist wenn man einen Bug findet der externer Natur ist? Also z.B. das Kernsystem oder ein Fremdmodul betrifft. Oder wenn ein komplett neues Feature diskutiert werden soll. Welchen Issue Tracker verwendet man in solchen Fällen? In welches Wiki trägt man Informationen das Gesamtprojekt betreffend ein?
Man fängt an mit dem Gedanken zu spielen ein zentrales Master Projekt / Repository zu erstellen wo all diese Sachen gesammelt werden können. Also ein Repository was keinerlei projektbezogenen Source Code beinhaltet sondern maximal Meta Files.

Die meisten Collaboration Tools erlauben eine Strukturierung in der Art von:

Gruppenstruktur in Git Collaborations Tools

Die Gruppe entspricht dabei in der Regel dem Kunden. Nicht selten kommt es aber vor, dass man für einen Kunden mehrere Gesamtprojekte betreut. Zum Beispiel einen Online Store, Firmenwebseite und eine Intranetapplikation.

Wenn man nicht mit monolith repositories arbeitet müsste man also mehrere Gruppen für einen Kunden anlegen nach dem Schema:

  • Acme_Store
  • Acme_Website
  • Acme_Intranet

Eine Gruppierung von Gruppen gibt es meines Wissens nach bei keinen der bekannten Kollaborations Tools. Die einzige Option wäre wie zu SVN / Trac Zeiten beispielsweise jeweils eine Gitlab CE Installation je Kunde. Der dadurch entstehende zusätzliche Administrationsaufwand rechtfertigt dann schon fast eine Vollzeit Stelle.

CI / CD Integration

Ein Repository / Projekt sollte immer vollständig sein, d.h. auch jedes dieser Teilprojekte benötigt seine eigenen Tests, Build und Deployment Prozesse.
Spätestens da ist der Zeitpunkt erreicht wo man ein Master Projekt definieren möchte um z.B. nur ein zentrales Buildfile, Gulp / Grund Tasks, Dockerfile, etc. erstellen zu müssen.

Doch welches soll das Master Projekt sein. Modul Y? Das Theme X? Also kommen Überlegungen, dass das Master Projekt im Grunde genommen nur ein Meta Repository ist um die Subprojekte zu integrieren.

Wir sehen wo das hinführt. Man wünscht sich so langsam sein single, monolith SVN Repository zurück ;)

Single Repositories für Kundenprojekte

Die Gründe warum man Git Repositories schlank halten und splitten sollte haben wir weiter oben genannt. Auf Kundenprojekte wie Webseiten und Shops trifft es aber kaum zu. Wir entwickeln in der Regel keine Extensions im Umfang eines Contao CMS und Magento Shop Systems. Ein Kundenprojekt besteht meist aus einem Theme + ein paar Modulen.

Verglichen mit den Projekten auf die sich obiges Zitat eigentlich bezieht, ist die Anzahl / Größe der Programmdateien bei 99% der Kundenprojekte auch in größeren Agenturen sehr überschaubar.

In einem monolith Repository kommt die Trennung der Module, Plugins und Themes über die Verzeichnissstruktur. Das macht es für Entwickler sehr leicht sich einen Überblick zu verschaffen und das Projekt als Ganzes zu verstehen.

Der ganze Overhead aus multiplen Projekten / Repositories entfällt zum großen Teil. Für Kunden wie auch Entwickler werden die Workflows übersichtlicher und weniger komplex.

Verschlankung durch Composer

Dank Composer und SemVer können wir ausserdem eine starke Verschlankung schaffen da wir nicht mehr selber das Kern System (Contao, Drupal, Magento, etc.) versionieren müssen. Auch externe Module können einfach integriert werden und blähen das Repository nicht unnötig auf.
Wir müssen nur noch die richtige Versionsnummer in unserer composer.json eintragen und haben unsere Abhängigkeiten zum Kernsystem und Fremdmodulen definiert. Kein Code mehr der nicht auch von uns geschrieben wurde. Das schafft eine starke Verschlankung der zu verwaltenden Programmsourcen.

Desweiteren bietet Composer seit 9/2015 auch Support für monolith Repositories, also interne Abhängigkeitsverweise auf Module in Subdirs. Sehr praktisch für CI / CD.

Vorteile

Die im vorweg genanten Abschnitt genannten Nachteile von multiple Repositories je Gesamtprojekt treffen auf single, monolith Repositories nicht zu.

  • Zentraler Issuetracker. Issues sind nie an der falschen Stelle. Strukturierung durch Milestones, Labels
  • Zentrales Wiki: Alle wichtigen Information in One Place
  • Einheitliches UI / UX beim Einsatz integrierter Kollaborations Tools wie Gitlab
  • Zentraler CI / Build Prozess = Einfacheres Deployment
  • Übersichtlichkeit für Kunden und Entwickler
  • Schlanke Workflows
  • Einfache Administration
  • Optimale Abbildung von Gruppen <=> Kunden und Projekten <=> Repositories Beziehungen in Tools wie Gitlab, Github, etc.

Wir empfehlen trotzdem sorgfältig zu überlegen und sich bei den einzelnen Komponenten eines Gesamt- Kunden-Projektes vor allem folgende Frage zu stellen:

Wird oder kann diese Komponente künftig auch in anderen Projekten verwendet (werden)?
Wenn ja sollte diese Komponente entweder in ein eigenes Projekt / Repository oder in ein shared Repository ausgelagert werden.

Beispiele:

Habt ihr zum Beispiel ein Contao Content Element, welches ihr Kundenübergreifend in vielen Projekten verwendet? Dann ganz klar ein eigenes Repository.

Habt ihr einen Kunden der zwei Online Shops über euch betreibt und in beiden Stores eine Schnittstellen-Extension zu seiner Warenwirtschaft und ein individual entwickeltes Umfrage Modul einsetzt? Dann kommen diese beiden Extensions in ein shared Repository / Projekt.
Siehe Beispieldarstellung. 

Acme = Gruppe = Kunde
shared,Store1,Store2 = jeweils ein Repository



Beispiel eines shared Repositories

Desweiteren sollten große Dateien ohne direkten Projektbezug, also nicht notwendig für die Entwicklung oder Betrieb der Applikation, wie PSD-Files, DB Backups, etc. aus den Repositories rausgehalten bzw. wenn nötig in dem Fall tatsächlich in ein Meta Repository ausgelagert werden.

Fazit

Für Agentur- / Kundenprojekte sind häufig monolith / single Repositories das bessere Konzept.
Als wir uns mit der Frage anfangs beschäftigt hatten, wollten wir es zu Beginn korrekt machen und alle Module, Themes, etc. je Kundenprojekt in mehrere Repositories splitten. Nach den ersten Versuchen & Erfahrungen stellte sich aber schnell heraus, dass dies der falsche Ansatz für uns ist.

Zumindest in den meisten Fällen. Man sollte sich bei den Modulen / Themes / Plugins stets die Frage stellen ob man sie wiederverwenden, generalisieren oder sharen kann. Dann ist ein eigenes Projekt / Repository wahrscheinlich der bessere Weg.
Allerdings muss man das natürlich auch kostenmäßig und aus gesetzlicher Sicht berücksichtigen. Man kann ein Modul welches für einen Kunden entwickelt und voll bezahlt wurde nicht einfach bei einem anderen Kunden integrieren.
In solchen Fällen empfiehlt es sich solche Komponenten als Standardsoftware zu definieren und zu verkaufen.

Welche Ansätze werden in eurer Firma / Agentur verfolgt? Seht ihr Vor- / Nachteile die wir nicht berücksichtigt haben?

In den nächsten Posts wollen wir berichten über:

  • Git Workflow verbunden mit Continues Integration / Deployment
  • Docker Environments für Entwicklungsumgebungen

Update - 25.2.2016

Auf dem Contao Agenturtag 2016 haben wir das Thema vorgetragen und mit anderen Agenturen und Entwicklern darüber diskutiert.

Die Slides der Präsentation findet ihr hier: 

http://blog.cts-media.eu/files/documents/slides/workshop.html

Dieser Artikel teilen

Autor

Zurück

Kommentare

comments powered by Disqus