feat(ci): add automated workflows for releases and Docker builds
- Introduce auto-changelog and release workflow for version management - Add Docker workflows for nightly and release image builds - Include scripts for release ID retrieval and asset uploads - Document release process and best practices in `.gitea` directory
This commit is contained in:
50
.gitea/COMMIT_GPT.md
Normal file
50
.gitea/COMMIT_GPT.md
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# GPT Prompt
|
||||||
|
|
||||||
|
This is a prompt for a GPT model to generate a commit message based on the changes made in the code.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
# System
|
||||||
|
You are a highly precise Git commit message generator for changelog-driven repositories.
|
||||||
|
Your only task is to read the provided multi-file git diff and generate **one and only one** Conventional Commit message that strictly complies with the rules below.
|
||||||
|
|
||||||
|
# Language
|
||||||
|
You MUST write the entire message in English only.
|
||||||
|
|
||||||
|
# Commit Rules
|
||||||
|
|
||||||
|
1. Use exactly one of the following lowercase types:
|
||||||
|
feat, fix, docs, style, refactor, perf, test, chore, revert
|
||||||
|
|
||||||
|
2. Optionally add a `(<scope>)` after the type:
|
||||||
|
• Use a short lowercase identifier (e.g., directory, module, file group)
|
||||||
|
• Omit if no dominant scope exists
|
||||||
|
|
||||||
|
3. Follow this structure:
|
||||||
|
`type(scope): summary`
|
||||||
|
• The summary must be in imperative mood
|
||||||
|
• Max 72 characters
|
||||||
|
• No trailing period
|
||||||
|
• Must not contain emojis or casing deviations
|
||||||
|
|
||||||
|
4. If the body is needed:
|
||||||
|
• Add exactly one blank line after the subject
|
||||||
|
• Use `- ` bullet points
|
||||||
|
• Each line must be ≤ 72 characters
|
||||||
|
• Explain what was changed and (if shown in the diff) why
|
||||||
|
|
||||||
|
5. Do NOT include:
|
||||||
|
• `BREAKING CHANGE:` or any `!` markers
|
||||||
|
• PR numbers, issue IDs, author names, ticket references
|
||||||
|
• Markdown formatting, emojis, or code blocks
|
||||||
|
|
||||||
|
6. The following `chore(...)` patterns MUST be ignored and skipped from changelogs:
|
||||||
|
chore(changelog), chore(version), chore(release): prepare for, chore(deps), chore(pr), chore(pull)
|
||||||
|
|
||||||
|
7. If the commit body contains the word `security`, it will be classified as security-relevant (🛡️), regardless of type.
|
||||||
|
|
||||||
|
8. Output MUST consist only of the final commit message, as plain text.
|
||||||
|
No extra prose, no explanation, no formatting, no examples.
|
||||||
|
|
||||||
|
# Now, read the diff and generate the message.
|
||||||
|
Output only the valid Conventional Commit message, exactly.
|
||||||
|
```
|
198
.gitea/HOWTO_RELEASE.md
Normal file
198
.gitea/HOWTO_RELEASE.md
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
# 📦 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**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧾 Umgang mit `CHANGELOG.md` beim Mergen und Releasen
|
||||||
|
|
||||||
|
Wenn du automatisiert einen Changelog mit `git-cliff` erzeugst, ist `CHANGELOG.md` ein **generiertes Artefakt** – und kein handgepflegter Quelltext.
|
||||||
|
|
||||||
|
Beim Mergen von Feature-Branches in `main` kann es deshalb zu **unnötigen Konflikten** in dieser Datei kommen, obwohl der Inhalt später sowieso neu erzeugt wird.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧼 Umgang mit `CHANGELOG.md` in Feature-Branches
|
||||||
|
|
||||||
|
Wenn du mit **Feature-Branches** arbeitest, wird `CHANGELOG.md` dort oft automatisch erzeugt.
|
||||||
|
Das kann beim späteren Merge in `main` zu **unnötigen Merge-Konflikten** führen.
|
||||||
|
|
||||||
|
### ✅ Empfohlene Vorgehensweise
|
||||||
|
|
||||||
|
**Bevor du den Branch mit `main` zusammenführst** (Merge oder Cherry-Pick):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git rm CHANGELOG.md
|
||||||
|
git commit -m "chore(changelog): remove generated CHANGELOG.md before merge"
|
||||||
|
git push
|
||||||
|
```
|
||||||
|
|
||||||
|
Dadurch:
|
||||||
|
|
||||||
|
* verhinderst du Merge-Konflikte mit `CHANGELOG.md`
|
||||||
|
* wird die Datei bei Feature-Branches nicht mehr automatisch erzeugt
|
||||||
|
* bleibt deine Historie sauber und konfliktfrei
|
||||||
|
|
||||||
|
> 💡 Der Workflow erzeugt `CHANGELOG.md` automatisch **nur**, wenn:
|
||||||
|
>
|
||||||
|
> * die Datei schon vorhanden ist **oder**
|
||||||
|
> * der Branch `main` heißt
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧩 Merge-Konflikte verhindern mit `.gitattributes`
|
||||||
|
|
||||||
|
Damit Git bei Konflikten in `CHANGELOG.md` **automatisch deine Version bevorzugt**, kannst du folgende Zeile in die Datei `.gitattributes` aufnehmen:
|
||||||
|
|
||||||
|
```gitattributes
|
||||||
|
CHANGELOG.md merge=ours
|
||||||
|
```
|
||||||
|
|
||||||
|
Das bedeutet:
|
||||||
|
|
||||||
|
* Beim Merge wird die Version aus dem aktuellen Branch (`ours`) behalten
|
||||||
|
* Änderungen aus dem Ziel-Branch (`theirs`) werden verworfen
|
||||||
|
|
||||||
|
### ✅ So verwendest du es richtig:
|
||||||
|
|
||||||
|
1. **Füge die Regel in `main` hinzu**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "CHANGELOG.md merge=ours" >> .gitattributes
|
||||||
|
git add .gitattributes
|
||||||
|
git commit -m "chore(git): prevent merge conflicts in CHANGELOG.md"
|
||||||
|
git push origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Hole sie in deinen Feature-Branch**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git checkout feature/xyz
|
||||||
|
git rebase origin/main
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Ab sofort werden Konflikte in `CHANGELOG.md` automatisch aufgelöst** – lokal.
|
||||||
|
|
||||||
|
> ⚠️ Hinweis: Plattformen wie **Gitea, GitHub oder GitLab ignorieren `.gitattributes` beim Merge über die Web-Oberfläche**.
|
||||||
|
> Führe Merges daher **lokal** durch, wenn du Konflikte verhindern willst.
|
21
.gitea/scripts/get-release-id.sh
Executable file
21
.gitea/scripts/get-release-id.sh
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Eingaben
|
||||||
|
TAG="$1"
|
||||||
|
TOKEN="${ACTIONS_RUNTIME_TOKEN:-<fallback_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"
|
40
.gitea/scripts/upload-asset.sh
Executable file
40
.gitea/scripts/upload-asset.sh
Executable file
@@ -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:-<fallback_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"
|
59
.gitea/workflows/build-docker.yml
Normal file
59
.gitea/workflows/build-docker.yml
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
name: Build and upload Docker nightly image
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths-ignore:
|
||||||
|
- 'CHANGELOG.md'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push:
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Restore Docker cache
|
||||||
|
uses: https://git.0xmax42.io/actions/cache@v1
|
||||||
|
with:
|
||||||
|
key: buildx-general
|
||||||
|
paths: |
|
||||||
|
/tmp/.buildx-cache
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
id: buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
with:
|
||||||
|
driver: docker-container
|
||||||
|
install: true
|
||||||
|
|
||||||
|
- name: Login to Gitea Docker Registry
|
||||||
|
env:
|
||||||
|
REGISTRY: git.0xmax42.io
|
||||||
|
USERNAME: ${{ secrets.PACKAGE_USER }}
|
||||||
|
PASSWORD: ${{ secrets.PACKAGE_TOKEN }}
|
||||||
|
run: |
|
||||||
|
echo "$PASSWORD" | docker login $REGISTRY --username "$USERNAME" --password-stdin
|
||||||
|
|
||||||
|
- name: Build Docker Image
|
||||||
|
run: |
|
||||||
|
CREATED=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||||
|
VERSION_TAG=nightly-$(date +%Y%m%d)
|
||||||
|
docker buildx build \
|
||||||
|
--tag git.0xmax42.io/simdev/lt-auth-proxy:nightly \
|
||||||
|
--platform linux/amd64,linux/arm64 \
|
||||||
|
--label org.opencontainers.image.description="Lightweight LanguageTool Auth Proxy" \
|
||||||
|
--label org.opencontainers.image.documentation="https://git.0xmax42.io/maxp/lt-auth-proxy" \
|
||||||
|
--label org.opencontainers.image.authors="0xMax42 <mail@0xmax42.io>" \
|
||||||
|
--label org.opencontainers.image.created=$CREATED \
|
||||||
|
--label org.opencontainers.image.version=$VERSION_TAG \
|
||||||
|
--cache-from=type=local,src=/tmp/.buildx-cache \
|
||||||
|
--cache-to=type=local,dest=/tmp/.buildx-cache,mode=max \
|
||||||
|
--builder ${{ steps.buildx.outputs.name }} \
|
||||||
|
--push \
|
||||||
|
--progress=plain \
|
||||||
|
.
|
||||||
|
|
78
.gitea/workflows/build-release.yml
Normal file
78
.gitea/workflows/build-release.yml
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
# ========================
|
||||||
|
# 📦 Upload Assets Template
|
||||||
|
# ========================
|
||||||
|
# Dieser Workflow wird automatisch ausgelöst, wenn ein Release
|
||||||
|
# in Gitea veröffentlicht wurde (event: release.published).
|
||||||
|
#
|
||||||
|
# Er dient dem Zweck, Release-Artefakte (wie z. B. Binary-Dateien,
|
||||||
|
# Changelogs oder Build-Zips) nachträglich mit dem Release zu verknüpfen.
|
||||||
|
#
|
||||||
|
# Voraussetzung: Zwei Shell-Skripte liegen im Projekt:
|
||||||
|
# - .gitea/scripts/get-release-id.sh → ermittelt Release-ID per Tag
|
||||||
|
# - .gitea/scripts/upload-asset.sh → lädt Datei als Release-Asset hoch
|
||||||
|
#
|
||||||
|
# --------------------------------------
|
||||||
|
|
||||||
|
name: Build and upload Docker release image
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published] # Nur bei Veröffentlichung eines Releases (nicht bei Entwürfen)
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
upload-assets:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
env:
|
||||||
|
VERSION: ${{ github.event.release.tag_name }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# 📥 Checke den Stand des Repos aus, exakt auf dem veröffentlichten Tag
|
||||||
|
# So ist garantiert, dass die Artefakte dem Zustand des Releases entsprechen.
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.release.tag_name }} # z. B. "v1.2.3"
|
||||||
|
|
||||||
|
- name: Strip "v" from tag
|
||||||
|
id: version
|
||||||
|
run: |
|
||||||
|
echo "VERSION_STRIPPED=${VERSION#v}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Restore Docker cache
|
||||||
|
uses: https://git.0xmax42.io/actions/cache@v1
|
||||||
|
with:
|
||||||
|
key: buildx-general
|
||||||
|
paths: |
|
||||||
|
/tmp/.buildx-cache
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
id: buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
with:
|
||||||
|
driver: docker-container
|
||||||
|
install: true
|
||||||
|
|
||||||
|
- name: Login to Gitea Docker Registry
|
||||||
|
env:
|
||||||
|
REGISTRY: git.0xmax42.io
|
||||||
|
USERNAME: ${{ secrets.PACKAGE_USER }}
|
||||||
|
PASSWORD: ${{ secrets.PACKAGE_TOKEN }}
|
||||||
|
run: |
|
||||||
|
echo "$PASSWORD" | docker login $REGISTRY --username "$USERNAME" --password-stdin
|
||||||
|
|
||||||
|
- name: Build Docker Image
|
||||||
|
run: |
|
||||||
|
docker buildx build \
|
||||||
|
--tag git.0xmax42.io/simdev/lt-auth-proxy:${{ steps.version.outputs.VERSION_STRIPPED }} \
|
||||||
|
--tag git.0xmax42.io/simdev/lt-auth-proxy:latest \
|
||||||
|
--label org.opencontainers.image.description="Lightweight LanguageTool Auth Proxy" \
|
||||||
|
--label org.opencontainers.image.documentation="https://git.0xmax42.io/maxp/lt-auth-proxy" \
|
||||||
|
--label org.opencontainers.image.authors="0xMax42 <mail@0xmax42.io>" \
|
||||||
|
--label org.opencontainers.image.version=${VERSION} \
|
||||||
|
--platform linux/amd64,linux/arm64 \
|
||||||
|
--cache-from=type=local,src=/tmp/.buildx-cache \
|
||||||
|
--cache-to=type=local,dest=/tmp/.buildx-cache,mode=max \
|
||||||
|
--builder ${{ steps.buildx.outputs.name }} \
|
||||||
|
--push \
|
||||||
|
--progress=plain \
|
||||||
|
.
|
222
.gitea/workflows/release.yml
Normal file
222
.gitea/workflows/release.yml
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
name: Auto Changelog & Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- '**'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
detect-version-change:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
version_changed: ${{ steps.set.outputs.version_changed }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Check if VERSION file changed
|
||||||
|
if: github.ref == 'refs/heads/main'
|
||||||
|
run: |
|
||||||
|
echo "🔍 Vergleich mit github.event.before:"
|
||||||
|
echo "Before: ${{ github.event.before }}"
|
||||||
|
echo "After: ${{ github.sha }}"
|
||||||
|
|
||||||
|
echo "📄 Changed files between before and after:"
|
||||||
|
git diff --name-only ${{ github.event.before }} ${{ github.sha }} || echo "(diff failed)"
|
||||||
|
|
||||||
|
if git diff --name-only ${{ github.event.before }} ${{ github.sha }} | grep -q '^VERSION$'; then
|
||||||
|
echo "✅ VERSION file was changed"
|
||||||
|
echo "VERSION_CHANGED=true" >> $GITHUB_ENV
|
||||||
|
else
|
||||||
|
echo "ℹ️ VERSION file not changed"
|
||||||
|
echo "VERSION_CHANGED=false" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Set output (always)
|
||||||
|
id: set
|
||||||
|
run: |
|
||||||
|
echo "version_changed=${VERSION_CHANGED:-false}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
changelog-only:
|
||||||
|
needs: detect-version-change
|
||||||
|
if: github.ref != 'refs/heads/main' || needs.detect-version-change.outputs.version_changed == 'false'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Set Git Author
|
||||||
|
run: |
|
||||||
|
git config user.name "$CI_COMMIT_AUTHOR_NAME"
|
||||||
|
git config user.email "$CI_COMMIT_AUTHOR_EMAIL"
|
||||||
|
|
||||||
|
- name: Read CLIFF_VERSION from cliff.toml
|
||||||
|
id: cliff_version
|
||||||
|
run: |
|
||||||
|
echo "version=$(awk -F '=' '/^# CLIFF_VERSION=/ { gsub(/[" ]/, "", $2); print $2 }' cliff.toml)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Restore git-cliff cache
|
||||||
|
id: restore-cliff
|
||||||
|
uses: https://git.0xmax42.io/actions/cache@v1
|
||||||
|
with:
|
||||||
|
key: cargo-cliff-${{ steps.cliff_version.outputs.version }}
|
||||||
|
paths: |
|
||||||
|
/root/.cargo/bin
|
||||||
|
|
||||||
|
- name: Install git-cliff
|
||||||
|
if: steps.restore-cliff.outputs.cache-hit != 'true'
|
||||||
|
run: |
|
||||||
|
cargo install git-cliff --version "${{ steps.cliff_version.outputs.version }}" --features gitea
|
||||||
|
|
||||||
|
- name: Generate unreleased changelog (if file exists or on main)
|
||||||
|
run: |
|
||||||
|
if [[ -f CHANGELOG.md || "${GITHUB_REF##refs/heads/}" == "main" ]]; then
|
||||||
|
echo "Generating CHANGELOG.md..."
|
||||||
|
git-cliff -c cliff.toml -o CHANGELOG.md
|
||||||
|
else
|
||||||
|
echo "CHANGELOG.md does not exist and this is not 'main'. Skipping generation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Commit updated CHANGELOG
|
||||||
|
run: |
|
||||||
|
git add CHANGELOG.md
|
||||||
|
if git diff --cached --quiet; then
|
||||||
|
echo "No changes to commit"
|
||||||
|
else
|
||||||
|
git commit -m "chore(changelog): update unreleased changelog"
|
||||||
|
git push origin "${GITHUB_REF##refs/heads/}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
release:
|
||||||
|
needs: detect-version-change
|
||||||
|
if: needs.detect-version-change.outputs.version_changed == 'true' && github.ref == 'refs/heads/main'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Set Git Author
|
||||||
|
run: |
|
||||||
|
git config user.name "$CI_COMMIT_AUTHOR_NAME"
|
||||||
|
git config user.email "$CI_COMMIT_AUTHOR_EMAIL"
|
||||||
|
|
||||||
|
- name: Read VERSION
|
||||||
|
id: version
|
||||||
|
run: echo "value=$(cat VERSION)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Read CLIFF_VERSION from cliff.toml
|
||||||
|
id: cliff_version
|
||||||
|
run: |
|
||||||
|
echo "version=$(awk -F '=' '/^# CLIFF_VERSION=/ { gsub(/[" ]/, "", $2); print $2 }' cliff.toml)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Restore git-cliff cache
|
||||||
|
id: restore-cliff
|
||||||
|
uses: https://git.0xmax42.io/actions/cache@v1
|
||||||
|
with:
|
||||||
|
key: cargo-cliff-${{ steps.cliff_version.outputs.version }}
|
||||||
|
paths: |
|
||||||
|
/root/.cargo/bin
|
||||||
|
|
||||||
|
- name: Install git-cliff
|
||||||
|
if: steps.restore-cliff.outputs.cache-hit != 'true'
|
||||||
|
run: |
|
||||||
|
cargo install git-cliff --version "${{ steps.cliff_version.outputs.version }}" --features gitea
|
||||||
|
|
||||||
|
- name: Generate changelog for release and tag
|
||||||
|
id: generate-changelog
|
||||||
|
run: |
|
||||||
|
VERSION=${{ steps.version.outputs.value }}
|
||||||
|
git-cliff -c cliff.toml -t "v$VERSION" -o CHANGELOG.md
|
||||||
|
|
||||||
|
BODY=$(mktemp)
|
||||||
|
ESCAPED_VERSION=$(echo "$VERSION" | sed 's/\./\\./g')
|
||||||
|
|
||||||
|
awk -v ver="$ESCAPED_VERSION" '
|
||||||
|
$0 ~ "^## \\[" ver "\\]" {
|
||||||
|
print_flag=1
|
||||||
|
line = $0
|
||||||
|
sub(/^## /, "", line)
|
||||||
|
sub(/\\s*\\(.*\\)/, "", line) # entfernt z. B. "(...)" oder "(*)"
|
||||||
|
print line
|
||||||
|
next
|
||||||
|
}
|
||||||
|
$0 ~ "^## \\[" && $0 !~ "^## \\[" ver "\\]" {
|
||||||
|
print_flag=0
|
||||||
|
}
|
||||||
|
print_flag
|
||||||
|
' CHANGELOG.md > "$BODY"
|
||||||
|
|
||||||
|
echo "changelog_body_path=$BODY" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
|
||||||
|
- name: Commit updated CHANGELOG
|
||||||
|
run: |
|
||||||
|
git add CHANGELOG.md
|
||||||
|
if git diff --cached --quiet; then
|
||||||
|
echo "No changes to commit"
|
||||||
|
else
|
||||||
|
git commit -m "chore(changelog): update changelog for v${{ steps.version.outputs.value }}"
|
||||||
|
git push origin main
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Create Git tag (if not exists)
|
||||||
|
run: |
|
||||||
|
VERSION=${{ steps.version.outputs.value }}
|
||||||
|
if git rev-parse "v$VERSION" >/dev/null 2>&1; then
|
||||||
|
echo "Tag v$VERSION already exists, skipping tag creation."
|
||||||
|
else
|
||||||
|
git tag -a "v$VERSION" -F "${{ steps.generate-changelog.outputs.changelog_body_path }}" --cleanup=verbatim
|
||||||
|
git push origin "v$VERSION"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Create Gitea release
|
||||||
|
env:
|
||||||
|
RELEASE_PUBLISH_TOKEN: ${{ secrets.RELEASE_PUBLISH_TOKEN }}
|
||||||
|
run: |
|
||||||
|
VERSION=${{ steps.version.outputs.value }}
|
||||||
|
BODY_FILE="${{ steps.generate-changelog.outputs.changelog_body_path }}"
|
||||||
|
|
||||||
|
OWNER=$(echo "$GITHUB_REPOSITORY" | cut -d/ -f1)
|
||||||
|
REPO=$(echo "$GITHUB_REPOSITORY" | cut -d/ -f2)
|
||||||
|
|
||||||
|
# Token-Auswahl
|
||||||
|
TOKEN="${RELEASE_PUBLISH_TOKEN:-$ACTIONS_RUNTIME_TOKEN}"
|
||||||
|
|
||||||
|
if [[ -z "${RELEASE_PUBLISH_TOKEN:-}" ]]; then
|
||||||
|
echo "::warning title=Limited Release Propagation::"
|
||||||
|
echo "RELEASE_PUBLISH_TOKEN is not set. Using ACTIONS_RUNTIME_TOKEN instead."
|
||||||
|
echo "⚠️ Release events may not trigger other workflows if created with the runtime token."
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Prüfe, ob der Release schon existiert
|
||||||
|
if curl -sf "$GITHUB_API_URL/repos/$OWNER/$REPO/releases/tags/v$VERSION" \
|
||||||
|
-H "Authorization: token $TOKEN" > /dev/null; then
|
||||||
|
echo "🔁 Release for tag v$VERSION already exists, skipping."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "🚀 Creating Gitea release for v$VERSION"
|
||||||
|
|
||||||
|
# Release-Beschreibung vorbereiten
|
||||||
|
RELEASE_BODY=$(tail -n +2 "$BODY_FILE" | jq -Rs .)
|
||||||
|
|
||||||
|
curl -X POST "$GITHUB_API_URL/repos/$OWNER/$REPO/releases" \
|
||||||
|
-H "Authorization: token $TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d @- <<EOF
|
||||||
|
{
|
||||||
|
"tag_name": "v$VERSION",
|
||||||
|
"target_commitish": "main",
|
||||||
|
"name": "Release v$VERSION",
|
||||||
|
"body": $RELEASE_BODY,
|
||||||
|
"draft": false,
|
||||||
|
"prerelease": false
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "✅ Release for tag $VERSION created successfully."
|
Reference in New Issue
Block a user