From 5c03cdfb031adeb6ee5d0de0889477d6d1efafef Mon Sep 17 00:00:00 2001 From: "Max P." Date: Thu, 8 May 2025 19:02:14 +0200 Subject: [PATCH] docs(gitea): add release automation guide and scripts - Document automated release process with versioning and changelog generation - Add scripts for retrieving release IDs and uploading assets to releases - Provide best practices and debugging tips for maintaining consistency --- .gitea/HOWTO_RELEASE.md | 124 +++++++++++++++++++++++++++++++ .gitea/scripts/get-release-id.sh | 21 ++++++ .gitea/scripts/upload-asset.sh | 40 ++++++++++ 3 files changed, 185 insertions(+) create mode 100644 .gitea/HOWTO_RELEASE.md create mode 100755 .gitea/scripts/get-release-id.sh create mode 100755 .gitea/scripts/upload-asset.sh diff --git a/.gitea/HOWTO_RELEASE.md b/.gitea/HOWTO_RELEASE.md new file mode 100644 index 0000000..cb05232 --- /dev/null +++ b/.gitea/HOWTO_RELEASE.md @@ -0,0 +1,124 @@ +# 📦 HOWTO: Release erstellen mit Auto-Changelog-Workflow + +Dieses Repository nutzt einen automatisierten CI/CD-Workflow zur **Versionsverwaltung, Changelog-Generierung und Release-Erstellung**. +Der gesamte Prozess ist deklarativ und läuft automatisch – ausgelöst durch Änderungen an einer Datei: `VERSION`. + +--- + +## 🧭 Was passiert automatisch? + +Sobald Änderungen in `main` landen, prüft der Workflow: + +- 🔍 **Hat sich die Datei `VERSION` geändert?** + - ❌ **Nein** → es wird nur das `CHANGELOG.md` aktualisiert (unreleased Abschnitt) + - ✅ **Ja** → es wird: + - ein vollständiger Changelog für diese Version erzeugt + - ein Git-Tag `vX.Y.Z` erstellt + - ein Release in Gitea veröffentlicht (inkl. Beschreibung aus dem Changelog) + +--- + +## ✅ Wie erzeuge ich ein Release? + +### 1. Erhöhe die Version in der Datei `VERSION` + +Beispiel: + +```txt +1.2.3 +``` + +> Diese Datei muss **als eigene Commit-Änderung** erfolgen – idealerweise als letzter Commit in einem PR. +> Die Commit-Nachricht sollte mit `chore(version)` beginnen, damit dieser nicht im Changelog auftaucht. + +--- + +### 2. Mergen in `main` + +Sobald `main` den Commit mit neuer `VERSION` enthält, wird automatisch: + +- das `CHANGELOG.md` regeneriert und committed +- der neue Git-Tag erstellt (`v1.2.3`) +- ein Gitea Release mit genau diesem Changelog erzeugt + +--- + +## 🛡️ Hinweis zu Tokens & Webhooks + +Damit das Release auch korrekt weitere Workflows auslösen kann (z. B. über `on: release`), ist **ein Personal Access Token notwendig**. + +### 🔐 Secret: `RELEASE_PUBLISH_TOKEN` + +> Lege ein Repository-Secret mit diesem Namen an. +> Es sollte ein **Gitea Personal Access Token** mit folgenden Berechtigungen sein: + +- `write:repo` +- `write:release` +- idealerweise: keine Ablaufzeit + +Wird dieser Token **nicht** gesetzt, fällt der Workflow auf `ACTIONS_RUNTIME_TOKEN` zurück, aber: +- Release wird trotzdem erstellt +- **⚠️ andere Workflows, die auf `release.published` reagieren, könnten nicht getriggert werden** + +--- + +## 🧪 Debugging-Tipps + +- Stelle sicher, dass `VERSION` exakt **eine gültige neue semver-Version** enthält +- Achte auf den Commit-Log: Changelog-Commits sind mit `chore(changelog):` gekennzeichnet +- Verwende nur `main` als Trigger-Zweig + +--- + +## 🧩 Erweiterung + +In `upload-assets.yml` kannst du beliebige Build-Artefakte automatisch an das Release anhängen, sobald es veröffentlicht ist. + +Dafür: +- liegt das Script `.gitea/scripts/get-release-id.sh` +- sowie `.gitea/scripts/upload-asset.sh` bereit + +Mehr dazu in der Datei: `.gitea/workflows/upload-assets.yml` + +--- + +## 🧘 Best Practice + +- Changelog-Generierung nie manuell ausführen +- Nur `VERSION` ändern, um ein neues Release auszulösen +- Auf `CHANGELOG.md` nie direkt committen +- Release-Daten niemals per Hand in Gitea pflegen + +📎 Alles wird versioniert, automatisiert und reproduzierbar erzeugt. + +--- + +## 🧠 Commit-Gruppierung & Changelog-Erzeugung + +Der Changelog wird auf Basis definierter **Commit-Gruppen** erzeugt. +Diese Regeln sind in `cliff.toml` unter `commit_parsers` konfiguriert. + +| Prefix / Muster | Gruppe | Beschreibung | +|-------------------------------|---------------------------|--------------------------------------------------| +| `feat:` | 🚀 Features | Neue Funktionalität | +| `fix:` | 🐛 Bug Fixes | Fehlerbehebungen | +| `doc:` | 📚 Documentation | Änderungen an Doku, Readmes etc. | +| `perf:` | ⚡ Performance | Leistungsverbesserungen | +| `refactor:` | 🚜 Refactor | Reorganisation ohne Verhaltensänderung | +| `style:` | 🎨 Styling | Formatierung, Whitespaces, Code-Style | +| `test:` | 🧪 Testing | Neue oder angepasste Tests | +| `ci:` oder `chore:` (ohne Spezifizierung) | ⚙️ Miscellaneous Tasks | CI-Änderungen, Aufgaben, Wartung etc. | +| `chore(changelog)`, `chore(version)`, `chore(release): prepare for`, `chore(deps...)`, `chore(pr)`, `chore(pull)` | *(ignoriert)* | Diese Commits werden im Changelog **ausgelassen** | +| Commit-Body enthält `security` | 🛡️ Security | Sicherheitsrelevante Änderungen | +| `revert:` | ◀️ Revert | Rückgängig gemachte Commits | +| alles andere | 💼 Other | Fallback für nicht erkannte Formate | + +### ✍️ Beispiel: + +```bash +git commit -m "feat: add login endpoint" +git commit -m "fix: prevent crash on null input" +git commit -m "chore(version): bump to 1.2.3" +``` + +> Nur die ersten beiden erscheinen im Changelog – der dritte wird **automatisch übersprungen**. diff --git a/.gitea/scripts/get-release-id.sh b/.gitea/scripts/get-release-id.sh new file mode 100755 index 0000000..1058ede --- /dev/null +++ b/.gitea/scripts/get-release-id.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Eingaben +TAG="$1" +TOKEN="${ACTIONS_RUNTIME_TOKEN:-}" +REPO="${GITHUB_REPOSITORY:-owner/example}" +API="${GITHUB_API_URL:-https://gitea.example.tld/api/v1}" + +OWNER=$(echo "$REPO" | cut -d/ -f1) +NAME=$(echo "$REPO" | cut -d/ -f2) + +RESPONSE=$(curl -sf \ + -H "Authorization: token $TOKEN" \ + "$API/repos/$OWNER/$NAME/releases/tags/$TAG") + +RELEASE_ID=$(echo "$RESPONSE" | jq -r '.id') +echo "Release-ID für $TAG ist: $RELEASE_ID" + +# Für GitHub Actions als Umgebungsvariable +echo "GT_RELEASE_ID=$RELEASE_ID" >> "$GITHUB_ENV" diff --git a/.gitea/scripts/upload-asset.sh b/.gitea/scripts/upload-asset.sh new file mode 100755 index 0000000..36f5e73 --- /dev/null +++ b/.gitea/scripts/upload-asset.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Eingabeparameter +FILE_PATH="$1" # z. B. ./dist/build.zip +CUSTOM_NAME="${2:-}" # optional: anderer Name unter dem das Asset gespeichert werden soll +RELEASE_ID="${GT_RELEASE_ID:-}" # aus Umgebung + +# Validierung +if [[ -z "$RELEASE_ID" ]]; then + echo "❌ RELEASE_ID ist nicht gesetzt. Abbruch." + exit 1 +fi + +if [[ ! -f "$FILE_PATH" ]]; then + echo "❌ Datei '$FILE_PATH' existiert nicht. Abbruch." + exit 1 +fi + +# Default-Konfiguration +TOKEN="${ACTIONS_RUNTIME_TOKEN:-}" +REPO="${GITHUB_REPOSITORY:-owner/example}" +API="${GITHUB_API_URL:-https://gitea.example.tld/api/v1}" + +# Owner/Repo auflösen +OWNER=$(echo "$REPO" | cut -d/ -f1) +NAME=$(echo "$REPO" | cut -d/ -f2) + +# Dateiname setzen +FILENAME="${CUSTOM_NAME:-$(basename "$FILE_PATH")}" + +echo "🔼 Uploading '$FILE_PATH' as '$FILENAME' to release ID $RELEASE_ID" + +# Upload +curl -sf -X POST \ + -H "Authorization: token $TOKEN" \ + -F "attachment=@$FILE_PATH" \ + "$API/repos/$OWNER/$NAME/releases/$RELEASE_ID/assets?name=$FILENAME" + +echo "✅ Upload abgeschlossen: $FILENAME"