Publish: APK-Deploy ohne Server-Neustart (Version-Notify-Endpoint) #100

Closed
opened 2026-05-17 19:14:41 +00:00 by jreinemann-euris · 1 comment
jreinemann-euris commented 2026-05-17 19:14:41 +00:00 (Migrated from github.com)

Ziel

Den App-Deployment-Prozess entkoppeln: Das APK wird weiterhin per SCP auf den Server kopiert, aber der Server muss nicht neu gestartet werden. Stattdessen wird der Server über einen leichtgewichtigen API-Endpunkt benachrichtigt, der die Versionsinformation persistent speichert.

Problem

Der aktuelle Publish-Workflow (Skill: publish) erfordert in Schritt 4:

  1. SSH-Verbindung zum VPS
  2. sed-Bearbeitung der docker-compose.yml
  3. Implizit: Container-Neustart, um neue Env-Vars zu übernehmen

Das ist zu schwer für ein reines Versionsupdate. Ein neues APK sollte keinen Container-Neustart erfordern.

Gewünschtes Verhalten

Neuer Publish-Workflow

Schritt Bisher Neu
3 – APK hochladen scp app-debug.apk root@<vps>:/opt/krisenvorrat/data/app-latest.apk unverändert
4 – Version setzen SSH + sed docker-compose.yml + Container-Neustart curl POST /api/admin/version

Server-Seite

  • Neuer Endpoint: POST /api/admin/version (gesichert durch Admin-Token)
  • Server speichert versionCode und versionName persistent in data/version.json
  • GET /api/version liest aus dieser Datei (Fallback auf Env-Vars, falls Datei fehlt)
  • Env-Vars BOLLWERK_APP_VERSION_CODE / BOLLWERK_APP_VERSION_NAME können mittelfristig entfallen

Publish-Skill

  • Schritt 4 wird durch curl-Call ersetzt (kein SSH-Zugriff mehr nötig)
  • Der Admin-Token kommt aus einer lokalen .env-Datei / Skript-Variable

Abgrenzung

  • Nur der Publish-Prozess ändert sich – kein neues Feature in der App
  • Server-Authentifizierung des neuen Endpunkts muss gesichert sein (kein offener Write-Endpoint)
  • Der bestehende GET /api/version-Endpunkt bleibt kompatibel (App-seitig keine Änderung nötig)

Implementierungsplan

⚠️ Bitte den Plan bestätigen, bevor die Implementierung beginnt.

Phase 1 – Server: VersionStore + Endpunkte

  1. VersionStore – Neue Klasse, die data/version.json liest und schreibt (versionCode: Int, versionName: String)
  2. GET /api/version – liest aus VersionStore (mit Fallback auf Env-Vars, falls Datei nicht vorhanden)
  3. POST /api/admin/version – schreibt in VersionStore, gesichert durch Authorization: Bearer <BOLLWERK_ADMIN_TOKEN> Header

Phase 2 – Publish-Skill aktualisieren

  1. .github/skills/publish/SKILL.md – Schritt 4 durch curl-Call dokumentieren:
    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\"}"
    
  2. Publish-Skript (PowerShell) – curl-Call implementieren, Token aus Umgebungsvariable lesen

Phase 3 – VPS Cleanup (optional, separates Ticket)

  1. Env-Vars BOLLWERK_APP_VERSION_CODE / BOLLWERK_APP_VERSION_NAME aus docker-compose.yml entfernen

→ Bitte Plan bestätigen, dann startet die Implementierung.

