mirror of
https://github.com/Novaloop-AG/healthchat-web.git
synced 2026-11-07 06:58:25 +00:00
feat(desktop): build signed Windows + macOS apps in healthchat pipeline
Extend the HealthChat desktop pipeline beyond Linux to produce fully branded, signed Windows (.exe/.msi) and macOS (.dmg/.zip) installers, published to the GitHub Release on the healthchat-v* tag alongside the web build. - Add HealthChat desktop icons (icon.png/ico + Apple Icon Composer bundle), derived from apps/web/res/vector-icons/1024.png - Point the reusable build workflows at this fork (new repository/ref inputs) so the Electron shell, icons and healthchat:// handler are fork-branded - Relax hardcoded Element*/element-desktop* filename asserts to be product-name-agnostic - Wire signed macOS + Windows jobs into build-healthchat-desktop.yaml, trigger it on healthchat-v* tags, and add a release job that uploads installers - Map the org-level eSigner secrets to the CKA names the reusable expects - Document signing setup (Apple env, eSigner mapping, ESIGNER_MODE=prod) in the desktop README and releasing-healthchat skill
This commit is contained in:
@@ -6,13 +6,24 @@ description: Cut a versioned HealthChat release of element-web by tagging releas
|
||||
# Releasing HealthChat (element-web)
|
||||
|
||||
Releases are driven by git tags of the form `healthchat-v<semver>` pushed to
|
||||
`origin`. The tag triggers `.github/workflows/build-healthchat.yaml`, which
|
||||
builds the HealthChat Docker image, publishes it to ghcr.io under
|
||||
`healthchat-web:<version>`, `:stable`, and `:<sha>`, and creates a GitHub
|
||||
Release whose body is the matching section of `HEALTHCHAT_CHANGES.md`.
|
||||
`origin`. The tag triggers two workflows in parallel:
|
||||
|
||||
Publish target: **ghcr.io Docker image + GitHub Release only.** No npm,
|
||||
no tarball distribution, no desktop/mobile fan-out.
|
||||
- `.github/workflows/build-healthchat.yaml` (web) — builds the HealthChat Docker
|
||||
image, publishes it to ghcr.io under `healthchat-web:<version>`, `:stable`, and
|
||||
`:<sha>`, and creates a GitHub Release whose body is the matching section of
|
||||
`HEALTHCHAT_CHANGES.md`.
|
||||
- `.github/workflows/build-healthchat-desktop.yaml` (desktop) — builds the Electron
|
||||
app for Linux (amd64/arm64), macOS (universal, signed+notarised) and Windows
|
||||
(x64/arm64, signed), and attaches the installers (.dmg/.zip/.exe/.msi/.deb/.tar.gz)
|
||||
to the **same** GitHub Release. The two workflows create-if-missing then upload, so
|
||||
they race safely.
|
||||
|
||||
Publish target: **ghcr.io Docker image + GitHub Release (web bundle + desktop
|
||||
installers).** No npm, no mobile fan-out.
|
||||
|
||||
The desktop app version is taken from `apps/desktop/package.json`, not the tag
|
||||
(Windows squirrel rewrites any `version` override into a nightly string). Bump it
|
||||
in the release commit if you want the About dialog / installer filenames to match.
|
||||
|
||||
## Preflight checklist
|
||||
|
||||
@@ -62,6 +73,11 @@ without moving tags.
|
||||
path** — only the tag-push path creates Releases (keeps manual retries from
|
||||
clobbering the release history).
|
||||
|
||||
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.
|
||||
|
||||
## Tag format
|
||||
|
||||
```
|
||||
@@ -110,6 +126,11 @@ warning. Prefer fixing the changelog over relying on the fallback.
|
||||
with the correct body.
|
||||
- [ ] The `:stable` tag on ghcr.io now points at the new digest
|
||||
(`docker buildx imagetools inspect ghcr.io/<owner>/healthchat-web:stable`).
|
||||
- [ ] The desktop workflow run ("Build HealthChat Desktop") is green and the
|
||||
GitHub Release has the desktop installers attached (.dmg, *-mac.zip, *.msi,
|
||||
"* Setup*.exe", *.deb, *.tar.gz).
|
||||
- [ ] Smoke-check signing: macOS `spctl -a -vvv -t install <app>` is accepted;
|
||||
Windows installer shows a valid publisher (no SmartScreen block).
|
||||
|
||||
## Required secrets
|
||||
|
||||
@@ -120,6 +141,22 @@ 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. |
|
||||
|
||||
Desktop signing additionally requires two GitHub **environments** (Settings →
|
||||
Environments). Without them the desktop builds still run but produce
|
||||
unsigned/untrusted output:
|
||||
|
||||
| Environment | Secrets / variables |
|
||||
|---|---|
|
||||
| `Desktop Apple` | secrets `APPLE_ID`, `APPLE_ID_PASSWORD` (app-specific), `APPLE_CSC_LINK` (base64 `.p12`), `APPLE_CSC_KEY_PASSWORD`; variable `APPLE_TEAM_ID` |
|
||||
|
||||
Windows code-signing reuses the org-level SSL.com eSigner secrets shared with the
|
||||
other Novaloop apps (`ESIGNER_USERNAME`, `ESIGNER_PASSWORD`, `ESIGNER_TOTP_SECRET`);
|
||||
the windows job in `build-healthchat-desktop.yaml` maps them to the CKA names the
|
||||
reusable expects (no `credential_id` needed). Set variable `ESIGNER_MODE=prod` for a
|
||||
trusted signature. These org secrets are scoped to private/internal repos, so the
|
||||
fork must stay **internal** (not public). Add branch/environment protection so only
|
||||
`release/healthchat` + `healthchat-v*` runs can reach the signing credentials.
|
||||
|
||||
## Rollback
|
||||
|
||||
- **Bad image, notes fine** → fix the cause, commit, tag `healthchat-v<ver>-hotfix1`.
|
||||
@@ -135,6 +172,19 @@ These files are HealthChat-only and will conflict cleanly when rebasing
|
||||
during rebase):
|
||||
|
||||
- `.github/workflows/build-healthchat.yaml`
|
||||
- `.github/workflows/build-healthchat-desktop.yaml`
|
||||
- `HEALTHCHAT_CHANGES.md`
|
||||
- `.healthchat-workspace-version`
|
||||
- `.claude/skills/releasing-healthchat/SKILL.md`
|
||||
- `apps/desktop/build/icon.png`, `apps/desktop/build/icon.ico`,
|
||||
`apps/desktop/build/icon.icon/` (HealthChat icons)
|
||||
|
||||
The four shared desktop reusables carry small HealthChat additions (a `repository`
|
||||
input + product-name-agnostic asserts). These should merge cleanly, but if they
|
||||
conflict on rebase, re-apply the HealthChat changes rather than blindly taking
|
||||
either side:
|
||||
|
||||
- `.github/workflows/build_desktop_prepare.yaml`
|
||||
- `.github/workflows/build_desktop_linux.yaml`
|
||||
- `.github/workflows/build_desktop_macos.yaml`
|
||||
- `.github/workflows/build_desktop_windows.yaml`
|
||||
|
||||
Reference in New Issue
Block a user