Ještě před rokem vypadal náš release proces takhle: vývojář řekl „u mě to funguje”, operations dostal WAR soubor na sdíleném disku, v pátek v 18:00 ho nasadil na produkci a celý víkend držel telefon po ruce. Dnes máme Jenkins, automatické buildy a deployment na test prostředí po každém commitu. A v pátek večer chodíme na pivo. Tady je ten příběh.
Proč Jenkins (a ne Bamboo, TeamCity, …)¶
Výběr CI nástroje byl překvapivě jednoduchý. TeamCity je skvělý, ale licence pro větší tým není levná. Bamboo se hodí, pokud žijete v Atlassian ekosystému (a my žijeme — JIRA, Confluence, Stash). Ale Jenkins je zdarma, má obrovský ekosystém pluginů a — hlavně — náš ops tým s ním měl zkušenosti z předchozích projektů.
Nainstalovali jsme Jenkins na dedikovaný RHEL server (4 CPU, 16 GB RAM — pro CI je potřeba víc, než byste čekali). Master-slave architektura s dvěma build agenty: jeden pro Java projekty (Maven), druhý pro .NET věci (MSBuild). Celý setup trval dva dny včetně integrace se Stash (git webhooky) a JIRA.
Pipeline: od commitu k testovacímu prostředí¶
Náš build pipeline je jednoduchý, ale pokrývá to podstatné:
- Checkout — Jenkins stáhne kód ze Stash (git) po každém push
- Build — Maven clean install, kompilace a packaging
- Unit testy — JUnit, ~1200 testů, běží 4 minuty
- Static analysis — FindBugs, PMD, Checkstyle (přes Sonar)
- Deploy na DEV — automatický deployment WAR na GlassFish
- Integration testy — Selenium testy proti DEV prostředí
- Deploy na TEST — manuální trigger (klik v Jenkinsu)
Celý pipeline od commitu po integration testy trvá asi 15 minut. To je obrovský pokrok oproti stavu „buildíme jednou týdně a modlíme se”.
SonarQube — quality gate, který nepustí špatný kód¶
SonarQube (tehdy ještě Sonar) byl game changer pro kvalitu kódu. Nastavili jsme quality gate: pokud nový kód má coverage pod 70 %, obsahuje kritické bugy nebo security vulnerabilities, build failne.
První týden bylo hodně červených buildů. Vývojáři nadávali. Ale po měsíci si zvykli psát testy a kód se výrazně zlepšil. Technický dluh v Sonaru klesá každý sprint, což je krásný graf na sprint retrospektivě.
Deployment automatizace — zatím na půl cesty¶
Na DEV a TEST prostředí deployujeme automaticky. Ale produkční deployment je stále manuální proces s change managementem, schválením a rollback plánem. A upřímně — pro naše klienty v regulovaném prostředí to tak asi i zůstane. Auditor nechce slyšet, že na produkci nasazuje robot.
Deployment script je jednoduchý Bash: zastaví GlassFish domain, nakopíruje nový WAR, spustí a ověří health check URL. Není to Puppet ani Chef — je to skript. Ale funguje a ops tým mu rozumí. Někdy je jednoduchost cennější než elegance.
Git workflow — feature branches a pull requesty¶
S CI jsme zároveň přešli z SVN na Git (Atlassian Stash). A s tím přišly feature branches a pull requesty. Každá feature se vyvíjí ve vlastní větvi, po dokončení se vytvoří pull request, kolega udělá code review a merge do develop.
Na začátku byl odpor — „proč máme dělat code review, je to ztráta času”. Po měsíci nám code review zachytil dva bezpečnostní problémy a tři performance bugy. Teď si nedovedeme představit merge bez review.
Problémy, na které jsme narazili¶
Flaky testy. Selenium testy jsou notoricky nestabilní. Test projde lokálně, selže na CI. Řešení: explicitní waity místo Thread.sleep, izolované test data, clean browser session. Stále máme ~5 % flaky rate, ale je to lepší než 30 % na začátku.
Build time. 15 minut je OK, ale s rostoucím projektem to bude horší. Zvažujeme paralelizaci Maven modulů a možná přechod na Gradle, který je v inkrementálních buildech rychlejší.
Environment parity. „Na DEVu to funguje, na TESTu ne” je frustrace, kterou CI úplně nevyřeší. Ale pomáhá — aspoň víte, že build artefakt je identický. Problém je v konfiguraci prostředí, a to zatím řešíme manuálně. Možná jednou zkusíme Puppet nebo Chef.
Čísla, která mluví¶
- Release cyklus: z 4 týdnů na 2 týdny (a směřujeme k 1)
- Produkční incidenty po releasu: z ~5 na ~1 za kvartál
- Průměrný čas na opravu bugu: z 3 dnů na 4 hodiny
- Vývojářský feedback loop: z „za týden” na 15 minut
Začněte jednoduše¶
Nepotřebujete celý DevOps stack od prvního dne. Nainstalujte Jenkins, napojte ho na git, přidejte automatický build a testy. To samo o sobě změní způsob, jakým váš tým pracuje. Zbytek — deployment automatizace, infrastructure as code, monitoring — přidejte postupně, když na to budete připraveni. CI je cesta, ne cíl.