
Väljalaske viimine CI-sse, kaks korda
GeekBye v1.8.4 viis väljalaske-buildid CI-sse macOS-i ja Windowsi jaoks. Mida muudatuste logi ei ütle, on see, et proovisime seda juba korra varem, kustutasime kuu aega hiljem runnerite kulude pärast ja saime selle püsima alles teisel korral — sest selleks ajaks töötas väljalaskeskript juba käsitsi.
v1.8.4 muudatuste logis on rida, mis kõlab nagu puhas majapidamistöö: "Väljalaske-buildid tulevad nüüd CI-st nii macOS-i kui ka Windowsi jaoks." See loeb nagu asi, mis juhtub korra, puhtalt, ja millele enam kunagi ei mõtle. Nii ei olnud. Meeskond oli väljalasked juba korra CI-sse pannud — ja selle välja kiskunud. See väljalase on teine katse, ja põhjus, miks see püsis, on tegelik insenertöö-õppetund, nii et räägime selle järjekorras ära.
Esimene katse ja miks see suri
Veel 2025. aasta oktoobris eksisteeris release.yml. Selle käivitas tag push — lükka v*.*.* tag ja macOS-i runner käivitus, buildis ja avaldas. See tegi oma allkirjastamise seadistuse käsitsi: samm, mis dekodeeris allkirjastamissertifikaadi, lõi ja lukustas lahti ajutise keychaini, importis sertifikaadi, et codesign selle üles leiaks, ja vastav koristussamm lõpus. See töötas. See oli ka ainult macOS — Windowsi väljalasked polnud CI-s üldse.
- novembril see kustutati. Commiti sõnum on ebatavaliselt aus selle kohta, miks: "remove GitHub Actions release workflow to conserve minutes / macOS runners cost 10x multiplier (100 billed minutes per 10-minute release). Releases will be done locally." See on kogu esimese katse lugu ühes lauses. GitHub arvestab macOS-i runneri aega kümme korda kõrgema määraga kui Linuxi oma, ja tag-käivitatud väljalase tähendab, et iga üksik tag — kaasa arvatud ühekordsed, ümbertag'imised, need "oih, unustasin versiooni tõsta" omad — kulutab vaikselt sada arvestatud minutit. Automaatika, mida sa ei kontrolli, on automaatika, mis kulutab raha ilma sinu teadmata. Nii läksid väljalasked järgmiseks kolmeks ja pooleks kuuks tagasi arendaja Macile.
Kus rasked probleemid tegelikult lahendati
Siin on osa, mis paneb teise katse tööle, ja see juhtus täielikult väljaspool CI-d. Nende kolme ja poole kuu jooksul kohalikke väljalaskeid neelas scripts/release.js — lihtne Node'i skript, mille arendaja käsitsi käivitab — iga pakendamisprobleemi, mis rakendusel oli, ühe paranduse kaupa:
- White-label taastamine. See on white-label koodibaas, mis buildib ühest allikast nii GeekBye kui ka Pavleuri, mis tähendab, et väljalase vahetab
package.jsonväljad ja ikoonivarad sihtprodukti jaoks. Kaks parandust õpetasid skripti kõik pärast tagasi panema, nii et Pavleuri buildimine ei jätnud su git-puud Pavleuri identiteediga mustaks. - Kahe arhitektuuri Windows. Parandus, et buildida mõlemad x64 ja arm64 Windowsi installerid ühe asemel.
- Allkirjastamata Windowsi möödahiilimine. Uuem electron-builder ignoreeris konfiguratsioonilippu, mis pidi Windowsi allkirjastamise välja lülitama, nii et skript õppis allkirjastamata buildi peale suruma, seades selle asemel keskkonnas
CSC_IDENTITY_AUTO_DISCOVERY=false— konarus, mille leiad ainult sellele otsa komistades. - Notariseerimise automaatne tuvastus. Skript õppis oma keskkonda vaatama ja otsustama: allkirjastamise volitused olemas? Allkirjasta. Apple'i notariseerimise volitused samuti olemas? Notariseeri. Kumbki mitte? Buildi allkirjastamata. Ühtegi lippu pole vaja meeles pidada; saladuste olemasolu on konfiguratsioon.
Miski sellest pole hiilgav. Kõik see on selline asi, mis, kui see üllatab sind CI-runneri sees, maksab sulle tunni push-oota-kukku-loe-logisid iga katse kohta — 10x arvestusega. Lahendatud Macil, mille ees sa istud, maksab igaüks neist ühe minuti.
Teine katse: kuuskümmend kuus rida
Kui CI naasis v1.8.4-s, oli workflow 66 rida, ja selle määrav omadus on see, kui vähe see teeb. Commit kirjeldab seda otsekoheselt: "Manual workflow_dispatch trigger that builds both platforms in parallel, reusing existing release.js script. macOS builds are signed and notarized, Windows builds are unsigned." Iga selles peituv disainiotsus tuleneb sellest, mida esimene katse valusalt õpetas:
workflow_dispatch, mitte tag-käivitatud. Väljalaske alustad, klõpsates "Run workflow." Inimene väravab iga tasulise macOS-i minuti. Kuluprobleem, mis esimese versiooni tappis, lahendatakse lihtsalt käivitajat mitte automatiseerides — ainsa koha, kus automaatika oli aktiivselt kahjulik.productsisend. Dispatch võtab rippmenüü —geekbyevõipavleur— nii et sama workflow tarnib kummagi brändi. White-label õmblus ulatub kogu tee välja kuni väljalaskenupuni.- Kaks paralleelset jobi.
build-macmacos-latest-il,build-winwindows-latest-il, joostes samal ajal. Windows CI-s on siin tõesti uus; oktoobri workflow ei buildinud seda kunagi. - Ei mingit allkirjastamisloogikat YAML-is. See ongi kogu mõte. Pole keychaini žongleerimist, pole sertifikaadi impordisammu, pole koristust. Maci job käivitab
node scripts/release.js <product> --publishja Windowsi job käivitab sama--no-sign-iga. Kõik, mida esimene workflow YAML-is käsitsi tegi, elab nüüd skriptis, mis juba töötab. Workflow on orkestraator, mitte teostus.
Kaks platvormi tahavad vastandlikke asju, ja jobid peegeldavad seda ausalt. macOS buildib karastatud runtime'i all, allkirjastatud ja notariseeritud electron-builderi sisseehitatud raja kaudu (@electron/notarize), volitustega, mis on antud repositooriumi saladustest ja mille skript automaatselt tuvastab. Windows buildib allkirjastamata NSIS-installerid x64 ja arm64 jaoks. Üks workflow, kaks jobi, kaks täiesti erinevat arusaama sõnast "valmis."
Tõestus on selles, mida ei juhtunud
Nii sa tead, et järjestus oli õige: pärast kahte sama päeva näpistust, mis andsid jooksudele nimed ja parandasid ühe token-saladuse nime, ei puudutatud release.yml-i enam neli kuud. Ei ühtki allkirjastamise-tõrke kiirparandust. Ei ühtki notariseerimise-tagasilükkamise sebimist. Ei ühtki "natiivbinaar puudub runneril" paanikat. Koodi allkirjastamise ja notariseerimise torustiku jaoks — CI žanri jaoks, mis on kõige kurikuulsam rabelemise poolest — on nelja kuu vaikus peaaegu ennekuulmatu.
Oli vaikne, sest müra oli juba kusagil odavamas kohas juhtunud. Võitlused, mis tavaliselt mängivad välja CI-logide vahekaardil, 10x arvestusega, ühe force-push'i kaupa, olid kohaliku ajastu jooksul välja mängitud arendajate Macides. CI ei pidanud olema koht, kus pakendamine siluti, sest pakendamine oli juba siledaks silutud. See on tees ühes reas: vii build oma Macist minema alles siis, kui su Mac on lakanud sind üllatamast.
Ainus sidestus, mis võib veel valu teha
See pole päris ilma nõrga kohata, ja seda tasub nimetada, sest see on peen. Swift-binaarid, millest macOS-i rakendus sõltub — OCR, ekraanihõive, transkribeerijad — on git'i kommitud. Aga väljalase ei tarni kommitud koopiaid; build kompileerib need runneril uuesti. Ja check-swift-version.js värav laseb kogu väljalaske kõvasti läbi kukkuda, kui kompilaator pole kinnitatud versioon. Sel väljalaskel oli see kinnitus Swift 6.2.x, ja miski workflow's ei installi seda — job lihtsalt usaldab, et macos-latest-i vaike-Swift klapib. Päeval, mil GitHub tõstab oma runneri image'i kinnitusest ette, väljalase peatub, mitte sellepärast, et rakendusega oleks midagi valesti, vaid sellepärast, et torustik on vaikselt seotud masina image'iga, mida ta ei kontrolli. See on ainus teostusdetail, mida see õhuke workflow ei lükanud alla millessegi, mis talle endale kuulub.
Väljalaske teine pool: väiksemad koormused
Väljalase kandis üht mitteseotud funktsiooni, mida tasub mainida, sest see on puhas näide latentsusparandusest ärajätmise teel. Assist Me toiming saatis backendile igal päringul rohkem konteksti, kui vaja oli. Üks commit kärpis kahte asja: kaasa saadetud transkriptsiooniajalugu langes viimaselt 30 kirjelt viimasele 15-le, ja kasutaja profiili kontekstifailid — mis süstitakse süsteemipromptisse igal kutsel — said kõva ülempiiri 4,000 märgi juures koos kärpemärgiga. Vähem serialiseerida, vähem üles laadida, vähem mudelil lugeda enne vastamise alustamist, mis ongi mõõdik, mida commit optimeerib: time-to-first-token. Aususe huvides: commit väidab kiirendust, aga ei mõõda seda — ajaloos pole enne/pärast numbrit, nii et suhtu sellesse pigem kui hästi põhjendatud kärpesse, mitte kui võrdlustestiga tõestatud võitu.
Kolm asja, mida see väljalase meile õpetas
- CI on õhuke kate skripti peal, mis juba töötab. 66-realisel workflow'l pole oma allkirjastamisloogikat; see kutsub skripti, mille kolm kuud kohalikke väljalaskeid olid juba silunud. Pane mehhanism asja sisse, mida saad käsitsi käivitada, ja lase CI-l lihtsalt otsustada, millal seda käivitada.
- Automatiseeri töö, mitte tingimata käivitaja. Esimene katse suri, sest tag-käivitatud väljalasked kulutasid automaatselt 10x-arvestatud runneri minuteid. Käsitsi
workflow_dispatchsäilitab automaatika ja eemaldab osa, mis raha maksis — vahel ongi inimene ahelas see funktsioon. - Silu seal, kus iteratsioon on odav. Iga pakendamisvõitlus, mis lahendati arendaja Macil, on võitlus, mis ei juhtu kunagi CI-logide vahekaardil kümnekordse hinnaga. Vii Macist minema viimasena, mitte esimesena.
Eelmise peatüki jaoks v1 loos — kolmekümne keele tarnimine ilma turvavõrguta (v1.8.3); ja kogu kaare jaoks tarkvara täiuslikkuseni tarnimise anatoomia.