Změna v repu není změna na serveru
„Hotovo" má u softwaru dva významy. Kód je hotový, když je napsaný, otestovaný a v gitu. Změna je hotová, když ji vidí ten, pro koho je. Mezi tím leží nasazení, a na to se zapomíná nejsnáz, protože ho žádný nástroj neudělá sám.
Commit proběhl, monitor nevznikl
Mám skript, který mi zakládá hlídání dostupnosti služeb. Přidal jsem do něj nový monitor, commit proběhl, git byl čistý, úkol odškrtnutý. Jenže skript se pouští ze serveru, ne z repozitáře, a na server jsem ho nezkopíroval. Ostrý běh vyrobil jeden monitor místo dvou.
Nic nekřičelo. Kód byl správně, git byl v pořádku. Chyběl krok, o kterém se nikde nemluví, a to, že chybí, nebylo vidět ani z gitu, ani ze serveru.
Půlka opravy
Druhá varianta je zákeřnější. LevisIDE, moje vývojové prostředí, má dvě části: soubory, které si stáhne prohlížeč, a proces, který běží na serveru. Jednou jsem proces přeložil o minutu dřív, než jsem commitl opravu, kterou měl obsahovat. Soubory pro prohlížeč se později přeložily znovu, takže nové chování terminálu naběhlo. Proces ale celý den běžel ze staršího překladu.
Vypadalo to jako záhadně poloviční oprava, ne jako nenasazení. Poznat se to dalo jednoduše, porovnáním času překladu s časem commitu:
git log -1 --format=%cd --date=format-local:%H:%M -- mobil/
date -r dist-mobil/index.js +%H:%M
Od té doby nasazuju jedním příkazem, který přeloží obě části a restartuje službu. Nasazení je krok. Ne vedlejší efekt a ne něco, na co musím myslet.
Nahráno neznamená vidět
U webů je mezi „nahráno" a „vidět" ještě jedna vrstva: cache. Tenhle web i moje Tipovačka běží na Wedosu a před nimi stojí CDN, síť serverů, která drží kopie souborů blíž k návštěvníkům. Stránky se díky tomu načítají rychle. Jenže po nasazení může CDN ještě chvíli rozdávat starou verzi. FTP klient ohlásí, že upload doběhl, a na webu je pořád to staré.
Nejhorší je stránka napůl nová: HTML nové, styl starý, nebo obráceně. Tady by to dopadlo ještě hůř. Každý styl a skript má v HTML otisk (SRI, integrity="sha384-…"), a když soubor otisku neodpovídá, prohlížeč ho zahodí. Nové HTML se starým CSS by znamenalo stránku úplně bez vzhledu.
Proto tu platí tři věci:
- Každé nasazení má novou verzi. Odkazy na styly a skripty nesou
?v=s číslem verze. Nová verze je pro CDN nová adresa, takže starou kopii nemá odkud vzít. Nasazovací skript odmítne nahrávat, když verzi nezvednu. - Otisky počítá server z nasazeného souboru. Nejde je zapomenout přegenerovat, protože je nikdo negeneruje ručně.
- Po nasazení ověřuju ostrý web, ne svůj disk. Skript stáhne každou stránku a každý odkazovaný soubor přesně z adresy, kterou dostane návštěvník, spočítá otisk a porovná ho s tím v HTML. Když CDN ještě vrací starou verzi, výsledek zní „nahráno, ale ještě to není vidět". Ne „hotovo".
Jak se to ověřuje
Na ruční kontrolu stačí curl. Hlavičky řeknou, jestli odpověď přišla z cache a jak je stará:
curl -sI https://levinger.cz/ | grep -iE 'last-modified|x-cacheable|age'
Hlavičky ale nejsou všechno, rozhoduje obsah. Když nasazuju změnu textu, hledám nový text přímo v odpovědi serveru. Když měním styl, porovnávám otisk staženého souboru. Že upload doběhl, je tvrzení o mém počítači. Že se změna projevila, je tvrzení o webu. Každé chce vlastní důkaz.
Jednou jsem to spletl i mimo web. Televizi jsem nastavil vlastní CSS a ověřil si, že si ho stáhla. Z toho jsem vyvodil, že bude vypadat stejně jako v prohlížeči. Nevypadala. Její starý prohlížeč pravidla, kterým nerozuměl, tiše zahodil. Doručení a účinek jsou dvě různá tvrzení, i když se jedno zdá jako důsledek druhého.
Pravidlo
Pracoviště není nasazení. Rozdělaná práce patří na můj disk. Na server jde jen hotový a ověřený stav, jedním krokem, který nejde přeskočit ani udělat napůl. A „hotovo" píšu až ve chvíli, kdy změnu vidím tam, kde ji uvidí ostatní.
U AI to platí dvojnásob. Asistent, který commitne a ohlásí hotovo, je horší než ruční práce, protože vypadá hotově. Proto po něm chci důkaz z ostrého prostředí, ne zprávu, že příkaz doběhl.