V pracovním procesu vývojáře se občas vyskytne práce, která je poměrně důležitá, ale navenek není vidět. Tím je například aktualizace kódu. Aktualizace vzniká v případě, kdy máte aplikaci, která se skládá z mnoha různých modulů. Tyto moduly vyvíjejí jiné subjekty – organizace, týmy, programátoři, kteří je nahráli do veřejných repozitářů a dali ostatním k dispozici pro používání. Každý modul je vydán v nějaké verzi. Svou aplikaci jste postavili na těchto verzích, odladili ji a doplnili vlastní funkcionalitu. Použité verze je nutné při instalaci aplikace zafixovat, aby se použily jen ty, pro které jste svůj kód připravili. Jen tak máte jistotu, že váš produkt bude s moduly fungovat. Ovšem vše kolem se stále vyvíjí a mění. V modulech se opravují nalezené chyby nebo přidávají nové vlastností. Z toho důvodu je vhodné čas od času fixaci zrušit a začít používat novější verze.
Sémantické verzování
Pro snadnější přechod na novější verze se používá takzvané sémantické verzování. O tom již existuje mnoho článků a návodů, tak jen ve stručnosti připomenu základ: verze se definuje třemi čísly – hlavní, vedlejší a oprava, například 1.2.3. Hlavní část vývojáři oznamuje, že daný modul není kompatibilní s předchozí verzí. Vedlejší část znamená, že modul obsahuje nějakou novou funkcionalitu, ale přesto je s předchozí verzí stále kompatibilní. Třetí část pak říká, že se jedná o opravu nějaké chyby. Díky tomu je přechod na vyšší verze usnadněn tak, že pokud se modul povýší jen o vedlejší nebo opravnou verzi, tak by mělo být zaručeno, že bude s ostatním kódem fungovat i nadále.
Frameworky, moduly a pluginy v QE
Naše webové aplikace, obecně weby, jsou postaveny na redakčním systému Django CMS. Ten sám je nadstavbou webového frameworku Django. Django CMS je modulární a je tak možné do něj vkládat různé pluginy. Těch může být mnoho. Všechny tyto části jsou napsány v jazyce Python.
U konkrétního webu tak stačí nastavit konfiguraci definující, jaké pluginy u něj chceme používat a doplnit vlastní design. Protože však provozujeme webů více a konfigurace by se u nich neustále opakovala, tak jsme vše, co je u nich společné, vložili do projektu Django CMS QE. V něm je i definice použitých verzí.
Tím se dostáváme k samotné aktualizaci. Zní to jednoduše. Stačí, když v QE nastavíme nové verze, nejlépe ty vedlejší a opravné, a je vystaráno. Jenže ejhle! Věci kladou odpor. Nejenom v tom fyzickém, ale i ve virtuálním. Zatímco v tom fyzickém se vám hřebík ohne nebo lanko praskne, tak v tom virtuálním dojde například k tomu, že plugin, který potřebujete, přestal jeho autor vyvíjet (viz Deprecated – This project is no longer supported.). Tak hledáte jiný, protože psát si vlastní je neekonomické. Hledáte nejlépe takový, který někdo od původního autora převzal. Pokud jej nenajdete, tak vám nezbývá, než jej převzít sami. V našem případě se věc ještě komplikuje tím, že například u pluginu pro formulář potřebujeme, aby uměl ukládat i údaje předané od poskytovatele identity MojeID a ne jenom ty, co vyplní uživatel. Tím bylo dáno, že takový plugin převezmeme.
Python verze >= 3.9
V rámci aktualizace pluginů a frameworků jsme přistoupili i k aktualizaci verze Python kódu. Ten byl původně napsán pro verzi 2.x, ale byl ovšem optimalizován i na trojkovou verzi. Starý kód pro 2.x nemá smysl již udržovat, tak jsme jej odstranili. K tomu jsme použili nástroj pyugrade, konkrétně s parametrem –py39-plus. V setupu jsme v python_requires nastavili minimální verzi na 3.9. Šlo nám především o to, abychom mohli psát anotace novějším způsobem a neimportovat je z typing, ale použít typy vestavěné. Tedy místo from typing import List; … List[int] psát jen prosté list[int].
Pluginy ze skupiny Aldryn
Z opuštěných pluginů jsme potřebovali především Aldryn forms na vytváření formulářů, Aldryn News&Blog pro správu novinek a Aldryn search pro integraci vyhledávacího engine. Ty jsou ale navázané na další neudržované pluginy z kolekce Aldryn. Převzali jsme tedy všechny, které byly třeba. Název projektu jsme doplnili o předponu djangocms-, abychom jej pak mohli vydat odděleně od originálu na pypi.org. Verze balíků jsme odvodili od původních a hlavní (major) číslo jsme navýšili, protože tyto aktualizace nejsou zpětně kompatibilní už jen z důvodu použité novější verze Pythonu. Jméno modulu jsme ale ponechali, čímž nebylo nutné měnit jejich názvy v již existující databázi webu. Zde je jejich přehled:
- djangocms-aldryn-common
Knihovna s utilitami používanými v Aldryn projektech – stránkování, vytváření slug typů, práce s časem a daty. - djangocms-aldryn-search
Podpora pro integraci vyhledávacího engine Haystack. - djangocms-aldryn-translation-tools
Podpora pro definování datových modelů u vícejazyčných webů. - djangocms-aldryn-categories
Implementace stromové hierarchické struktury dat. - djangocms-aldryn-people
Implementace záznamů o osobách a jejich seskupování do skupin. Používá se na News&Blog. - djangocms-aldryn-newsblog
Implementace článků novinek nebo blogu. Lze je seskupovat do kategorií, vydávat k určitému datu, atd. - djangocms-aldryn-forms
Generování formuláře s různými typy polí. Ukládání postů nebo jejich posílání stanoveným uživatelům.
Frontend pro Bootstrap 5
V původní Django CMS verzi se používaly pluginy pro frontend Django CMS Bootstrap 4 s podporou Bootstrap 4. Při aktualizaci jsme přešli na pluginy Djnago CMS Frontend, které používají Bootstrap 5. Záznamy v databázi jsou pro obě verze dost rozdílné. Přesněji – novější verze ukládá mnohem více parametrů, než předchozí. Navíc jsme potřebovali převést i pluginy, které v původním frontendu na něco nestačily a tak jsme používali jiné. Například jsme měli samostatný plugin pro zobrazení obrázku ve formátu SVG, protože původní plugin na obrázky zvládal jen bitmapy.
Nástroj pro aktualizaci pluginů
Pro účel převodu dat v databázi pluginů jsme vytvořili nástroj DjangoCMS upgrade plugins. Frontend sice obsahuje kód pro migraci, ten jsme ale nevyužili. Změna v datech je natolik zásadní, že převod se provádí na vyexportovaných datech. Data se vyexportují do souboru ve formátu json django příkazem dumpdata . Na něm se provede konverze dat – vytvoří se nový json. Pak se smaže současná databáze. Po té se provede aktualizace modulů. Po aktualizaci se spustí migrace. Při ní se založí databáze nová a v ní se vytvoří všechny potřebné tabulky. Data se do databáze nahrají django příkazem loaddata. Při tom se musí dát pozor na správné Django site, aby se stránky nenačetly do jiného. Při migraci se totiž vloží nové s názvem example.com. To je nutné přepsat na konkrétní hodnotu, která je uvedena v json datech. V projektu je ještě utilitka djangocms_editor_permissions, která do skupiny oprávnění „Editor“ nahraje práva editace pluginů nového Frontendu. Podrobněji je celý proces popsán v README projektu.
Úprava kaskádových stylů
Po změně kódu na Bootstrap 5 bylo ještě nutné provést pár úprav v kaskádových stylech, neboť se změnily některé názvy tříd.
Integrace do CI
Pro nasazování na produkci používáme Gitlab Continuous Integration. Do konfigurace jsme vložili skript, který celý proces aktualizace provedl automaticky, včetně stopnutí webového serveru, vytvoření databázového dumpu, zahození databáze, vytvoření nové, nahrání nových dat a spuštění serveru. Skript si též ohlídal, aby aktualizace proběhla jen jednou a nebylo tak možné data rozbít při náhodném opakovaném spuštění. Vše jsme nejdříve pečlivě otestovali na testovacích prostředích a k tomu měli připravené zálohy, kdyby přece jen došlo k potížím. Samotná aktualizace na produkci tak proběhla hladce. Celý proces trval obvykle kolem dvaceti vteřin.
Vlastní pluginy
Díky aktualizaci modulů na nejnovější verze tak máme k dispozici opravený kód s novými vlastnostmi, na kterém můžeme dále vyvíjet další pluginy, které ke své práci potřebujeme. Jsou to například:
- djangocms-git-md-page
Modul zobrazuje stránku s markdownem z git repozitáře. - djangocms-mapycz-markers
Pluginy pro zobrazení Seznam.cz map se značkami. - djangocms-oidc
Plugin pro autentizaci uživatele pomocí OpenID Connect. - djangocms-oidc-form-fields
Plugin pro integraci dat předaných od poskytovatele identity s položkami formuláře. - djangocms-verify-vat-number
Django aplikace pro ověřování IČ a VAT společností.
Na první a na druhý pohled
Občas se udělá práce, která na první pohled není vidět. Například naše weby jsou po aktualizaci stále stejné. Na druhý pohled jsme ovšem zaktualizovali několik pluginů a projektů. A ty jsme publikovali. Též nástroj pro převod pluginů je volně k dispozici. Tím opensource komunitě tak trochu vracíme, co si od ní půjčujeme.