Efektivní monorepo: Jak jsme srazili build time backendu o 95 %


Dlouhodobý vývoj komplexního backendu v polyrepo modelu (35+ repozitářů) vedl v našem ekosystému k neúnosnému overheadu při delivery.
Každá změna ve sdílených knihovnách (common modules) vyžadovala kaskádu merge requestů, postupné publikování do Artifactory a manuální synchronizaci verzí.
Migrací na monorepo s multi-module Gradle architekturou a agresivním cachingem jsme zkrátili build times o 95 % a sjednotili správu závislostí při zachování kompletní historie kódu.

Deep Dive
Původní stav odrážel historickou genezi – servisy byly přebírány od různých týmů, což vyústilo v roztříštěnost verzí knihoven i CI konfigurací.
Kritickým pain pointem se stala synchronizace změn. Pokud vývojář potřeboval upravit třídu ve sdílené knihovně, musel projít několika koly MRs kvůli vzájemným závislostem a teprve poté aktualizovat cílovou mikroservisu.
Pro migraci jsme zvolili nástroj git-filter-repo. To nám umožnilo transformovat původní repozitáře do podadresářů nového monorepa při zachování integrity historie commitů od roku 2019.

Optimalizace CI/CD:
Build monorepa o tomto rozsahu by bez optimalizace trval desítky minut.

Nasadili jsme:
Gradle Configuration Cache: Gradle při každém spuštění nemusí rekalkulovat graf úloh, což srazilo build celého projektu na 55 sekund.

Docker Buildx: Využili jsme moderní build engine s podporou pokročilého cachování vrstev. Odstraněním nepotřebných vrstev a optimalizací zbývajících za účelem maximalizace cachovacího potenciálu v Dockerfiles jsme srazili build image ze 144 minut na 5 minut.

Sdílená infrastruktura v CI: Místo izolovaných databází pro každý modul jsme zavedli sdílený Postgres kontejner pro JOOQ codegen, čímž jsme radikálně snížili resource footprint CI runnerů.

Trade-offs
Přechod na monorepo přinesl i nové výzvy:

Flaky Tests:
Paralelní běh testů v jednom monorepu odhalil špatně izolované integrační testy, které v polyrepo modelu procházely jen díky náhodě.

Log Management:
S 14 000 unit testy začal CI runner narážet na limity velikosti logů. Řešením bylo plošné vypnutí logování přes logback-test.xml pro standardní běhy.

Deployment Strategy:
Monorepo nás vede k atomickým releasům. I když je technicky možné nasadit jednu servisu, standardem se stává nasazování konzistentního stavu celého monorepa pro eliminaci verzovacích chyb na prostředí.

Budeme rádi za vaše názory – vyjádřete se ke článku na LinkedIn.