niceshops
Unser Weg zum Monorepo
Description
Lena Höhsl und Sebastian Mandl von niceshops sprechen in ihrem devjobs.at TechTalk darüber, wie das Devteam im Unternehmen eine einheitliche Struktur in viele kleine Teilprojekte gebracht hat.
Beim Videoaufruf stimmst Du der Datenübermittlung an YouTube und der Datenschutzerklärung zu.
Video Zusammenfassung
In „Unser Weg zum Monorepo“ erklären Lena Höhsl & Sebastian Mandl (niceshops) den Wechsel von vielen Shop‑Repositories mit Git‑Flow und Jenkins zu einem GitLab‑basierten Monorepo mit Trunk‑Based Development und strikt MR‑basiertem Arbeiten. Sie zeigen, wie eine durchgängige QA‑Pipeline (Linting, statische Analyse, Unit‑Tests), Code‑Ownership, MR‑Labels, YouTrack‑Integration und ein vereinfachtes Staging/Deployment (einmaliger Code‑Upload, V‑Hosts pro Shop) Merge‑Konflikte, Laufzeiten und Komplexität deutlich reduzieren und die Codequalität erhöhen. Übertragbar sind ihr Migrationsvorgehen (Voranalyse, Skript, Dependency Injection, „Tag X“-Cutover) und die Learnings zu kleinen, stets funktionierenden Inkrementen; als Ausblick planen sie automatisierte Cypress/Selenium‑Tests und Application Warming.
Vom Git-Flow-Overhead zum Monorepo: Wie niceshops mit Trunk-Based Development Tempo und Qualität steigert
Kontext: „Unser Weg zum Monorepo“ mit Lena Höhsl & Sebastian Mandl (niceshops)
Bei DevJobs.at haben wir die Session „Unser Weg zum Monorepo“ von Lena Höhsl und Sebastian Mandl (niceshops) verfolgt. Der Titel führt zwar auf die Spur, aber wie die beiden gleich zu Beginn klar machen: Das Monorepo war nur die sichtbare Spitze – tatsächlich handelte es sich um eine umfassende Modernisierung des gesamten Dev-Stacks. Vom Branching-Modell über CI/CD bis hin zum Deployment und den Entwicklungsgewohnheiten wurde vieles neu gedacht und konsequent vereinfacht.
Was uns besonders auffiel: Die Umstellung wurde nicht primär als Tool-Migration verstanden, sondern als organisatorischer und kultureller Wandel hin zu kleineren, sichereren Schritten – abgestützt durch Automatisierung in GitLab und klare Regeln für Quality Gates.
Ausgangslage: Viele Shops, noch mehr Repositories – und kaum Überblick
niceshops betreibt zahlreiche Online-Shops. Vor der Umstellung stand hinter jedem Shop ein eigenes Git-Repository. Übergreifende Komponenten waren zusätzlich als Submodule eingebunden. Sebastian beschreibt das frühere Setup so:
- Jedes Shop-Projekt hatte ein eigenes Repository.
- Darunter waren mehrere Submodule eingebunden:
- eine gemeinsame Library (Library-Source-Code)
- zentrale Konfigurationen (Config)
- ein Repository für Bilder
- ein ehemals separates Lagerhaltungsmodul (das bereits zuvor integriert wurde)
Was aus der Ferne strukturiert klingt, war in der Praxis „selbst für einen erfahrenen Entwickler total undurchsichtig“. Wer eine Änderung über mehrere Shops hinweg durchführen wollte, musste Shop für Shop auschecken, anpassen, pushen, Reviews orchestrieren – ein zeitraubender und fehleranfälliger Prozess. Hinzu kamen lang laufende Pipelines pro Shop, die die Feedback-Zyklen weiter verlängerten.
Git-Flow in der Praxis: Team-Branches, Feature-Branches – und eskalierende Merges
Organisatorisch setzte niceshops auf Git-Flow mit drei permanenten Branches: Master, Develop und Hotfix. Zusätzlich haben die Teams Team-Branches für die Sprints angelegt, darunter wiederum Feature-Branches. Am Sprintende wurden die Team-Branches zurück in Develop gemerged – ein Moment, den Sebastian unverblümt als Ort der „richtig, richtig eskalierenden“ Merge-Konflikte beschreibt.
„…das war meistens der Zeitpunkt, wo die Merge-Konflikte richtig, richtig eskaliert sind… weil natürlich in allen Teams sehr viel weitergegangen ist, aber die Information zwischen den Teams einfach nicht geteilt worden ist.“
Das Resultat: viel Koordinationsaufwand, Konflikte im schlechtesten Zeitpunkt, späte Integration und daraus resultierende Risiken. Transparenz litt, da Änderungen lange in Branches blieben und erst am Ende sichtbar wurden.
CI als Blackbox: Jenkins als „Fluch und Segen“
Für das CI setzte niceshops auf Jenkins – mächtig, aber aus Sicht der Entwickler eine Blackbox. Sebastian spricht von „zehn verschiedenen Programmiersprachen“ innerhalb der Jenkins-Logik. Die DevOps-Teams waren zwar sattelfest, Entwicklerinnen und Entwickler „haben nur Knöpfe gedrückt“. In Summe fehlte die Nähe zur Pipeline-Logik – und damit auch ein Gefühl für die Qualität der eigenen Schritte entlang des Wegs zum Merge.
Der Wendepunkt: Ein Monorepo und ein neuer Ort der Zusammenarbeit (GitLab)
Die Entscheidung fiel radikal aus: „Wir haben eigentlich alles über den Haufen geschmissen.“ Aus den Einzel-Repositories wurde ein großes Monorepo, der vormals bare-metal Git-Server wich einem GitLab-System. Damit verknüpft: Ein grundlegender Wechsel im Branching- und Delivery-Modell.
Trunk-Based Development statt Git-Flow: Kleine Schritte, früheres Feedback
Die größte Umstellung betraf das Branching: weg von Git-Flow, hin zu Trunk-Based Development.
- Der Trunk (Main/Master) ist der zentrale Arbeitszweig.
- Alle Änderungen entstehen in kurzen, kleinen Feature-Branches direkt vom Trunk.
- Rückführung erfolgt ausschließlich via Merge Requests (MR) in den Trunk.
- Release-Branches „bleiben stehen“; Hotfixes werden zuerst im Main gefixt und per Cherry-Pick in die jeweilige Release-Linie übernommen.
Dieses Vorgehen reduziert Integrationsrisiken, weil Änderungen schneller im Main landen, Konflikte kleiner sind und Teams unmittelbarer voneinander profitieren. Sebastian bringt es auf den Punkt:
„Es sind die Änderungen viel kleiner… als Reviewer tut man sich viel einfacher… und es sind einfach viel weniger Fehler.“
Quality Gates im Merge Request: Protected Branches, Auto-MR, QA-Pipeline, Gruppenfreigaben
GitLab spielt seine Stärken genau dort aus, wo früher Jenkins als Blackbox stand. niceshops hat mehrere Mechanismen verankert:
- Keine Direkt-Pushes auf den Master: Alles läuft über Merge Requests.
- Auto-Erstellung von MRs: Beim Push eines Branches wird automatisch ein Merge Request erzeugt.
- Vollständige QA-Pipeline beim MR:
- PHPStan und Linting
- Unit-Tests
- Bereichsverantwortung durch Gruppenfreigaben: Relevante Teilbereiche im Source-Code sind Gruppen zugeordnet, deren Zustimmung im MR erforderlich ist.
Das Ergebnis ist ein klarer, reproduzierbarer Qualitäts-Workflow. Der Main bleibt „so gut wie immer grün“, weil die Pipeline die Eintrittskarte in den Trunk ist und Änderungen klein bleiben:
„…wir haben diesen einen Merge-Tag nicht mehr, wo wir einen riesigen Merge-Konflikt haben… es sind eigentlich immer diese kleinen Änderungen, die zurück reingemerged werden.“
Deployment neu gedacht: Jenkins raus, GitLab rein – Staging vereinfacht per V-Hosts
Mit Jenkins verschwand auch das alte Deployment. In GitLab entstand eine neue Pipeline-Logik.
- Live-Deployment bleibt ähnlich zum früheren Prozess.
- Staging wird durch das Monorepo deutlich einfacher: Der gesamte Code wird einmal auf den Server gebracht; per Virtual Hosts wird pro Shop (A, B, …) die Zielinstanz ausgewählt.
Besonders elegant: Labels im Merge Request steuern die Pipeline-Verarbeitung. Beim Push werden Labels automatisch zugewiesen – abhängig davon, in welchen Bereichen Änderungen stattfanden. Dazu kommen YouTrack-Informationen, die dem MR über eine eigens geschriebene Schnittstelle zugeordnet werden. Die Sicht auf Tickets im MR bündelt Kontext an einem Ort.
„…ein Riesenvorteil, weil ich eigentlich nur mehr ein System habe, mit dem ich arbeiten muss.“
Vorarbeit: Zwei Monate Analyse, Skript in neun Iterationen, Pipeline-Design, Architektur-Refactoring
Die Migration fußte auf solider Vorbereitung:
- Zwei Monate Analyse: Was ist notwendig? Was muss wie umgestellt werden?
- Ein Kollege schrieb ein Umstellungsskript – neun Iterationen waren nötig, bis „wirklich alles dort war, wo es hingeführt hat“.
- Das DevOps-Team baute parallel die GitLab-Pipelines: MR-Erstellung, Deployment-Prozess, QA-Stufen.
- In den Entwicklungsteams liefen vorbereitende Aufgaben: Applikationsklassen wurden aufgelöst und durch Dependency Injection ersetzt. Ziel: weniger hart verdrahtete Shop-spezifische Instanziierungen und bessere Überschreibbarkeit ohne „Ping-Pong“ zwischen Ebenen.
Der Cutover: Ein Sprint, Tabula Rasa, zwei Wochen Auftauphase
Für die Umstellung reservierte niceshops einen kompletten Sprint über alle drei Scrum-Teams hinweg. Am „Tag X“ galt „Tabula Rasa“: Alles wurde in das neue Repository kopiert, das Alte eingefroren. Für zwei Wochen blieb eine „Auftauschstufe“, um im Live-System mögliche Bugs aus den alten Strukturen noch deployen zu können. Danach: Fokus auf die QA-Pipeline und das Ausbügeln kleinerer Fehler im neuen Setup.
Sebastian spart nicht mit Pragmatismus: Was vor Tag X nicht fertig war, „war verlorene Lebenszeit“ – denn Nachziehen einzelner Brocken aus dem alten System ins Monorepo war mühsam. Das zeigt die Wichtigkeit eines klaren Cutovers und einer strikten Scope-Definition.
Warum sich der Schritt lohnt: Sofortige und sichtbare Verbesserungen
Nach einigen Monaten Betrieb zieht Sebastian ein positives Zwischenfazit:
- Höhere Softwarequalität: durch kleinere Änderungen, frühere Integration und automatische Qualitätssicherung.
- Schnellere Reviews: kleine MR-Deltas sind leichter zu verstehen und zu prüfen.
- Stetig grüner Main-Branch: Integrationshölle am „Merge-Tag“ entfällt.
- Sofortiger Team-Nutzen: „Das gesamte Team profitiert sofort von einer Änderung, die zurück in den Main geht – also alle Teams profitieren sofort davon.“
Ein unterschätzter Effekt: Unbewusstes Mit-Testen. Wer am ersten Sprint-Tag eine Änderung am Bestellprozess merged, profitiert von jeder Person, die innerhalb des Sprints damit in Berührung kommt – weil die Änderung im Main liegt und von allen implizit genutzt wird.
Architekturgewinn: Schluss mit Code-Ping-Pong
Vorher gab es ein „Ping-Pong“ zwischen Applikationsebene (Shop-spezifische Klassen) und der Library. Ein Teil instanziierte den anderen, überschrieben wurde auf Shop-Ebene, zurückgegriffen wieder in die Library. Mit Dependency Injection wurde dieses Geflecht vereinfacht. Ergebnis: weniger Dateien, klarere Verantwortlichkeiten, weniger kopplungsgetriebene Seiteneffekte.
Lessons Learned: Menschen, Gewohnheiten, Taktung
Die technische Migration war nur ein Teil der Herausforderung. Die eigentliche Umstellung fand im Kopf statt:
- Alle mitnehmen: „Von Anfang an alle abzuholen und ihnen zu zeigen, wie die Arbeitsweise dann sein wird“ – das war laut Sebastian die größte Hürde.
- Arbeitsstil ändern: Von „Riesenprojekten“ zu „kleinen Häppchen“. Und jeder Schritt, der in den Trunk strebt, „muss immer komplett funktionieren“ – Zwischenzustände, die erst später zusammenschnappen, sind tabu.
- Tag X koordinieren: Über drei Scrum-Teams hinweg bedeutete der harte Cut, dass unfertige Arbeiten kaum „billig“ nachgezogen werden konnten. Der Druck, in den neuen Takt zu kommen, war real – aber er hat disziplinierende Wirkung auf Planung und Scope gesunder, kleiner Schritte.
Nächste Schritte: Mehr Automatisierung in der Pipeline und Application Warming
Die Reise ist nicht zu Ende. niceshops fokussiert weitere Verbesserungen in der Pipeline:
- Automatisiertes Frontend-Testing: Die QA-Abteilung überführt manuelle Tests in automatisierte Cypress- oder Selenium-Tests. Per Label im MR sollen diese Tests bei Bedarf in der Pipeline mitlaufen – „vollautomatisch wird das komplette Frontend einfach durchgeklickt oder auch im Backend die Prozesse“.
- Application Warming beim Deployment: Konfigurationen und Cache-Dateien sollen direkt beim Ausrollen vorab generiert werden, damit der erste Request nach einem Deployment nicht mehr Cache-Aufbau betreiben muss. Ziel: schnellere, stabilere Livesysteme unmittelbar nach dem Deploy.
Praktische Takeaways für Teams mit ähnlichen Schmerzen
Auch wenn jedes Setup individuell ist, lassen sich einige Prinzipien aus der niceshops-Erfahrung ableiten – wohlgemerkt all das in den Worten und Beobachtungen der Session „Unser Weg zum Monorepo“ mit Lena Höhsl & Sebastian Mandl (niceshops):
- Transparenz vor Komplexität: Viele Repos mit Submodulen schaffen scheinbare Ordnung, aber oft geht Übersicht verloren. Ein Monorepo reduziert Integrationskosten – vorausgesetzt, es gibt disziplinierte Quality Gates.
- Trunk-Based Development diszipliniert: Kleine Branches, schnelle Merges, kontinuierliche QA – statt seltener, großer Integrationsschritte mit Konflikt-Risiko.
- Merge Requests als Dreh- und Angelpunkt: Protected Branches, automatische MR-Erstellung, statische Analyse, Tests und gruppenbasierte Freigaben sorgen für einen immer „grünen“ Trunk.
- Deployment konsolidieren: Einmal deployen, per V-Host routen – und Pipeline-Labels nutzen, um nur relevante Pfade anzustoßen.
- Tooling nicht als Blackbox belassen: Entwickler müssen die Qualitätssicherung lesen, verstehen und beeinflussen können. GitLab als zentraler Ort erleichtert das.
- Vorbereitung zahlt sich aus: Analyse, Migrationsskript (mehrere Iterationen!), parallel entwickelter Pipeline-Stack und gezielte Refactors wie Dependency Injection ebnen den Weg.
- Harte Schnitte planen: Ein klar definierter Tag X verhindert, dass alte und neue Welt zu lange parallel laufen – aber er verlangt auch entschiedene Planung über Teamgrenzen hinweg.
- Früh integrieren, gemeinsam testen: Änderungen am Anfang des Sprints mergen, damit die Organisation unbewusst „mittestet“.
- Architektur entrümpeln: Wo „Ping-Pong“ zwischen Ebenen entsteht, helfen DI-Prinzipien und klare Verantwortlichkeiten.
- Weiter automatisieren: E2E-Tests und Application Warming schließen Lücken zwischen technischem Erfolg der Pipeline und wahrgenommener Produktqualität im Live-System.
Fazit: Monorepo als Katalysator – die eigentliche Veränderung ist der Takt
„Unser Weg zum Monorepo“ von Lena Höhsl & Sebastian Mandl (niceshops) zeigt, wie eine fokussierte Umstellung auf Trunk-Based Development und GitLab die Entwicklung beschleunigt und gleichzeitig Qualität erhöht. Das Monorepo war das Vehikel – der eigentliche Fortschritt entstand durch kleine, saubere Änderungen, einen immer grünen Main und klare, automatisierte Quality Gates. Besonders überzeugend ist der praktische Zuschnitt: automatische MR-Erstellung, Labels als Steuerhebel, YouTrack-Integration für Kontext, DI statt Ping-Pong.
Wer mit Git-Flow-Müdigkeit, Merge-Staus und pipelinebedingter Intransparenz kämpft, findet in diesem Erfahrungsbericht eine klare Roadmap: konsequent vereinfachen, Feedback vorziehen, Integration alltäglich machen – und so Organisation und Code in einen gemeinsamen, ruhigeren Takt bringen.
Weitere Informationen zur Session: www.unser-weg-zum-monorepo.com