refactor(publish): publish-apk.ps1 übernimmt vollständigen Deploy-Workflow

- publish-apk.ps1: Version-Bump, Build, SCP, API, Verify, git commit/push
  (alle Parameter optional – Standalone-Nutzung ohne Copilot möglich)
- publish.prompt.md: vereinfacht (kein manueller Version-Bump mehr nötig)
- SKILL.md: Parameter-Tabelle aktualisiert
- deploy.ps1 im Root entfernt (Logik lebt jetzt im Skill)
This commit is contained in:
Jens Reinemann 2026-05-18 11:34:42 +02:00
parent 301d60aea4
commit 76ad50e3aa
3 changed files with 123 additions and 67 deletions

View file

@ -1,5 +1,5 @@
---
description: "publish Neue App-Version bauen und auf dem VPS veröffentlichen. Bumpt die Version, baut die APK, lädt sie auf den Server hoch und verifiziert QR-Code-Seite + Update-API."
description: "publish Neue App-Version bauen und auf dem VPS veröffentlichen. Bumpt die Version automatisch, baut die APK, lädt sie auf den Server hoch, verifiziert QR-Code-Seite + Update-API und committet den Version-Bump."
name: "publish"
agent: agent
tools: [read, search, execute/runInTerminal, execute/sendToTerminal, execute/getTerminalOutput, edit]
@ -7,54 +7,48 @@ tools: [read, search, execute/runInTerminal, execute/sendToTerminal, execute/get
Lies **zuerst** die Publish-Skill-Datei `.github/skills/publish/SKILL.md` vollständig mit `read_file`.
Führe danach den vollständigen Publish-Workflow durch:
Führe danach den Publish-Workflow durch:
---
## Schritt 1 Version ermitteln
## Schritt 1 Optionale Vorbereitung
1. Lies `app/build.gradle.kts` und ermittle den aktuellen `versionCode` und `versionName`.
2. Frage den User, auf welche Version gebumpt werden soll (Vorschlag: versionCode +1, versionName minor bump).
3. Ändere `versionCode` und `versionName` in `app/build.gradle.kts`.
- Lies `app/build.gradle.kts` um den aktuellen Stand zu zeigen (versionCode / versionName).
- Falls der User eine bestimmte `versionName` möchte, nutze den Parameter `-VersionName`.
- Ansonsten: kein Eingriff nötig das Skript bumpt den versionCode automatisch.
---
## Schritt 2 Build & Test (Quality Gate)
## Schritt 2 Publish-Skript ausführen
```powershell
.\gradlew.bat assembleDebug test
& ".github/skills/publish/publish-apk.ps1"
# oder mit explizitem versionName:
& ".github/skills/publish/publish-apk.ps1" -VersionName "2.0"
```
- **BUILD SUCCESSFUL** → weiter mit Schritt 3.
- **Fehler** → analysieren und beheben (max. 3 Zyklen).
Das Skript erledigt vollautomatisch:
1. versionCode +1 in `app/build.gradle.kts`
2. `./gradlew assembleDebug`
3. APK per SCP auf VPS hochladen
4. `POST /api/admin/version` (kein Container-Neustart)
5. Verifizieren (Homepage + Version-API)
6. `git commit` + `git push`
Verwende `mode=sync` mit `timeout=300000`.
**Voraussetzungen prüfen** (falls Fehler auftreten):
- SSH-Agent: `ssh-add -l`
- Token: `$env:BOLLWERK_ADMIN_TOKEN` muss gesetzt sein
---
## Schritt 3 Commit & Push
1. Erstelle einen Commit: `release: v{versionName} (build {versionCode})`
2. Push auf origin (gemäß Git-Konventionen: ankündigen, User kann abbrechen).
---
## Schritt 4 APK auf VPS veröffentlichen
Führe das Publish-Skript aus:
```powershell
& ".github/skills/publish/publish-apk.ps1" -VersionCode <code> -VersionName "<name>"
```
Verwende `mode=sync` mit `timeout=120000`.
---
## Schritt 5 Ergebnis berichten
## Schritt 3 Ergebnis berichten
Berichte kurz:
- Neue Version (versionCode + versionName)
- Build/Test-Status (✅ / ❌)
- Push-Status (✅ / ❌)
- Build-Status (✅ / ❌)
- VPS-Deployment (✅ / ❌)
- Homepage-URL: `http://bollwerk.online:8080/`
- Version-API: `http://bollwerk.online:8080/api/version`
- Push-Status (✅ / ❌)
- Homepage: `https://bollwerk.online/`
- Version-API: `https://bollwerk.online/api/version`

View file

@ -109,10 +109,17 @@ Invoke-WebRequest -Uri "https://bollwerk.online/" -UseBasicParsing | Select-Obje
## Automatisiertes Skript
Das Skript `publish-apk.ps1` in diesem Skill-Ordner automatisiert Schritte 35:
Das Skript `publish-apk.ps1` in diesem Skill-Ordner automatisiert den **gesamten** Release-Workflow (Version bumpen, bauen, hochladen, API-Call, verifizieren, committen):
```powershell
& ".github/skills/publish/publish-apk.ps1" -VersionCode 4 -VersionName "1.3"
# Alles automatisch (versionCode +1, versionName bleibt):
& ".github/skills/publish/publish-apk.ps1"
# Mit neuem versionName:
& ".github/skills/publish/publish-apk.ps1" -VersionName "2.0"
# Nur hochladen (APK bereits gebaut, kein Push):
& ".github/skills/publish/publish-apk.ps1" -SkipBuild -SkipPush
```
**Voraussetzungen:**
@ -122,12 +129,14 @@ Das Skript `publish-apk.ps1` in diesem Skill-Ordner automatisiert Schritte 35
**Parameter:**
| Parameter | Pflicht | Beschreibung |
| -------------- | ------- | -------------------------------------- |
| `-VersionCode` | ja | Neuer versionCode (Integer) |
| `-VersionName` | ja | Neuer versionName (String, z.B. "1.3") |
| `-ApkPath` | nein | Pfad zur APK (Default: debug-APK) |
| `-SkipVerify` | nein | Verifizierung überspringen |
| Parameter | Pflicht | Default | Beschreibung |
| -------------- | ------- | ------------- | --------------------------------------------------- |
| `-VersionName` | nein | aktueller | Neuer versionName (z.B. "2.0"); sonst unverändert |
| `-VersionCode` | nein | aktuell + 1 | Expliziter versionCode; sonst automatisch +1 |
| `-ApkPath` | nein | debug-APK | Pfad zur APK-Datei |
| `-SkipBuild` | nein | false | Gradle-Build überspringen |
| `-SkipVerify` | nein | false | Verifizierung nach dem Deploy überspringen |
| `-SkipPush` | nein | false | Git-Push überspringen (nur lokaler Commit) |
---

View file

@ -1,29 +1,45 @@
<#
.SYNOPSIS
Publiziert eine APK auf den Bollwerk VPS.
Vollständiger Publish-Workflow: Version bumpen, bauen, auf VPS deployen, committen.
.DESCRIPTION
Lädt die APK auf den VPS hoch und benachrichtigt den Server über die neue
Version via API-Endpoint (kein Container-Neustart nötig).
.PARAMETER VersionCode
Neuer versionCode (Integer, muss > aktueller sein).
Führt alle Schritte des Release-Workflows aus:
1. versionCode automatisch erhöhen (aus build.gradle.kts)
2. APK bauen (./gradlew assembleDebug) überspringbar mit -SkipBuild
3. APK per SCP auf VPS hochladen
4. Server-Version per API aktualisieren (kein Container-Neustart nötig)
5. Verifizieren (überspringbar mit -SkipVerify)
6. git commit + push überspringbar mit -SkipPush
.PARAMETER VersionName
Neuer versionName (z.B. "1.3").
Neue versionName (z.B. "1.8"). Wenn weggelassen, bleibt die aktuelle.
.PARAMETER VersionCode
Expliziter versionCode. Wenn weggelassen, wird der aktuelle automatisch um 1 erhöht.
.PARAMETER ApkPath
Pfad zur APK-Datei. Default: app/build/outputs/apk/debug/app-debug.apk
.PARAMETER SkipBuild
Gradle-Build überspringen (wenn APK bereits gebaut).
.PARAMETER SkipVerify
Verifizierung nach dem Deploy überspringen.
.PARAMETER SkipPush
Git-Push überspringen (nur lokaler Commit).
.EXAMPLE
& ".github/skills/publish/publish-apk.ps1"
& ".github/skills/publish/publish-apk.ps1" -VersionName "2.0"
& ".github/skills/publish/publish-apk.ps1" -SkipBuild -SkipPush
#>
param(
[Parameter(Mandatory)] [int] $VersionCode,
[Parameter(Mandatory)] [string] $VersionName,
[string] $VersionName,
[int] $VersionCode = 0,
[string] $ApkPath = "app/build/outputs/apk/debug/app-debug.apk",
[switch] $SkipVerify
[switch] $SkipBuild,
[switch] $SkipVerify,
[switch] $SkipPush
)
$ErrorActionPreference = "Stop"
$VPS = "root@195.246.231.210"
$RemoteDir = "/opt/bollwerk"
$ServerUrl = "https://bollwerk.online"
$BuildGradle = "app/build.gradle.kts"
# --- Admin-Token laden ---
$AdminToken = $env:BOLLWERK_ADMIN_TOKEN
@ -32,8 +48,34 @@ if (-not $AdminToken) {
exit 1
}
# --- Preflight ---
Write-Host "=== Publish APK v$VersionName (build $VersionCode) ===" -ForegroundColor Cyan
# --- Version aus build.gradle.kts lesen und bumpen ---
$gradleContent = Get-Content $BuildGradle -Raw
$currentCode = [int]([regex]::Match($gradleContent, 'versionCode\s*=\s*(\d+)').Groups[1].Value)
$currentName = [regex]::Match($gradleContent, 'versionName\s*=\s*"([^"]+)"').Groups[1].Value
$newCode = if ($VersionCode -gt 0) { $VersionCode } else { $currentCode + 1 }
$newName = if ($VersionName) { $VersionName } else { $currentName }
Write-Host ""
Write-Host "=== Publish APK v$newName (build $newCode) ===" -ForegroundColor Cyan
Write-Host " $currentName ($currentCode) → $newName ($newCode)" -ForegroundColor Gray
Write-Host ""
$updated = $gradleContent -replace "versionCode\s*=\s*$currentCode", "versionCode = $newCode"
if ($VersionName) {
$updated = $updated -replace 'versionName\s*=\s*"[^"]+"', "versionName = `"$newName`""
}
[System.IO.File]::WriteAllText((Resolve-Path $BuildGradle).Path, $updated)
Write-Host "[OK] build.gradle.kts: versionCode=$newCode, versionName=$newName" -ForegroundColor Green
# --- Build ---
if ($SkipBuild) {
Write-Host "[--] Build uebersprungen (-SkipBuild)" -ForegroundColor DarkGray
} else {
Write-Host "`n[1/4] APK bauen..." -ForegroundColor Yellow
& ./gradlew assembleDebug
if ($LASTEXITCODE -ne 0) { Write-Error "Build fehlgeschlagen."; exit 1 }
Write-Host "[OK] APK gebaut" -ForegroundColor Green
}
if (-not (Test-Path $ApkPath)) {
Write-Error "APK nicht gefunden: $ApkPath - bitte zuerst './gradlew assembleDebug' ausfuehren."
@ -48,17 +90,17 @@ if ($LASTEXITCODE -ne 0) {
}
Write-Host "[OK] SSH-Agent aktiv" -ForegroundColor Green
# --- Schritt 1: APK hochladen ---
Write-Host "`n[1/3] APK hochladen..." -ForegroundColor Yellow
# --- Schritt 2: APK hochladen ---
Write-Host "`n[2/4] APK hochladen..." -ForegroundColor Yellow
ssh $VPS "mkdir -p $RemoteDir/data"
scp $ApkPath "${VPS}:${RemoteDir}/data/app-latest.apk"
if ($LASTEXITCODE -ne 0) { Write-Error "APK-Upload fehlgeschlagen."; exit 1 }
Write-Host "[OK] APK hochgeladen" -ForegroundColor Green
# --- Schritt 2: Server über neue Version benachrichtigen ---
Write-Host "`n[2/3] Server-Version aktualisieren (API-Call)..." -ForegroundColor Yellow
# --- Schritt 3: Server über neue Version benachrichtigen ---
Write-Host "`n[3/4] Server-Version aktualisieren (API-Call)..." -ForegroundColor Yellow
$body = @{ versionCode = $VersionCode; versionName = $VersionName } | ConvertTo-Json -Compress
$body = @{ versionCode = $newCode; versionName = $newName } | ConvertTo-Json -Compress
$headers = @{
"Authorization" = "Bearer $AdminToken"
"Content-Type" = "application/json"
@ -78,22 +120,22 @@ try {
Write-Error "Version-Update fehlgeschlagen: $_"
exit 1
}
Write-Host "[OK] Version gesetzt: $VersionName (build $VersionCode)" -ForegroundColor Green
Write-Host "[OK] Version gesetzt: $newName (build $newCode)" -ForegroundColor Green
# --- Schritt 3: Verifizieren ---
# --- Schritt 4: Verifizieren ---
if ($SkipVerify) {
Write-Host "`n[3/3] Verifizierung uebersprungen." -ForegroundColor DarkGray
Write-Host "`n[4/4] Verifizierung uebersprungen." -ForegroundColor DarkGray
} else {
Write-Host "`n[3/3] Verifizieren..." -ForegroundColor Yellow
Write-Host "`n[4/4] Verifizieren..." -ForegroundColor Yellow
Start-Sleep -Seconds 2
$versionResponse = Invoke-WebRequest -Uri "$ServerUrl/api/version" -UseBasicParsing
$versionJson = $versionResponse.Content | ConvertFrom-Json
if ($versionJson.versionCode -eq $VersionCode -and $versionJson.versionName -eq $VersionName) {
if ($versionJson.versionCode -eq $newCode -and $versionJson.versionName -eq $newName) {
Write-Host "[OK] /api/version: versionCode=$($versionJson.versionCode), versionName=$($versionJson.versionName)" -ForegroundColor Green
} else {
Write-Warning "Version stimmt nicht ueberein! Erwartet: $VersionCode/$VersionName, Erhalten: $($versionJson.versionCode)/$($versionJson.versionName)"
Write-Warning "Version stimmt nicht ueberein! Erwartet: $newCode/$newName, Erhalten: $($versionJson.versionCode)/$($versionJson.versionName)"
}
$homepageResponse = Invoke-WebRequest -Uri "$ServerUrl/" -UseBasicParsing
@ -104,6 +146,17 @@ if ($SkipVerify) {
}
}
# --- Git Commit + Push ---
Write-Host "`n[Git] Committen..." -ForegroundColor Yellow
git add $BuildGradle
git commit -m "chore: release v$newName ($newCode)"
if (-not $SkipPush) {
git push
Write-Host "[OK] Gepusht" -ForegroundColor Green
} else {
Write-Host "[--] Push uebersprungen (-SkipPush)" -ForegroundColor DarkGray
}
Write-Host "`n=== Publish abgeschlossen ===" -ForegroundColor Cyan
Write-Host "Homepage: https://bollwerk.online/" -ForegroundColor DarkGray
Write-Host "API: https://bollwerk.online/api/version" -ForegroundColor DarkGray
Write-Host "Homepage: $ServerUrl/" -ForegroundColor DarkGray
Write-Host "API: $ServerUrl/api/version" -ForegroundColor DarkGray