Radek Krejčí

Jak v LydiaCMS automatizuji kontrolu změn a nasazování

LydiaCMS se postupně rozrostlo do samostatných Composer balíčků. Změna v jádře proto může ovlivnit několik modulů i aplikací, které je používají. Ruční kontrola každého kroku by byla pomalá a nechávala příliš mnoho prostoru pro chybu.

Cílem je automatizovat co největší část opakovatelné práce — od kontroly architektury přes testování a hromadné refaktoringy až po vydávání balíčků a nasazování. Ruční rozhodování a kontrola výsledku zůstávají, ale samotné provedení má být co nejvíce opakovatelné.

Pravidla, která hlídají bezpečnost a architekturu

PHPStan spouštím na maximální úrovni. Obecná statická analýza ale nezná bezpečnostní a architektonická pravidla konkrétní aplikace, proto používám také 12 vlastních pravidel pro LydiaCMS.

Například SignalHandlerRequiresCapabilityRule kontroluje, že každá administrační akce obsahuje kontrolu příslušného oprávnění. Pokud při přidání nové akce na kontrolu zapomenu, chyba se zachytí při statické analýze místo toho, aby vznikla nechráněná cesta v administraci.

Pro hromadný refaktoring a vynucování architektonických pravidel používám kombinaci AI a 14 vlastních pravidel pro Rector. AI mi pomáhá změnu navrhnout a rozpracovat, zatímco Rector provede definovanou transformaci konzistentně napříč balíčky. Výsledný diff následně kontroluji před začleněním. Automatizace zde nenahrazuje kontrolu výsledku; omezuje mechanickou práci a zajišťuje jednotné provedení změny.

Zdrojové kódy: lydiacms-phpstan a lydiacms-rector.

Více vrstev kontroly místo jednoho čísla

Jedna vrstva testů nestačí pro všechny druhy chyb. Jednotkové testy rychle kontrolují izolovanou logiku, integrační testy ověřují spolupráci s databází a E2E scénáře procházejí skutečné chování veřejného webu a administrace v prohlížeči.

  • Jádro obsahuje více než 800 testovacích metod pro jednotkové a integrační scénáře v Nette Testeru.
  • Ukázkovou aplikaci ověřuje více než 250 E2E testů v Playwrightu.
  • Testy používají samostatnou databázi, ochranu proti záměně s vývojovou databází a izolovaná paralelní vlákna. Databázové změny jednotlivých testů se vracejí transakcí.

Jádro aktuálně dosahuje přibližně 62% code coverage. Dalším cílem je přiblížit se k 80 %. Tuto hodnotu nevnímám jako univerzální hranici kvality ani jako důkaz, že je systém bez chyb. Je to praktický cíl inspirovaný Paretovým principem: pokrýt většinu důležitého chování, aniž by se neúměrné množství práce spotřebovalo na poslední, málo přínosné procentní body.

Prioritu nemají nejsnáze testovatelné řádky, ale bezpečnostní pravidla, datové operace, oprávnění a části systému, jejichž chyba by měla největší dopad. Celou sadu jádra spouštím z aplikace lydiacms-demo v Dockeru a v GitLab CI z ní vytvářím HTML report pokrytí.

CI/CD pro samostatné balíčky

Většina repozitářů přebírá společnou konfiguraci GitLab CI. Povinná kontrola ověří strukturu composer.json a syntaxi všech PHP souborů. Pipeline spouští také sdílenou kontrolu stylu; specializované balíčky přidávají vlastní statickou analýzu a testy.

Po změně v hlavní větvi pipeline vytvoří další verzovaný tag a publikuje balíček do soukromého Composer registru. Aplikace při sestavení release instaluje přesné verze uzamčené v souboru composer.lock, takže produkční sestavení nevzniká z náhodně aktuálního stavu jednotlivých repozitářů.

Automatizovaný release s cestou zpět

I přes statickou analýzu a testy se může při sestavení nebo nasazení něco pokazit. Proto má také release automatické kontroly a mechanismus návratu k předchozí verzi. Nasazovací skript neupravuje soubory právě běžící aplikace, ale každou verzi připraví do samostatného adresáře:

  1. vytvoří nový release a pomocí composer install nainstaluje uzamčené produkční závislosti,
  2. připojí sdílenou konfiguraci, logy a nahrané soubory,
  3. zkušebně nastartuje DI kontejner a nefunkční sestavení zastaví ještě před přepnutím provozu,
  4. během zálohy databáze a migrací přepne web do maintenance režimu,
  5. atomicky přepne symbolický odkaz na nový release a provede health check veřejného webu i administrace.

Pokud health check selže, skript vrátí předchozí souborový release. Databázi lze obnovit z předmigrační zálohy, ale tento krok není vždy automatický — mohl by odstranit data zapsaná po vytvoření zálohy. Rollback proto rozlišuje mezi bezpečným návratem kódu a potenciálně destruktivní obnovou databáze.

Méně ručních kroků, méně prostoru pro chybu

Smyslem automatizace v LydiaCMS není pouze zrychlení práce. Každý opakovaný ruční krok představuje možnost, že bude jednou vynechán nebo proveden jinak.

Proto postupně automatizuji kontroly oprávnění a architektury, refaktoringy napříč balíčky, testování, verzování, sestavení release, zálohu databáze, migrace i následný health check. Ručně zůstávají především rozhodnutí, posouzení rizika a kontrola výsledného diffu.

Přenositelný princip není automatizovat všechno bez rozmyslu. Největší hodnotu má automatizace opakovaných kroků, jejichž chybné nebo nekonzistentní provedení může ovlivnit bezpečnost, stabilitu nebo další rozvoj systému.

← LydiaCMS

Kontakt

Hledáte posilu do PHP týmu?

Pokud řešíte nový backendový projekt, integraci nebo potřebujete posílit vývoj existujícího systému, napište mi.