docs: Desktop-App — Update in der App (Handbücher, CI-Secrets, CHANGELOG)
Tessera CI/CD / Lint & Type Check (push) Successful in 48s
Tessera CI/CD / Tests (push) Successful in 1m8s
Tessera CI/CD / Desktop-Pakete bauen (push) Successful in 7m56s
Tessera CI/CD / Build & Publish Images (push) Successful in 3m12s

- Anwenderhandbuch: Menüeintrag "Update installieren", Ablauf per Klick
  unter Windows/Linux, Fehlerfall, https-Bedingung, einmaliger Wechsel für
  Clients bis 1.2.0
- Betriebshandbuch Kap. 10: Signierschlüssel (Secrets, Ablage, Sicherung,
  Verlust), Kontrollzeile /desktop/update, Manifest-Felder, zwei Fehlerbilder
- Entwicklungshandbuch: lokal `tauri build --no-sign`, Hinweise zu tauri dev
- ci-cd-setup.md: die zwei neuen Secrets, Bau-Schritte signieren,
  Fehlerbild "no private key"
- CHANGELOG: eine Zeile unter Unveröffentlicht → Neu

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-17 15:36:58 +02:00
parent 7004b5b020
commit 7479cb485f
5 changed files with 125 additions and 16 deletions
+31 -4
View File
@@ -81,17 +81,27 @@ docker ps --filter name=gitea-runner
### Gitea Secrets (fuer die CI-Pipeline)
In Gitea unter **Repository > Settings > Actions > Secrets** werden die Secrets
fuer die Pipeline konfiguriert. Benoetigt wird genau eines:
fuer die Pipeline konfiguriert. Benoetigt werden drei:
| Secret | Beschreibung |
|--------|--------------|
| `REGISTRY_TOKEN` | Gitea-Zugangstoken (Access Token) mit Schreibrecht auf Pakete (`package: write`) und zusaetzlich auf das Repository (`repository: write`, fuer Releases). Wird im Job `publish` fuer `docker login localhost:3002 --password-stdin` verwendet und im Release-Schritt ueber `env` als `GITEA_TOKEN` an `.gitea/scripts/publish-release.sh` gereicht -- nie als Argument. |
| `TAURI_SIGNING_PRIVATE_KEY` | Inhalt der privaten Schluesseldatei des Tauri-Updaters (eine Base64-Zeile, erzeugt mit `tauri signer generate`). Wird ausschliesslich an den zwei `tauri build`-Schritten des Jobs `desktop` als `env` gesetzt; die Tauri-CLI signiert damit das AppImage und den Windows-Installer (`.sig` neben dem Bundle). Der oeffentliche Gegenpart steht in `apps/desktop/src-tauri/tauri.conf.json` (`plugins.updater.pubkey`). |
| `TAURI_SIGNING_PRIVATE_KEY_PASSWORD` | Passwort zu diesem Schluessel; gleiche Stelle, gleicher Umfang. |
Das Token erscheint nie im Log: es wird per `--password-stdin` uebergeben und
Gitea maskiert Secret-Werte in der Job-Ausgabe. Das Veroeffentlichungs-Skript
`.gitea/scripts/publish-images.sh` kennt das Token nicht; der Login bleibt im
Workflow.
Der Signierschluessel wird ebenfalls nie ausgegeben: die Skripte kennen ihn
nicht (`desktop-collect.sh` prueft nur, OB die Variable gesetzt ist, um die
Signatur zur Pflicht zu machen), nur die beiden Bau-Schritte sehen ihn --
weder `pnpm install`, `apt-get`, `cargo install cargo-xwin` noch die
Cache-Schritte. Die Sicherung des Schluessels ausserhalb der Pipeline
(`~/.tessera/desktop-updater/` auf dem Entwicklungsrechner) beschreibt das
Betriebshandbuch, Kapitel 10.
Der Push geht ueber `localhost:3002` (Gitea laeuft auf demselben Rechner wie der
Runner), weil der Nginx Proxy Manager vor `git.vicolab.de` grosse Image-Blobs
blockt. Das Pullen auf den Servern laeuft ueber `git.vicolab.de`
@@ -180,10 +190,15 @@ sh .gitea/scripts/desktop-stamp.sh stamp`.
(`cargo check`/`cargo clippy`, D-16), Bau des Linux-AppImage
(`tauri build --bundles appimage`), dann des Windows-Installers per
Cross-Bau (`tauri build --runner cargo-xwin --target
x86_64-pc-windows-msvc --bundles nsis`).
x86_64-pc-windows-msvc --bundles nsis`). Beide Bau-Schritte tragen die
Secrets `TAURI_SIGNING_PRIVATE_KEY`/`_PASSWORD` als `env` und signieren
die Bundles (quick-260917-kgc): die Tauri-CLI legt `.sig`-Dateien neben
`-setup.exe` und `.AppImage` ab -- host-unabhaengig, also auch im
Cross-Bau. Kein `--no-sign` im CI.
6. **Pakete einsammeln** (`desktop-collect.sh --require linux,windows`) --
schreibt `manifest.json` und schlaegt fehl, wenn eine der beiden Dateien
fehlt.
schreibt `manifest.json` (mit `updateVersion` und je Plattform der
`signature` aus der `.sig`-Datei) und schlaegt fehl, wenn eine der beiden
Dateien fehlt oder auf `main`/Tags eine `.sig` fehlt.
7. **Uebergabe an `publish`** per `actions/cache/save@v4` mit dem Schluessel
`desktop-dist-${{ gitea.sha }}` (ein neuer Schluessel je Commit, damit
`publish` garantiert die Pakete des gerade gebauten Standes bekommt, nicht
@@ -343,6 +358,18 @@ und einen Branch-Schutz fuer `live` anlegen (T-KU1-04).
Speicherdruck `CARGO_BUILD_JOBS` (z. B. auf `4`) als Umgebungsvariable im
Job setzen, um die parallele Uebersetzung zu drosseln.
### Job `desktop`: "A public key has been found, but no private key"
Die Tauri-CLI bricht den Bau ab, weil `plugins.updater.pubkey` in
`tauri.conf.json` gesetzt ist, aber `TAURI_SIGNING_PRIVATE_KEY` in der
Umgebung fehlt. Ursache sind fast immer fehlende oder umbenannte Secrets: in
Gitea unter **Repository > Settings > Actions > Secrets** pruefen, ob
`TAURI_SIGNING_PRIVATE_KEY` und `TAURI_SIGNING_PRIVATE_KEY_PASSWORD` unter
genau diesen Namen existieren, und ob beide Bau-Schritte in `ci.yml` den
`env`-Block tragen. Niemals `--no-sign` in `ci.yml` eintragen -- damit
entstuenden unsignierte Pakete, die kein Client als Update annimmt
(`desktop-collect.sh` bricht auf `main`/Tags ohne `.sig` ohnehin ab).
### `desktop` baut, obwohl nichts geaendert wurde -- oder uebernimmt trotz Aenderung
**Baut trotzdem:**