bollwerk/.github/skills/publish/SKILL.md
2026-05-18 12:08:12 +02:00

170 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: publish
description: "APK publizieren: Version bumpen, APK bauen, auf VPS hochladen, Server-Version aktualisieren, QR-Code/Download-Seite verifizieren. Verwende diesen Skill immer wenn eine neue App-Version veröffentlicht werden soll auch wenn der User nur 'publish', 'release', 'veröffentlichen', 'neue Version', 'APK hochladen', 'APK deployen', 'Update bereitstellen' oder 'QR-Code aktualisieren' sagt. Trigger-Phrasen: 'publish', 'release', 'veröffentlichen', 'APK hochladen', 'neue Version', 'Update ausrollen', 'QR-Code'."
---
# Skill: Publish (APK auf VPS veröffentlichen)
Dieser Skill deckt den vollständigen Workflow ab, um eine neue App-Version auf dem VPS bereitzustellen, sodass:
1. Die **Homepage** (QR-Code + Download-Link) die aktuelle APK anbietet
2. Die **Update-Prüfung in der App** die neue Version erkennt und zum Download anbietet
---
## Architektur-Überblick
```
App (lokal) VPS (bollwerk.online)
───────────── ─────────────────────
app/build.gradle.kts /opt/bollwerk/
versionCode / versionName ├── docker-compose.yml (BOLLWERK_APP_VERSION_CODE/NAME)
├── data/app-latest.apk (statisch ausgeliefert)
./gradlew assembleDebug └── Server-Container (Ktor)
→ app-debug.apk ├── GET / → Homepage mit QR-Code
├── GET /api/version → JSON {versionCode, versionName, apkUrl}
scp → /opt/bollwerk/data/ └── GET /static/* → Dateien aus data/
```
### Wie die Update-Prüfung funktioniert
1. App ruft `GET {serverUrl}/api/version` auf → erhält `VersionInfo(versionCode, versionName, apkUrl)`
2. `CheckForUpdateUseCase` vergleicht `versionInfo.versionCode > BuildConfig.VERSION_CODE`
3. Falls neuer → zeigt Download-Button, lädt APK herunter, installiert via `ApkInstaller`
### Wie die Version gesetzt wird
- `POST /api/admin/version` mit `Authorization: Bearer <BOLLWERK_ADMIN_TOKEN>` Header
- Server speichert `versionCode` + `versionName` persistent in `data/version.json`
- `GET /api/version` liest aus `VersionStore` (Fallback auf Env-Vars, falls Datei fehlt)
- **Kein Container-Neustart nötig!**
### Wie die Homepage funktioniert
- `GET /` liefert HTML mit QR-Code (via qrcodejs) + Download-Link auf `/static/app-latest.apk`
- Version wird aus `VersionStore` gelesen (persistent in `data/version.json`)
---
## Publish-Workflow (Schritte)
### Schritt 1 Version bumpen
In `app/build.gradle.kts`:
- `versionCode` um 1 erhöhen
- `versionName` passend anpassen (z.B. "1.2" → "1.3")
### Schritt 2 Build & Test
```powershell
.\gradlew.bat assembleDebug test
```
Die APK liegt danach unter: `app/build/outputs/apk/debug/app-debug.apk`
### Schritt 3 APK auf VPS hochladen
```powershell
scp app/build/outputs/apk/debug/app-debug.apk root@195.246.231.210:/opt/bollwerk/data/app-latest.apk
```
**Voraussetzung:** SSH-Agent muss laufen und Key geladen sein (siehe vps-deploy Skill).
### Schritt 4 Server über neue Version benachrichtigen
Die Version wird per API-Call gesetzt (kein Container-Neustart nötig):
```powershell
$body = @{ versionCode = $CODE; versionName = $NAME } | ConvertTo-Json -Compress
Invoke-WebRequest -Uri "https://bollwerk.online/api/admin/version" `
-Method POST `
-Headers @{ "Authorization" = "Bearer $env:BOLLWERK_ADMIN_TOKEN"; "Content-Type" = "application/json" } `
-Body $body `
-UseBasicParsing
```
Alternativ mit curl:
```bash
curl -s -X POST https://bollwerk.online/api/admin/version \
-H "Authorization: Bearer $BOLLWERK_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"versionCode\": $CODE, \"versionName\": \"$NAME\"}"
```
**Voraussetzung:** Die Umgebungsvariable `BOLLWERK_ADMIN_TOKEN` muss gesetzt sein. Das Token muss mit dem `BOLLWERK_ADMIN_TOKEN` auf dem VPS übereinstimmen.
### Schritt 5 Verifizieren
```powershell
# Version-API prüfen
Invoke-WebRequest -Uri "https://bollwerk.online/api/version" -UseBasicParsing | Select-Object -ExpandProperty Content
# Homepage prüfen (QR-Code-Seite)
Invoke-WebRequest -Uri "https://bollwerk.online/" -UseBasicParsing | Select-Object StatusCode, StatusDescription
```
---
## Automatisiertes Skript
Das Skript `publish-apk.py` in diesem Skill-Ordner automatisiert den **gesamten** Release-Workflow (Version bumpen, bauen, hochladen, API-Call, verifizieren, committen):
```powershell
# Alles automatisch (versionCode +1, versionName bleibt):
python ".github/skills/publish/publish-apk.py"
# Mit neuem versionName:
python ".github/skills/publish/publish-apk.py" --version-name "2.0"
# Nur hochladen (APK bereits gebaut, kein Push):
python ".github/skills/publish/publish-apk.py" --skip-build --skip-push
```
**Voraussetzungen:**
- SSH-Agent muss laufen (für APK-Upload per SCP)
- `$env:BOLLWERK_ADMIN_TOKEN` muss gesetzt sein (für Version-Notify API-Call)
**Parameter:**
| Parameter | Pflicht | Default | Beschreibung |
| ---------------- | ------- | ----------- | ------------------------------------------------- |
| `--version-name` | nein | aktueller | Neuer versionName (z.B. "2.0"); sonst unverändert |
| `--version-code` | nein | aktuell + 1 | Expliziter versionCode; sonst automatisch +1 |
| `--apk-path` | nein | debug-APK | Pfad zur APK-Datei |
| `--skip-build` | nein | false | Gradle-Build überspringen |
| `--skip-verify` | nein | false | Verifizierung nach dem Deploy überspringen |
| `--skip-push` | nein | false | Git-Push überspringen (nur lokaler Commit) |
---
## Wichtige Dateien
| Datei | Beschreibung |
| -------------------------------------------------------- | ------------------------------------------ |
| `app/build.gradle.kts` (L18-19) | `versionCode` / `versionName` |
| `server/src/main/resources/application.conf` | Server-Version-Defaults + Env-Var-Override |
| `server/src/main/kotlin/.../store/VersionStore.kt` | Persistente Version in `data/version.json` |
| `server/src/main/kotlin/.../routes/VersionRoutes.kt` | Homepage + `/api/version` + POST-Endpoint |
| `server/src/main/kotlin/.../plugins/Routing.kt` | `staticFiles("/static", File("data"))` |
| `app/src/main/java/.../usecase/CheckForUpdateUseCase.kt` | Update-Prüfung in der App |
| `app/src/main/java/.../ui/update/UpdateViewModel.kt` | Update-UI + Download-Logik |
---
## Environment-Variablen (VPS)
| Variable | Pflicht | Beschreibung |
| --------------------------- | ------- | ------------------------------------------------------------ |
| `BOLLWERK_ADMIN_TOKEN` | ja | Bearer-Token für `POST /api/admin/version` (min. 32 Zeichen) |
| `BOLLWERK_APP_VERSION_CODE` | nein | Fallback-VersionCode (nur wenn `data/version.json` fehlt) |
| `BOLLWERK_APP_VERSION_NAME` | nein | Fallback-VersionName (nur wenn `data/version.json` fehlt) |
---
## Bekannte Lücken / TODOs
- **Kein Release-Build:** Aktuell wird `assembleDebug` verwendet. Für Produktion → Signing-Config + `assembleRelease` einrichten.
- **Env-Vars optional:** `BOLLWERK_APP_VERSION_CODE` / `BOLLWERK_APP_VERSION_NAME` können aus der docker-compose.yml entfernt werden, sobald `data/version.json` initial gesetzt ist.