09 · Fejlesztés
Hogyan jut el egy változtatás az éles rendszerig.
A munka számozott szállítási körökben készül, a jelenlegi sorozatban eddig 454 ilyen kör volt. Mindegyiket specifikáljuk, egyeztetjük, egészében megépítjük, igazoljuk és dokumentáljuk.
A platform leírása
A fejlesztői környezet
A fejlesztés két, szándékosan eltérő felszereltségű gépen folyik: egy teljes környezet a fejlesztői munkaállomáson, ahol az adatbázis is található, és egy eldobható felhőkonténer, amelyben a kód írása és tesztelése adatbázis nélkül történik.
A munkaállomás, phoenix-dev26.
- A megoldás a projekt gyökeréből Visual Studio-ban nyílik meg, és Kestrel alatt fut a projekt indítási profilján keresztül a https://localhost:51880 címen, egy egyszerű HTTP-kísérőporttal, Development környezetben.
- Az alkalmazás közvetlenül éri el az SQL Servert. A tulajdonos döntése szerint egy visszaállított fejlesztői másolat helyett az éles katalógusokat éri el, egy rendszerszintű környezeti változóban tárolt kapcsolati karakterláncon keresztül.
- A projektfájlban létezik egy user secrets azonosító, de a gyakorlatban nincs használatban; a konfiguráció a környezetből származik.
- Egy ismert csapda: a Razor-nézetek ugyanabba az assemblybe fordulnak, mint az oldalmodellek, így ha egy .cs fájlban végzett módosítás megjelenik, egy .cshtml fájlban végzett pedig nem, akkor az inkrementális build egy elavult nézetet használ újra. A megoldás az obj és bin mappák törlése, majd az újrafordítás.
- A sémaszkripteket a tulajdonos futtatja, kézzel, katalógusonként, a saját SQL-kliensével.
- Egyetlen parancs, a verify.cmd lefordítja a megoldást, négy próbát futtat, egy izolált példányt indít a saját portján, bejelentkezik, megnyitja mind a tizenhat kimutatásoldalt, és mindegyiket letölti PDF-ként. Mintamódja ugyanezt a futtatást tesztadatokon, adatbázis nélkül végzi el.
A felhőkonténerben egy .NET 8 SDK és egy build-könyvtárfa található, adatbázis egyáltalán nincs.
- A kapcsolati karakterlánc hiánya választja ki a mintamódot, amelyben a pénzügyi, a kimutatás-, a naptár-, az áfa- és a dokumentumtárolók tesztadat-implementációi válaszolnak minden lekérdezésre; az indító nem indul el, ha kapcsolati karakterlánc van jelen.
- A tesztadatok a cég saját dokumentumaiból és számadataiból készülnek, ezért egy teszt olyan számokra tud ellenőrzést végezni, amelyek már papíron is rendelkezésre állnak.
- Egy fej nélküli (headless) böngésző vezérli a futó alkalmazást a próbákhoz, képernyőképekhez és PDF-előállításhoz.
- Egy helyi helyettesítő pontos, előre rögzített válaszokkal felel az MI-végpont, valamint a piaci és árfolyam-adatforrások helyett, így az aritmetika modell bevonása nélkül igazolható.
Ellenőrzőkapuk. Minden körön harminchét ellenőrzőkapu-szkript és négy forráskód-átvizsgálás fut le.
- Egy részük statikus vizsgálat, amely a forráskód egy tulajdonságát ellenőrzi, például hogy egy CTE-n belül nincs névtelen projekció, vagy hogy egy konfigurációs fájlban nincs hosszú hexadecimális literál.
- Az értékesebbek a futó alkalmazást vezérlik. A projekt legdrágább tanulsága, hogy egy teszt, amely soha nem futtatja azt, amit a felhasználó futtat, nem láthat futásidejű hibát.
- Az ellenőrzőkapuk azt a szabályt ellenőrzik, amelyet egy kör rögzített, és nem a kiadott kifejezést, továbbá az ellenőrzés előtt eltávolítják a megjegyzéseket; ezt a javítást négy különböző alkalommal kellett elvégezni.
Átvitel a gépek között. A fájlok rögzített eljárás szerint, az asztali fájlhídon keresztül jutnak át:
- egy kör első szerkesztése előtt minden fájlról, amelyhez a kör hozzányúlhat, hash készül a munkaállomás lemezén;
- a commit előtt ugyanezeket a fájlokat újra előkészítjük és tartalom alapján összevetjük;
- a commit után mindkét oldalon ismét hash készül, és az összesített kivonatokat összevetjük.
A "kiadva" állítás mindig a munkaállomás lemezére vonatkozik, soha nem a build-konténerre.
A telepítés pontosan négy dolgot másol az éles webhelyre: a teljes statikus webmappát, az alkalmazás assemblyjét, annak szimbólumait és futtatható állományát. A konfigurációs fájlokat nem másoljuk, így az éles beállítások és titkok túlélik a kiadást. A másolás után az alkalmazáskészletet újraindítjuk, a közzététel előtti ellenőrzőlista pedig törli az állapotellenőrző tokent, és megerősíti, hogy a diagnosztikai osztály eltávolításra került.
Hogyan specifikáljuk, építjük és igazoljuk a munkát
A munka számozott szállítási körökben készül. A jelenlegi build a v31.454, ami jól mutatja, hogyan folyik a projekt: sok kicsi, teljes, ellenőrzött szállítás hosszú ágak helyett. Egy kör a tulajdonos kérésével kezdődik, döntések mátrixává alakul, amelyet a tulajdonos elfogad vagy módosít, majd egészében kerül kiadásra. Egy kört csak olyan munka miatt osztunk fel, amely még nem végezhető el, például egy megválaszolatlan diagnosztika vagy egy olyan döntés, amelyet csak a tulajdonos hozhat meg.
Minden kör írásos nyomot hagy.
- A projekt dokumentációjában egy körfeljegyzés rögzíti, mi változott és miért.
- Egy feltevés-nyilvántartás rögzít minden olyan mérlegelést, amely téves lehet: sorszámmal, a kódban az általa szabályozott sor mellett megjelölve, kockázati besorolással, és azzal az SQL-lel együtt, amely eldöntené.
- Ha egy döntés egy korábbit vonja vissza, a korábbi döntést törlés helyett áthúzzuk és megjegyzéssel látjuk el, így egy döntés története olvasható marad.
Négy állandó szabály határozza meg, mi végezhető el külön kérdés nélkül:
- A titkok kizárólag rendszerszintű környezeti változókban találhatók, soha nem olyan fájlban, amelyet a webszerver kiszolgálhat, és soha nem kerülnek bemásolásra egy beszélgetésbe.
- Új csomag nem vehető fel a projektbe, ezért a Web Push-implementáció, a PDF-író és a naptármeghívó-feldolgozó mind kézzel írt.
- Sémamódosítás, ideértve egy új indexet is, nem történik a tulajdonos jóváhagyása nélkül, és minden szkript védett és ismételten futtatható módon készül, és azt a tulajdonos futtatja, katalógusonként.
- A lekönyvelt számviteli adatokat soha nem módosítjuk egy megjelenítési probléma kompenzálására, és a historikus rekordokat soha nem javítjuk tömegesen egy javítás mellékhatásaként.
Az igazolás többrétegű.
- A buildnek hibamentesnek kell lennie.
- Az átvizsgálások a forráskódot az ismert hibaosztályokra ellenőrzik.
- Az ellenőrzőkapuk a szabályokat ellenőrzik.
- A próbák a futó alkalmazást vezérlik.
- A végső ellenőrzés mindig egy hash-összevetés a munkaállomás lemezével.
Ahol a sandbox valamit nem lát, azt a jelentés kimondja. A legvilágosabb példa az SQL: a build-konténerben egyetlen lekérdezés sem fut, így egy lekérdezés módosítását statikusan és átnézéssel igazoljuk, amíg az éles katalógusokon nem fut, és a körjelentés ezt rögzíti.