From 76ad50e3aae6921af933c35f7bd88b4272009687 Mon Sep 17 00:00:00 2001 From: Jens Reinemann Date: Mon, 18 May 2026 11:34:42 +0200 Subject: [PATCH] =?UTF-8?q?refactor(publish):=20publish-apk.ps1=20=C3=BCbe?= =?UTF-8?q?rnimmt=20vollst=C3=A4ndigen=20Deploy-Workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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) --- .github/prompts/publish.prompt.md | 62 +++++++-------- .github/skills/publish/SKILL.md | 25 ++++-- .github/skills/publish/publish-apk.ps1 | 103 +++++++++++++++++++------ 3 files changed, 123 insertions(+), 67 deletions(-) diff --git a/.github/prompts/publish.prompt.md b/.github/prompts/publish.prompt.md index e21a228..e32828b 100644 --- a/.github/prompts/publish.prompt.md +++ b/.github/prompts/publish.prompt.md @@ -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 -VersionName "" -``` - -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` diff --git a/.github/skills/publish/SKILL.md b/.github/skills/publish/SKILL.md index 701fd4d..af7167a 100644 --- a/.github/skills/publish/SKILL.md +++ b/.github/skills/publish/SKILL.md @@ -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 3–5: +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 3–5 **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) | --- diff --git a/.github/skills/publish/publish-apk.ps1 b/.github/skills/publish/publish-apk.ps1 index a58ed06..93011e3 100644 --- a/.github/skills/publish/publish-apk.ps1 +++ b/.github/skills/publish/publish-apk.ps1 @@ -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" +$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