Files
healthchat-web/apps/desktop/element.io/healthchat/README
T
joel.poyet f6925dbd77 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
2026-06-26 15:10:38 +02:00

102 lines
5.6 KiB
Plaintext

HealthChat desktop variant
===========================
This directory is the `--cfgdir` / build config for HealthChat desktop builds:
config.json Element Web runtime config baked into webapp.asar. Mirrors
apps/web/config.json (HealthChat homeserver, theme, branding) and
loads the HealthChat plugin:
- "modules": ["/modules/healthchat-module.js"]
- "ch.healthchat.elements_base_url": "/webapp/modules/elements"
build.json electron-builder variant (appId, productName "HealthChat", protocols).
Why the paths differ from web
-----------------------------
The desktop app serves the webapp from `vector://vector/webapp/`, so root-relative
paths need a `/webapp` prefix:
- The `modules` array is rewritten automatically by apps/desktop/src/electron-main.ts
(`/modules/x` -> `/webapp/modules/x`), so it stays as `/modules/healthchat-module.js`.
- `ch.healthchat.elements_base_url` is NOT auto-rewritten (the elements bundle is loaded
by a <script> tag the plugin injects, not by the module loader), so it is set explicitly
to `/webapp/modules/elements` here. On web it is `/modules/elements`.
The plugin artifacts must live inside the asar at `modules/healthchat-module.js` and
`modules/elements/healthchat-elements.js`.
Building locally
----------------
# 1. Build the element-plugin (from the healthchat-workspace checkout) and stage it:
(cd ../healthchat-workspace/element-plugin && npm ci && npm run build)
(cd ../healthchat-workspace/element-plugin/module && npm ci && npm run build)
mkdir -p plugin-dist/elements
cp ../healthchat-workspace/element-plugin/module/dist/healthchat-module.js plugin-dist/healthchat-module.js
cp ../healthchat-workspace/element-plugin/dist/elements/browser/main.js plugin-dist/elements/healthchat-elements.js
# 2. Build the fork webapp with the plugin injected:
./apps/desktop/scripts/build-healthchat-webapp.sh
# 3. Pack and run:
cp apps/desktop/element.io/healthchat/config.json apps/desktop/webapp/config.json
pnpm --dir apps/desktop run asar-webapp
pnpm --dir apps/desktop start
CI
--
.github/workflows/build-healthchat-desktop.yaml builds the plugin + webapp artifact and
feeds it into build_desktop_prepare.yaml (`config: element.io/healthchat`,
`webapp-artifact: healthchat-webapp`) and the per-platform build_desktop_{linux,macos,windows}.yaml
reusables. It runs on every `healthchat-v*` tag (alongside the web build) and via
workflow_dispatch. The reusables are pointed at THIS fork (`repository`/`ref` inputs) so the
Electron shell, icons and the healthchat:// deep-link handler are fork-branded. On a tag push the
`release` job attaches the .dmg / .zip / .exe / .msi / .deb / .tar.gz to the GitHub Release.
Branding assets
---------------
App icons live in apps/desktop/build/ and are HealthChat-branded, derived from
apps/web/res/vector-icons/1024.png:
- icon.png (Linux, 512x512)
- icon.ico (Windows, multi-resolution)
- icon.icon/ (macOS Apple Icon Composer bundle; Assets/healthchat.png + icon.json)
Regenerate after a logo change with ImageMagick:
magick apps/web/res/vector-icons/1024.png -resize 512x512 apps/desktop/build/icon.png
magick apps/web/res/vector-icons/1024.png -define icon:auto-resize=16,24,32,48,64,128,256 apps/desktop/build/icon.ico
cp apps/web/res/vector-icons/1024.png apps/desktop/build/icon.icon/Assets/healthchat.png
Signing (required for trusted installers)
-----------------------------------------
The macos/windows jobs run with sign: true, which gates on these GitHub environments. Create
them under repo Settings -> Environments with the listed secrets/variables:
Desktop Apple (macOS notarisation)
secrets: APPLE_ID Apple ID email of the signing account
APPLE_ID_PASSWORD app-specific password (NOT the Apple ID password)
APPLE_CSC_LINK base64 of the Developer ID Application .p12
APPLE_CSC_KEY_PASSWORD password for that .p12
variables: APPLE_TEAM_ID Apple Developer Team ID
Windows code-signing (SSL.com eSigner CKA)
The reusable signs via eSigner CKA and expects ESIGNER_USER_NAME / ESIGNER_USER_PASSWORD /
ESIGNER_USER_TOTP. The Novaloop org already provides CodeSignTool-style secrets under
different names (ESIGNER_USERNAME / ESIGNER_PASSWORD / ESIGNER_TOTP_SECRET); the windows job
in build-healthchat-desktop.yaml maps them. CKA does not use credential_id. These org secrets
are scoped to "private and internal repositories", so this fork must stay internal/private.
Set repo or org variable ESIGNER_MODE=prod for a trusted signature (defaults to the untrusted
sandbox demo cert).
Without these the jobs still build but produce unsigned/untrusted output. Because element-web is
a public-history fork, add environment/branch protection so only release/healthchat + healthchat-v*
runs can reach the signing credentials.
Open items
----------
- api_base_url: confirm the production API origin in config.json (currently assumed
https://healthchat.ch). On desktop this MUST be absolute (vector:// origin can't reach
a relative /api).
- App version: the desktop app version comes from apps/desktop/package.json (Windows squirrel
rewrites any `version` override into a nightly string), NOT the healthchat-v tag. Bump
apps/desktop/package.json in the release commit if you want the About dialog / installer
filenames to match the tag.
- Auto-update: not wired up. The apps install from the GitHub Release but do not self-update.
Adding it needs a hosted update feed (releases.json / RELEASES) on a stable URL.