diff --git a/AGENTS.md b/AGENTS.md index a209373..3c6e6de 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1982,6 +1982,26 @@ published the new manifest version and a complete `buendel` block; the zip serve identically to `bundle.json`'s `sha256`; `unzip -l`/`-t` confirmed 13 entries, `index.html` at the root, no backslashes, no corruption. +**A second, quieter bug surfaced 2026-08-24 when a manifest-only metadata change (the GitHub-removal +commit) prompted the question of whether it needed a version bump.** It didn't — but the question +exposed that nothing enforced `frontend/app/bundle.json`'s version staying in sync with +`manifest.json`'s on a *real* bump. Trace the failure: bump manifest to V2, ship via `install.ps1`, +forget `npm run ota` → backend publishes `app: "V2"` live, but `bundle.json` (frozen at build time) +still says V1, and the already-installed app is still V1. `Hinweisleiste` compares app-vs-server and +correctly says "you're outdated, update" (V1 ≠ V2) — but the Update screen's `buendelPasst()` +compares app-vs-*bundle* and says "you're current" (V1 = V1, the bundle's stale number). Two +contradictory messages, and no way to actually reach V2 via OTA until someone notices and reruns +`npm run ota` — the exact kind of silent-until-discovered coordination bug this project has fixed +repeatedly elsewhere (trip status, tire counter, `edited_fields`). Fixed at the one chokepoint every +delivery already passes through: `install.ps1` now reads `frontend/app/bundle.json`'s version right +after reading the manifest's, warns loudly and adds the mismatch as the **first** Restliste item if +they differ (a missing bundle file is not a mismatch — OTA is optional, silence is correct then). +Verified both ways on a mock config dir: matching versions print "OTA-Bündel passt zur Integration" +and add nothing to the Restliste; a deliberately bumped manifest (tested via a temporary edit, +reverted byte-for-byte after, diffed against `HEAD` to confirm) produces the warning and lands it as +Restliste item 1. `VERSIONIERUNG.md`'s "Was du tun musst" now lists the OTA rebuild as its own +numbered step (2, before shipping) instead of omitting it entirely. + Capacitor's `server.url` pointed at HA was considered and **rejected**: it would make the app as current as the panel, but the shell then cannot boot without reaching HA, gutting the deliberately built offline queue (`api/warteschlange.ts`). diff --git a/VERSIONIERUNG.md b/VERSIONIERUNG.md index 2c751fb..72a04b9 100644 --- a/VERSIONIERUNG.md +++ b/VERSIONIERUNG.md @@ -88,13 +88,26 @@ ohne Netz darf keinen Fehlalarm auslösen. 1. `version` in `manifest.json` erhöhen — bei mehreren Änderungen am selben Tag die laufende Nummer: `2026.8.23.2` → `2026.8.23.3`, am nächsten Tag `2026.8.24.1`. -2. Integration ausliefern: `homeassistant\installationspaket\Installieren.cmd` +2. **OTA-Bündel neu bauen: `npm run ota`** (in `companion-app/`). Baut die + Oberfläche und packt sie mit der neuen Versionsnummer — siehe + [OTA-Updates](#ota-updates-seit-2026-08-24) unten. Ohne diesen Schritt + trägt `frontend/app/bundle.json` noch die alte Nummer: die Hinweisleiste + sagt dann „du bist veraltet" (liest die Version live), die Update-Seite + sagt „du bist aktuell" (vergleicht gegen das eingefrorene, jetzt falsche + Bündel) — ein Widerspruch, aus dem es ohne diesen Schritt keinen Ausweg + gibt. `install.ps1` prüft das seit 2026-08-24 selbst und warnt, falls + vergessen — aber besser, es passiert gar nicht erst. +3. Integration ausliefern: `homeassistant\installationspaket\Installieren.cmd` (HACS scheidet aus — siehe Kasten oben, das Repository ist privat). -3. iOS-App neu bauen (`npm run build`), damit sie dieselbe Zahl einkompiliert - bekommt. +4. iOS-App für Xcode neu bauen (`npm run build`), damit eine über App Store + Connect / Sideload signierte Fassung dieselbe Zahl einkompiliert bekommt. + Für alle, die die App schon installiert haben, erledigt Schritt 2 das + automatisch über OTA — dieser Schritt ist nur für die nächste + Neuinstallation oder Signatur-Erneuerung nötig. -Vergisst du Schritt 3, ist das kein stiller Fehler mehr: die App meldet selbst, -dass sie älter ist als der Server. +Vergisst du Schritt 4, ist das kein stiller Fehler mehr: die App meldet selbst, +dass sie älter ist als der Server. Vergisst du Schritt 2, bleibt es leider +still — deshalb die Prüfung in `install.ps1`. **Bei einer reinen Neuinstallation** ohne Codeänderung: nichts tun. diff --git a/homeassistant/installationspaket/install.ps1 b/homeassistant/installationspaket/install.ps1 index f03cd00..7478484 100644 --- a/homeassistant/installationspaket/install.ps1 +++ b/homeassistant/installationspaket/install.ps1 @@ -106,6 +106,33 @@ if (-not $quelle) { $version = (Get-Content (Join-Path $quelle "manifest.json") -Raw | ConvertFrom-Json).version Gut "Quelle: $quelle (Version $version)" +# ------------------------------------------------ OTA-Bündel auf Stand prüfen +# Das Bündel für die iOS-App (frontend\app\bundle.json, gebaut von +# companion-app\scripts\ota-paket.ps1) trägt seine eigene, zum Bauzeitpunkt +# eingefrorene Versionsnummer. Ändert sich manifest.json's Version, ohne dass +# jemand "npm run ota" erneut laufen lässt, bekommt die App zwei +# widersprüchliche Signale gleichzeitig: die Hinweisleiste sagt "du bist +# veraltet" (vergleicht gegen die live gelesene manifest-Version), die +# Update-Seite sagt "du bist aktuell" (vergleicht gegen das eingefrorene, nun +# falsche Bündel) - und es gibt keinen Weg, das Update zu bekommen, bis jemand +# den Widerspruch bemerkt. Das ist kein Zustand, den ein Installer schweigend +# durchwinken sollte - hier ist der eine Ort, an dem jede Auslieferung +# durchläuft, also der einzige verlässliche Punkt für diese Prüfung. +# +# Ein fehlendes Bündel ist dagegen kein Fehler: OTA ist eine optionale +# Zusatzfunktion, nicht jede Installation liefert eins mit. +$buendelInfo = Join-Path $quelle "frontend\app\bundle.json" +if (Test-Path $buendelInfo) { + $buendelVersion = (Get-Content $buendelInfo -Raw | ConvertFrom-Json).version + if ($buendelVersion -ne $version) { + Warnung "OTA-Bündel (frontend\app\bundle.json) steht auf Version $buendelVersion, die Integration auf $version." + Write-Host " Die App-Update-Funktion würde bis zur Behebung falsche Ergebnisse zeigen." -ForegroundColor Yellow + [void]$restliste.Add("OTA-Bündel ist veraltet (Version $buendelVersion statt $version): in companion-app\ 'npm run ota' ausführen, dann dieses Skript erneut laufen lassen.") + } else { + Info "OTA-Bündel passt zur Integration (Version $buendelVersion)" + } +} + # ---------------------------------------------------------------- Ziel finden if (-not $Ziel) { Schritt "Suche Home Assistant ..."