release: één commando dat lokaal voorbereidt → CI bewaakt → verspreidt (met monotone tag-guard) #1161
Labels
No labels
accepted
bug
declined
docs
duplicate
enhancement
good first issue
in-progress
needs-info
privacy
security
triage
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
LibreKAT/Ocideck#1161
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Aanleiding
Bij het snijden van een release viel op dat er een update-notificatie voor MASWE
klaarstond (
make catalogs-outdated/ de adviserende check inscripts/build_release.sh). Zo'n melding hoort niet vlak vóór een release te wordenontdekt en dan met de hand te worden weggewerkt — precies dat soort verrassingen wil je
uit het releaseproces halen. De basisregel is: staat er een hogere upstream-versie, dan
wordt die bijgewerkt, niet genoteerd (zie de werkwijze rond
make check-pins/make deps-outdated/make catalogs-outdated).Breder: het releaseproces bestaat nu uit een reeks losse, met de hand uitgevoerde
stappen in een vaste volgorde. Dat werkt, maar het is elke keer handwerk en dus elke
keer nét iets anders. De wens is: één commando dat het hele proces volgtijdelijk en
identiek uitvoert, zodat je alleen nog de uitkomst hoeft te bewaken en het ook zelf
vanaf de commandoregel kunt draaien.
Doel
Eén orkestrerend commando (bijv.
make release TAG=v0.2.1ofscripts/release.sh v0.2.1) dat het volledige proces volgtijdelijk afdraait:en het minisign-tekenen van het manifest;
Zelfde proces, elke keer. Menselijke rol = de uitkomst bewaken en de handmatige
vertrouwenspunten bevestigen (Developer-ID/notarisatie-wachtwoorden, minisign-wachtwoord).
Huidige situatie (uitgangspunt — dit bestaat al en moet worden geörkestreerd, niet herbouwd)
De release draait vandaag op één
v*-tag. De keten en het "waarom waar" staan indocs/BUILD.md§ Cutting a release. Kort in kaart:Vóór de tag, met de hand (de "lokale fase" die nu impliciet is):
make check-releasegroen opmain(=make check-fullals harde poort + adviserendeZAP/DAST-scan van de live host). Ook
make linux-gateen een blik op opensecurity/privacy-issues.make catalogs-outdated— de MASWE/WSTG/MASTG/CWE-check die de aanleiding was.de sbom-freshness):
pubspec.yaml→version:(bron van de waarheid; nu0.2.0+5),lib/services/export_metadata.dart→kOciDeckVersion(bewaakt doortest/version_consistency_test.dart),CHANGELOG.md→ de## [x.y.z] — unreleased-kop wordt versie + datum,make sbomopnieuw (root-componentversie; anders faalt de sbom-freshness-poort).omdat de Windows-build daar draait en als release-asset terugkomt.
Op de tag, in CI (
.forgejo/workflows/release.yml):web,deploy-web(opt-in via secrets),linux,macos(tekent + notariseert opmac-brennomet keychain-items),windows-ophalen(wacht tot 45 min op de GitHub-mirror-asset),publiceren(bundelt alles +SHA256SUMS),website-downloads(draaitscripts/bump-ocideck.sh <versie>in de website-repo +./publiceersite).Ná de tag, met de hand (lokaal, bewust off-runner):
make sign-release SHA256SUMS=…→ minisign detached signature overSHA256SUMS(privésleutel
~/.minisign/ocideck-release.key, mét wachtwoord — mag nooit eenrunner-secret worden),
SHA256SUMS.minisigaan de release hangen.make deploy-webals de deploy-secrets niet gezet zijn (nu het geval:gebruiker deployt zelf).
Relevante bouwstenen die al bestaan:
scripts/build_release.sh(make build-release) — bouwt web + macOS lokaal, mét deadviserende catalogs-check ervóór.
scripts/sign_release.sh(make sign-release) — minisign.scripts/notarize_macos.sh(make notarize-macos) — Developer-ID + notarisatie, lokaal.scripts/deploy_web.sh(make deploy-web) — geharde webbundel live (verify → atomic swap → verify).make refresh-catalogs— regenereert WSTG/MASTG/MASWE (bewust buitenmake check).Voorgestelde opzet
Eén commando met een tag-argument, dat drie fasen strikt volgtijdelijk draait en bij
elke faalstap stopt (
set -Eeuo pipefail-discipline). Voorstel voor de naam:make release TAG=v0.2.1(dun laagje overscripts/release.sh).Fase 1 — Lokaal voorbereiden (alles móét groen vóór de tag)
TAG(semver,v-prefix) en controleer dat hij strikt hogeris dan de laatst uitgebrachte versie (
git tag --sort=-creatordate/ hoogstev*).Nooit gelijk of lager. Weiger anders, zonder iets te wijzigen.
(
make catalogs-outdated,make deps-outdated,make check-pins) en werk bij watbijgewerkt moet worden (dit is de MASWE-aanleiding). Bij een gevonden hogere versie:
make refresh-catalogsen de versies inlib/services/reference_standards.dartspiegelen, resp. de deps/pins bijwerken — conform de "hogere versie = overal bijwerken"-regel.
Ontwerpvraag: volledig automatisch bijwerken, of stoppen-met-melding zodat de mens
beslist? (catalogs is bewust adviserend gehouden; zie ontwerpvragen onderaan.)
pubspec.yaml,kOciDeckVersion,CHANGELOG.md-kop (unreleased → versie + datum), enmake sbomopnieuw.make check-release(+make linux-gate). Faalt er iets,dan stopt het proces hier — er wordt niets gepusht.
make build-release, en op deze machinehet macOS-tekenen/notariseren (
make notarize-macos) — de release-signing gebeurtop deze machine. Verifieer het zegel (
codesign --verify --deep --strict; let op deschone-build-valkuil:
flutter cleanvóór een build die je installeert).geverifieerde
.appnaar/Applications(eerst de draaiende app afsluiten; toets oppgrep, niet op de exitstatus vanosascript quit). Alleen als het zegel groen is —een kapot zegel reist mee door
ditto.Fase 2 — Naar de CI-straat en bewaken
origin(forge) énmirror(GitHub). Pas hier — geentag zolang fase 1 niet volledig groen is.
(
web,linux,macos,windows-ophalen,publiceren, eventueeldeploy-webenwebsite-downloads). Gebruik de REST-route die op deze instance wél werkt:GET /releases?limit=N+ filter optag_namevoor de release, en deactions/runs/{id}/jobs→jobs/{jobId}/logs-route voor jobstatus/logs.Let op de bekende valkuilen:
GET /releases/tags/{tag}is onbetrouwbaar op dezeinstance (gebruik de lijst), en een al-gepushte
v*-tag mag je nooit verplaatsen(mislukte release → nieuwe patch-tag, niet hertaggen — anders degradeert de
mirror-Windows-release tot draft en blijft
windows-ophaleneeuwig wachten).Fase 3 — Verspreiden (pas ná groene CI)
SHA256SUMSophalen uit de gepubliceerde release,make sign-release,SHA256SUMS.minisigterughangen.website-downloads-job dit alop de tag (
scripts/bump-ocideck.sh <versie>+./publiceersite). De orkestrator moetdit bewaken en, bij overslaan/falen, de handmatige terugval draaien in de
website-repo. Zie ontwerpvraag over dubbeling met de bestaande job.
make deploy-web(zolang dedeploy-secrets niet gezet zijn deployt de gebruiker zelf — dit punt respecteren, niet
eigenmachtig overrulen).
Detaileisen (expliciet gevraagd)
zijn dan de vorige. Harde stop, geen wijzigingen, duidelijke melding.
privésleutels blijven lokaal, nooit als runner-secret).
/Applications).gefaalde stap moet veilig zijn).
Ontwerpvragen / aandachtspunten
CI-keten inclusief website-downloads en (opt-in) deploy-web. De gevraagde orkestrator
zet lokaal-eerst en doet verspreiding "pas na CI". Er zit dus overlap: doet de
orkestrator de website/deploy zélf, of bewaakt hij alleen de CI-jobs die dat al doen
en springt hij alleen bij als die overslaan/falen? Voorkeur lijkt: CI blijft de bron,
orkestrator bewaakt + vult de handmatige gaten (minisign, /Applications, eventuele
handmatige web-deploy). Vast te leggen vóór bouwen.
nieuwe upstream-versie is een afweging, geen defect, en het bijwerken verandert waar een
rapport naar verwijst). "Alles automatisch bumpen in het releaseproces" botst daarmee.
Waarschijnlijk juiste vorm: de orkestrator stopt met een duidelijke melding als er
iets bij te werken valt, doet het bijwerken als aparte, bevestigde stap, en gaat dan
opnieuw door de poort — niet stilzwijgend meebumpen tijdens een release.
interactief. Het "één commando"-ideaal mag die niet omzeilen; het commando moet er netjes
om vragen op het juiste moment (of duidelijk pauzeren).
scripts/release.shmet een dunnemake release TAG=…-wrapperligt voor de hand (consistent met
build_release.sh/sign_release.sh). De CI-kant(
release.yml) is grotendeels al af; de wens raakt vooral de lokale orkestratie +bewaking, niet zozeer nieuwe CI-jobs. Documenteren in
docs/BUILD.md./releases/tags/{tag},job-log-route) horen in het script afgevangen, niet elke keer opnieuw ontdekt.
Acceptatiecriteria
manier afgehandeld (bijwerken of gecontroleerd stoppen).
make check-releasegroenvóór de tag.
.appvervangt deversie in
/Applications.web live (of expliciet aan de gebruiker gelaten zolang dat de afspraak is).
docs/BUILD.md; eentool/-poort of testdekt de tag-guard (een bugfix/gedragsregel krijgt een toets).
Raakvlakken (bestanden)
scripts/build_release.sh,scripts/sign_release.sh,scripts/notarize_macos.sh,scripts/deploy_web.sh,Makefile(release-targets),.forgejo/workflows/release.yml,pubspec.yaml,lib/services/export_metadata.dart,CHANGELOG.md,sbom/,lib/services/reference_standards.dart(+make refresh-catalogs), de website-repo(
scripts/bump-ocideck.sh,./publiceersite),docs/BUILD.md.Opgepakt. Tak: feat/1161-release-orchestrator. Ik begin met de veilige, testbare kern uit de acceptatiecriteria: scripts/release.sh met de monotone tag-guard (semver + v-prefix, strikt hoger dan de vorige release-tag, harde stop zonder wijzigingen) en de gefaseerde skelet-structuur (fase 1 lokaal → 2 CI-bewaking → 3 verspreiding), plus een tool-poort die de tag-guard toetst. De live-CI-polling en distributie bouw ik gefaseerd erop; de interactieve vertrouwenspunten (notarisatie/minisign) blijven expliciet.
Eerste iteratie gemerged op main (PR #1205):
make release TAG=vX.Y.Z(scripts/release.sh) met de monotone tag-guard (vX.Y.Z zonder suffix, == v+pubspec-versie, nog niet bestaand, geldige één-as-bump via de al geteste make check-version-bump) + fase 1 (catalogs-outdated, check-release, build-release, notarize-macos). Guard geverifieerd tegen vijf foutgevallen, shellcheck schoon, docs/BUILD.md bij. Blijft OPEN: de onomkeerbare fase 2-3 (tag→mirror-push, CI-bewaking per minuut, minisign-manifest, LibreKAT-website, /Applications-vervanging) wordt bewust nog niet automatisch afgevuurd — het script drukt die als geordende vervolgstappen af. Die automatisering is de volgende iteratie, ná het bewijzen van de orkestrator.Iteratie 2 (de onbewaakte automatisering van fase 2-3) staat klaar op tak
feat/release-auto→ PR #1239. Menu voor het SemVer-niveau + één minisign-wachtwoord vooraan, daarna onbewaakt t/m tag-push, tekenen en deploy-web; verouderingsgate, ERR-trap-fail-safe,--dry-run/--print-versionentest/release_auto_version_test.dartvoor de guard. Sluit dit issue bij merge.