## Ziel Den App-Deployment-Prozess entkoppeln: Das APK wird weiterhin per SCP auf den Server kopiert, aber der Server muss **nicht neu gestartet** werden. Stattdessen wird der Server über einen leichtgewichtigen API-Endpunkt benachrichtigt, der die Versionsinformation persistent speichert. ## Problem Der aktuelle Publish-Workflow (Skill: `publish`) erfordert in Schritt 4: 1. SSH-Verbindung zum VPS 2. `sed`-Bearbeitung der `docker-compose.yml` 3. Implizit: Container-Neustart, um neue Env-Vars zu übernehmen Das ist zu schwer für ein reines Versionsupdate. Ein neues APK sollte keinen Container-Neustart erfordern. ## Gewünschtes Verhalten ### Neuer Publish-Workflow | Schritt | Bisher | Neu | |---------|--------|-----| | 3 – APK hochladen | `scp app-debug.apk root@<vps>:/opt/krisenvorrat/data/app-latest.apk` | ✅ unverändert | | 4 – Version setzen | SSH + `sed docker-compose.yml` + Container-Neustart | `curl POST /api/admin/version` | ### Server-Seite - Neuer Endpoint: `POST /api/admin/version` (gesichert durch Admin-Token) - Server speichert `versionCode` und `versionName` **persistent** in `data/version.json` - `GET /api/version` liest aus dieser Datei (Fallback auf Env-Vars, falls Datei fehlt) - Env-Vars `BOLLWERK_APP_VERSION_CODE` / `BOLLWERK_APP_VERSION_NAME` können mittelfristig entfallen ### Publish-Skill - Schritt 4 wird durch `curl`-Call ersetzt (kein SSH-Zugriff mehr nötig) - Der Admin-Token kommt aus einer lokalen `.env`-Datei / Skript-Variable ## Abgrenzung - Nur der Publish-Prozess ändert sich – kein neues Feature in der App - Server-Authentifizierung des neuen Endpunkts muss gesichert sein (kein offener Write-Endpoint) - Der bestehende `GET /api/version`-Endpunkt bleibt kompatibel (App-seitig keine Änderung nötig) --- ## Implementierungsplan > ⚠️ **Bitte den Plan bestätigen, bevor die Implementierung beginnt.** ### Phase 1 – Server: VersionStore + Endpunkte 1. **`VersionStore`** – Neue Klasse, die `data/version.json` liest und schreibt (`versionCode: Int`, `versionName: String`) 2. **`GET /api/version`** – liest aus `VersionStore` (mit Fallback auf Env-Vars, falls Datei nicht vorhanden) 3. **`POST /api/admin/version`** – schreibt in `VersionStore`, gesichert durch `Authorization: Bearer <BOLLWERK_ADMIN_TOKEN>` Header ### Phase 2 – Publish-Skill aktualisieren 4. **`.github/skills/publish/SKILL.md`** – Schritt 4 durch `curl`-Call dokumentieren: ```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\"}" ``` 5. **Publish-Skript** (PowerShell) – `curl`-Call implementieren, Token aus Umgebungsvariable lesen ### Phase 3 – VPS Cleanup (optional, separates Ticket) 6. Env-Vars `BOLLWERK_APP_VERSION_CODE` / `BOLLWERK_APP_VERSION_NAME` aus `docker-compose.yml` entfernen --- **→ Bitte Plan bestätigen, dann startet die Implementierung.**
jreinemann-euris commented 2026-05-18 06:40:45 +00:00 (Migrated from github.com)

Abgeschlossen (2026-05-18)

Durchgeführte Aufgaben

  • VersionStore – Neue Klasse server/src/.../store/VersionStore.kt die data/version.json liest/schreibt
  • POST /api/admin/version – Neuer Endpoint, gesichert durch Authorization: Bearer <BOLLWERK_ADMIN_TOKEN>
  • GET /api/version – Liest nun aus VersionStore (Fallback auf Env-Vars falls Datei fehlt)
  • Homepage – Zeigt ebenfalls dynamische Version aus VersionStore
  • publish-apk.ps1 – Nutzt nun API-Call statt SSH+sed+Container-Neustart
  • SKILL.md Updates – publish und vps-deploy Dokumentation aktualisiert
  • Tests – 6 neue Tests für POST-Endpoint (Auth, Validation, Happy Path)

Verifikation

  • Build: assembleDebug + :server:compileKotlin erfolgreich
  • Version-Endpoint-Tests: 18/18 passed
  • Keine Regressions in Admin/Auth/Application-Tests

Nächste Schritte (VPS-Deployment)

  1. BOLLWERK_ADMIN_TOKEN in docker-compose.yml auf dem VPS setzen
  2. Neues Server-JAR bauen und deployen
  3. Env-Vars BOLLWERK_APP_VERSION_CODE/NAME können mittelfristig entfernt werden
## Abgeschlossen (2026-05-18) ### Durchgeführte Aufgaben - ✅ **VersionStore** – Neue Klasse `server/src/.../store/VersionStore.kt` die `data/version.json` liest/schreibt - ✅ **POST /api/admin/version** – Neuer Endpoint, gesichert durch `Authorization: Bearer <BOLLWERK_ADMIN_TOKEN>` - ✅ **GET /api/version** – Liest nun aus VersionStore (Fallback auf Env-Vars falls Datei fehlt) - ✅ **Homepage** – Zeigt ebenfalls dynamische Version aus VersionStore - ✅ **publish-apk.ps1** – Nutzt nun API-Call statt SSH+sed+Container-Neustart - ✅ **SKILL.md Updates** – publish und vps-deploy Dokumentation aktualisiert - ✅ **Tests** – 6 neue Tests für POST-Endpoint (Auth, Validation, Happy Path) ### Verifikation - Build: ✅ assembleDebug + :server:compileKotlin erfolgreich - Version-Endpoint-Tests: ✅ 18/18 passed - Keine Regressions in Admin/Auth/Application-Tests ### Nächste Schritte (VPS-Deployment) 1. `BOLLWERK_ADMIN_TOKEN` in docker-compose.yml auf dem VPS setzen 2. Neues Server-JAR bauen und deployen 3. Env-Vars `BOLLWERK_APP_VERSION_CODE`/`NAME` können mittelfristig entfernt werden
Sign in to join this conversation.
No description provided.