Versionen und Veröffentlichung
Diese Seite richtet sich an die Maintainer. Betreiber:innen finden das Einspielen einer Version unter Deployment.
Versionsnummern
Der Nusszopf folgt Semantic Versioning: MAJOR.MINOR.PATCH.
- MAJOR: Betreiber:innen müssen mehr tun als „Images laden, starten“ (ein Handgriff, ein entfernter Schalter, eine nicht umkehrbare Datenmigration).
- MINOR: neue Funktionen, abwärtskompatibel.
- PATCH: Fehler- und Sicherheitskorrekturen.
Tags haben kein v davor: 1.2.0, nicht v1.2.0. Vorab-Versionen heißen X.Y.Z-rc.N; sie werden als GitHub-Pre-Release
veröffentlicht und bewegen latest nicht. Die erste stabile Version ist 1.0.0.
Die Version steckt im Git-Tag und sonst nirgends. Der Build bäckt sie als NUSSZOPF_VERSION in die Images und in ein Label
(org.opencontainers.image.version). nusszopf:health, php artisan about und /health (mit Token) zeigen sie ohne
Datenbankzugriff. Ein aus einer Arbeitskopie gebautes Image meldet dev. Es gibt keine handgepflegte Versionsdatei.
Regeln, damit Upgrades gelingen
- Migrationen sind innerhalb einer Hauptversion additiv und vorwärts gerichtet. Nur ein MAJOR darf eine Migration verlangen, die Betreiber:innen etwas tun lässt.
- Image-Tags sind unveränderlich: Ein Tag wird nie erneut unter demselben Namen hochgeladen.
- Ein Handgriff über die üblichen drei Befehle hinaus gehört als Migration required: in den Changelog. Das sind zum Beispiel
eine neue Pflichteinstellung ohne Standardwert, ein geänderter Standard, den eine bestehende
.envnicht übernimmt, ein anderer Pin von PostgreSQL, Redis oder Meilisearch, ein nötigersearch:reindexoder eine Version, deren Vorgängerin auf dem neuen Schema nicht läuft. Ein geändertes Meilisearch-Pin bedeutet, das Volumemeilisearch-datazu entfernen und neu zu indexieren; das ist aus der Dokumentation von Meilisearch abgeleitet, nicht erprobt. - Ein bloß neue, optionale Einstellung oder eine geänderte Compose-Datei braucht keinen Marker:
install.sh --upgradebringt die Datei mit und listet fehlende Einstellungen selbst auf. - Ein Breaking:-Eintrag nennt, was sich ändert, wen es betrifft, die nötigen Befehle zum Kopieren, Folgen für Datenbank und Konfiguration und die Besonderheiten des Rollbacks.
Der Changelog
CHANGELOG.md folgt Keep a Changelog: Added, Changed, Fixed, Security, Deprecated,
Removed, dazu oben ein Abschnitt Unreleased. Beim Release wird er zum Abschnitt mit Version und Datum, und ein neuer, leerer
Unreleased kommt darüber. Der Abschnitt einer Version ist zugleich der Text der GitHub-Release-Notes: Der Workflow zieht ihn heraus
und weigert sich zu veröffentlichen, wenn er fehlt.
Wer den Changelog pflegt (Autor:in des Pull Requests oder Maintainer beim Release), ist noch offen; bisher tun es die Maintainer.
Eine Version veröffentlichen
-
Changelog vorbereiten. Verschiebe
Unreleasedunter## [X.Y.Z] - Datum. -
Prüfen (Details in Tests und Qualität): das Upgrade von der letzten Version, Backup mit Restore und Rollback, Suchindex-Wiederherstellung, Queue und Scheduler, und mit einem echten Postfach der Mailversand.
-
Die CI des genauen Commits ansehen. Ein CI-Lauf, der nie gestartet ist oder rot wurde, ist im Terminal unsichtbar. Der Release-Workflow führt dieselbe CI zwar noch einmal als Schranke aus, aber bemerke es vorher.
-
Mergen und taggen:
Lokale Entwicklung git tag -a X.Y.Z -m X.Y.Z && git push origin X.Y.Z
Der Tag startet .github/workflows/release.yml. Er lässt die ganze CI als Schranke laufen (Pint, Larastan, Pest, Playwright auf drei
Browsern, Produktions-Stack). Er baut beide Images für linux/amd64 und linux/arm64 (rund 40 Minuten) und lädt sie nach
ghcr.io/lchristmann/nusszopf-php-fpm und …/nusszopf-web, getaggt mit X.Y.Z und latest (Vorab-Versionen nur mit der Version).
Zuletzt legt er das GitHub-Release mit den Notes aus dem Changelog an und hängt docker-compose.yaml, env.production.example und
install.sh an.
Die Vorlage heißt als Anhang env.production.example ohne Punkt, denn GitHub benennt Dateien mit führendem Punkt um. install.sh
speichert sie auf dem Server unter dem Namen mit Punkt. tests/Feature/Release/ReleaseAssetsTest.php hält die Downloads des
Installers und die Anhänge des Workflows im Gleichschritt.
Nach dem Tag
Prüfe, dass sich beide Pakete ohne Anmeldung ziehen lassen; von einem Rechner, der nicht bei GHCR angemeldet ist:
docker manifest inspect ghcr.io/lchristmann/nusszopf-web:X.Y.ZDann installiert sh scripts/release-check.sh X.Y.Z die veröffentlichte Version so, wie es Betreiber:innen tun. Ein Tag
verify/X.Y.Z, der auf denselben Commit zeigt, startet release-verify.yml, das die Drills auf den gezogenen Images
nativ auf amd64 und arm64 wiederholt:
git tag verify/X.Y.Z X.Y.Z^{} && git push origin verify/X.Y.ZWas noch offen ist
Zum Zeitpunkt von 1.0.0 stehen diese Prüfungen aus und sind unter docs/release/parity/
vermerkt: eine Installation durch eine zweite Person auf einem echten Server mit ACME-Zertifikat, die Darstellung der Mails in
Gmail, Outlook und Apple Mail und ein Durchgang auf echten Telefonen.
Die englischen Bestandsseiten zum Thema liegen unter docs/release/.