ci: stage desktop feed on packages.healthchat.ch archive

This commit is contained in:
2026-07-29 23:28:39 +02:00
parent 09e66dba47
commit 30bb2bfca3
4 changed files with 143 additions and 103 deletions
+32 -30
View File
@@ -24,24 +24,26 @@ Releases are driven by git tags of the form `healthchat-v<semver>` pushed to
so they race safely). (Linux is intentionally not built — the upstream Linux reusable
pulls a build-env Docker image keyed by commit SHA that only exists in the upstream
element-hq registry, so it cannot succeed in this fork.) The `release` job **stages**
the Squirrel update feed and public installers and attaches them to the Release as
split `healthchat-desktop-feed-<version>.tar.gz.part*` assets (the compressed feed
exceeds GitHub's 2 GiB per-asset cap) — but it **does not publish them**. Installer
binaries are not attached individually; the Release notes get a "## Downloads"
section linking their public URLs on packages.healthchat.ch, which resolve once the
version is deployed. See "Deploying the desktop release" below.
the Squirrel update feed and public installers and uploads them to the versioned
archive at `https://packages.healthchat.ch/desktop-releases/<version>/` — but it
**does not publish them** to the live feed. Nothing binary is attached to the GitHub
Release (the compressed feed outgrew GitHub's 2 GiB per-asset cap at 1.6.0); the
Release notes get a "## Downloads" section linking the installers' public URLs on
packages.healthchat.ch, which resolve once the version is deployed. See "Deploying
the desktop release" below.
- `.github/workflows/deploy-healthchat-desktop.yaml` (desktop deploy) — **manual
dispatch only.** Downloads and reassembles those feed parts and mirrors the feed to
`https://packages.healthchat.ch/desktop/` over FTPS (the private GitHub Release can
serve neither end users nor the auto-updater), plus the legacy
dispatch only.** Fetches the staged archive for the requested version and mirrors it
to the live feed at `https://packages.healthchat.ch/desktop/` over FTPS (the private
GitHub Release can serve neither end users nor the auto-updater), plus the legacy
`https://healthchat.ch/packages/desktop/` path while clients built <= 1.5.0 are still
in the field. This is what makes installed apps
self-update; see `apps/desktop/element.io/healthchat/README` for the feed layout and
the two caveats (first install is manual; Windows auto-update needs the Setup.exe path,
not the .msi).
Publish target: **ghcr.io Docker image + GitHub Release (web bundle + desktop feed
parts, with installer download links).** No npm, no mobile fan-out.
Publish target: **ghcr.io Docker image + versioned feed archive on
packages.healthchat.ch + GitHub Release (web bundle + installer download links).**
No npm, no mobile fan-out.
## Release ≠ deploy
@@ -189,9 +191,9 @@ run or `:latest` had not moved yet.
## Deploying the desktop release
The desktop build attaches the split `healthchat-desktop-feed-<version>.tar.gz.part*`
assets to the Release but
leaves `https://packages.healthchat.ch/desktop/` untouched. Until you run this, installed
The desktop build stages the feed at
`https://packages.healthchat.ch/desktop-releases/<version>/` but
leaves the live feed at `https://packages.healthchat.ch/desktop/` untouched. Until you run this, installed
apps keep whatever version they have and the public download links still serve the old
installers.
@@ -223,10 +225,10 @@ means the feed is genuinely live. Installed apps pick it up on their next update
### Deploying an RC or rolling back
`version` accepts any released version, including `1.5.0-rc1`. Because the feed lives on
the Release (assets never expire, unlike workflow artifacts), **re-running this workflow
with an older version republishes that feed** — no rebuild, no re-signing. That is the
desktop rollback path:
`version` accepts any released version, including `1.5.0-rc1`. Because staged feeds
persist in the versioned archive (`desktop-releases/<version>/`), **re-running this
workflow with an older version republishes that feed** — no rebuild, no re-signing.
That is the desktop rollback path:
```bash
gh workflow run deploy-healthchat-desktop.yaml --ref release/healthchat -f version=1.4.1
@@ -237,9 +239,9 @@ newer `*.nupkg` files in place. That is intentional — Squirrel.Windows needs t
history — and harmless, since clients follow `RELEASES`/`releases.json`, not directory
listings.
Releases cut **before** this release/deploy split carry no feed tarball. The workflow says
so explicitly and lists the assets it did find; re-run "Build HealthChat Desktop" for that
version to produce one.
Versions with no staged archive (cut before the archive design) fail the deploy with a
pointer; dispatch "Build HealthChat Desktop" with `version=<version>` to rebuild and
stage that version, then re-run the deploy.
## Manual / retry path (workflow_dispatch)
@@ -260,9 +262,10 @@ without moving tags.
override in "Deploying the release" if that is what you want.
The desktop workflow ("Build HealthChat Desktop") has its own workflow_dispatch
with the same inputs; like the web path, its `release` job only publishes on a
real tag push, so a manual dispatch builds and uploads run artifacts but does not
attach anything to a Release.
with the same inputs. Its `release` job **also runs on dispatch** to (re)stage the
feed archive at `desktop-releases/<version>/` — that is the recovery path when a
version's archive is missing — but the GitHub Release steps (create + Downloads
links) stay tag-only, so a dispatch can never touch release history.
## Tag format
@@ -322,11 +325,10 @@ warning. Prefer fixing the changelog over relying on the fallback.
For an `-rc`/`-hotfix`/`-dryrun` tag the opposite is expected: `:latest` must
be **unchanged**.
- [ ] The desktop workflow run ("Build HealthChat Desktop") is green and the
GitHub Release carries the split feed assets
`healthchat-desktop-feed-<version>.tar.gz.part*` plus a "## Downloads" section
in its notes linking the public installers. Without those parts the desktop
deploy has nothing to publish.
- [ ] The desktop workflow run ("Build HealthChat Desktop") is green, the GitHub
Release notes carry the "## Downloads" section, and the staged archive exists:
`curl -fsS https://packages.healthchat.ch/desktop-releases/<version>/update/macos/releases.json`.
Without that archive the desktop deploy has nothing to publish.
- [ ] Confirm the live feed is still on the **previous** version — releasing must not have
moved it. `curl -fsS https://packages.healthchat.ch/desktop/update/macos/releases.json`
- [ ] Smoke-check signing before shipping to users: macOS `spctl -a -vvv -t install <app>`
@@ -354,7 +356,7 @@ Configured in repo Settings → Secrets and variables → Actions:
|---|---|
| `HEALTHCHAT_WORKSPACE_TOKEN` | PAT with read access to `Novaloop-AG/healthchat-workspace`. Needed by `actions/checkout` for the private plugin repo. |
| `GITHUB_TOKEN` | Auto-provided. Used for ghcr.io login and GitHub Release creation. No manual setup required. |
| `FTP_SERVER` / `FTP_USERNAME` / `FTP_PASSWORD` | Credentials for the healthchat.ch FTP(S) account. Used **only** by `deploy-healthchat-desktop.yaml` to publish the update feed + public installers under `/public_html/packages/desktop/` (docroot of packages.healthchat.ch) plus, during the URL migration, the legacy `/public_html/healthchat.ch/packages/desktop/`. `FTP_SERVER` is the hostname only (explicit FTPS / AUTH TLS). The release workflows never touch FTP, so a missing/expired credential breaks the deploy but never the release. |
| `FTP_SERVER` / `FTP_USERNAME` / `FTP_PASSWORD` | Credentials for the healthchat.ch FTP(S) account (docroot of packages.healthchat.ch is `/public_html/packages`). Used by the `release` job of `build-healthchat-desktop.yaml` to stage the feed archive under `/public_html/packages/desktop-releases/<version>/`, and by `deploy-healthchat-desktop.yaml` to publish the live feed under `/public_html/packages/desktop/` plus, during the URL migration, the legacy `/public_html/healthchat.ch/packages/desktop/`. `FTP_SERVER` is the hostname only (explicit FTPS / AUTH TLS). |
Desktop signing additionally requires two GitHub **environments** (Settings →
Environments). Without them the desktop builds still run but produce