mirror of
https://github.com/Novaloop-AG/healthchat-web.git
synced 2026-11-04 19:10:51 +00:00
chore: move desktop packages to packages.healthchat.ch
This commit is contained in:
@@ -29,8 +29,10 @@ Releases are driven by git tags of the form `healthchat-v<semver>` pushed to
|
|||||||
**does not publish them**. See "Deploying the desktop release" below.
|
**does not publish them**. See "Deploying the desktop release" below.
|
||||||
- `.github/workflows/deploy-healthchat-desktop.yaml` (desktop deploy) — **manual
|
- `.github/workflows/deploy-healthchat-desktop.yaml` (desktop deploy) — **manual
|
||||||
dispatch only.** Downloads that tarball and mirrors it to
|
dispatch only.** Downloads that tarball and mirrors it to
|
||||||
`https://healthchat.ch/packages/desktop/` over FTPS (the private GitHub Release can
|
`https://packages.healthchat.ch/desktop/` over FTPS (the private GitHub Release can
|
||||||
serve neither end users nor the auto-updater). This is what makes installed apps
|
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
|
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,
|
the two caveats (first install is manual; Windows auto-update needs the Setup.exe path,
|
||||||
not the .msi).
|
not the .msi).
|
||||||
@@ -185,7 +187,7 @@ run or `:latest` had not moved yet.
|
|||||||
## Deploying the desktop release
|
## Deploying the desktop release
|
||||||
|
|
||||||
The desktop build attaches `healthchat-desktop-feed-<version>.tar.gz` to the Release but
|
The desktop build attaches `healthchat-desktop-feed-<version>.tar.gz` to the Release but
|
||||||
leaves `https://healthchat.ch/packages/desktop/` untouched. Until you run this, installed
|
leaves `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
|
apps keep whatever version they have and the public download links still serve the old
|
||||||
installers.
|
installers.
|
||||||
|
|
||||||
@@ -321,7 +323,7 @@ warning. Prefer fixing the changelog over relying on the fallback.
|
|||||||
"* Setup*.exe") **plus** `healthchat-desktop-feed-<version>.tar.gz`. Without that
|
"* Setup*.exe") **plus** `healthchat-desktop-feed-<version>.tar.gz`. Without that
|
||||||
tarball the desktop deploy has nothing to publish.
|
tarball the desktop deploy has nothing to publish.
|
||||||
- [ ] Confirm the live feed is still on the **previous** version — releasing must not have
|
- [ ] Confirm the live feed is still on the **previous** version — releasing must not have
|
||||||
moved it. `curl -fsS https://healthchat.ch/packages/desktop/update/macos/releases.json`
|
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>`
|
- [ ] Smoke-check signing before shipping to users: macOS `spctl -a -vvv -t install <app>`
|
||||||
is accepted; Windows installer shows a valid publisher (no SmartScreen block).
|
is accepted; Windows installer shows a valid publisher (no SmartScreen block).
|
||||||
|
|
||||||
@@ -332,9 +334,10 @@ release"):
|
|||||||
|
|
||||||
- [ ] Web deployed and `curl -fsS https://app.healthchat.ch/version` reports the new version.
|
- [ ] Web deployed and `curl -fsS https://app.healthchat.ch/version` reports the new version.
|
||||||
- [ ] Desktop feed deployed: the "Deploy HealthChat Desktop" run is green. Its own verify
|
- [ ] Desktop feed deployed: the "Deploy HealthChat Desktop" run is green. Its own verify
|
||||||
step already asserts the five feed URLs return 200, so a green run is the check.
|
step already asserts the feed URLs (canonical + legacy) return 200, so a green run is
|
||||||
|
the check.
|
||||||
- [ ] `releases.json` now advertises the new version:
|
- [ ] `releases.json` now advertises the new version:
|
||||||
`curl -fsS https://healthchat.ch/packages/desktop/update/macos/releases.json | jq -r '.releases[0].updateTo.version'`
|
`curl -fsS https://packages.healthchat.ch/desktop/update/macos/releases.json | jq -r '.releases[0].updateTo.version'`
|
||||||
- [ ] Spot-check auto-update on a real installed client (or at least confirm the app's
|
- [ ] Spot-check auto-update on a real installed client (or at least confirm the app's
|
||||||
update check reaches the feed) before announcing.
|
update check reaches the feed) before announcing.
|
||||||
|
|
||||||
@@ -346,7 +349,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. |
|
| `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. |
|
| `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/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. 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. |
|
||||||
|
|
||||||
Desktop signing additionally requires two GitHub **environments** (Settings →
|
Desktop signing additionally requires two GitHub **environments** (Settings →
|
||||||
Environments). Without them the desktop builds still run but produce
|
Environments). Without them the desktop builds still run but produce
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ name: Build HealthChat Desktop
|
|||||||
#
|
#
|
||||||
# Notes:
|
# Notes:
|
||||||
# - This workflow RELEASES but does not DEPLOY. It attaches the installers and a staged update-feed
|
# - This workflow RELEASES but does not DEPLOY. It attaches the installers and a staged update-feed
|
||||||
# tarball to the GitHub Release; the live auto-update feed at healthchat.ch/packages/desktop/ is
|
# tarball to the GitHub Release; the live auto-update feed at packages.healthchat.ch/desktop/ is
|
||||||
# only touched by the manually dispatched deploy-healthchat-desktop.yaml. So cutting a tag never
|
# only touched by the manually dispatched deploy-healthchat-desktop.yaml. So cutting a tag never
|
||||||
# pushes an update to already-installed apps until a human decides to ship it.
|
# pushes an update to already-installed apps until a human decides to ship it.
|
||||||
# - The reusable build workflows are pointed at THIS fork (repository/ref inputs) so the Electron
|
# - The reusable build workflows are pointed at THIS fork (repository/ref inputs) so the Electron
|
||||||
@@ -195,10 +195,10 @@ jobs:
|
|||||||
targets: "dmg zip"
|
targets: "dmg zip"
|
||||||
# Generates dist/releases.json (the Squirrel.Mac feed manifest). The reusable appends
|
# Generates dist/releases.json (the Squirrel.Mac feed manifest). The reusable appends
|
||||||
# `/update/macos/<zip>` to this, so the in-manifest URL becomes
|
# `/update/macos/<zip>` to this, so the in-manifest URL becomes
|
||||||
# https://healthchat.ch/packages/desktop/update/macos/<zip>, matching where the
|
# https://packages.healthchat.ch/desktop/update/macos/<zip>, matching where the
|
||||||
# `release` job publishes the feed. Keep in sync with update_base_url in
|
# `release` job publishes the feed. Keep in sync with update_base_url in
|
||||||
# element.io/healthchat/config.json (.../packages/desktop/update/).
|
# element.io/healthchat/config.json (.../desktop/update/).
|
||||||
base-url: https://healthchat.ch/packages/desktop
|
base-url: https://packages.healthchat.ch/desktop
|
||||||
|
|
||||||
windows:
|
windows:
|
||||||
name: Windows ${{ matrix.arch }}
|
name: Windows ${{ matrix.arch }}
|
||||||
@@ -273,7 +273,7 @@ jobs:
|
|||||||
gh release upload "$TAG" release-files/* --clobber
|
gh release upload "$TAG" release-files/* --clobber
|
||||||
|
|
||||||
# The GitHub Release above is private (internal fork), so it can't serve end users or the
|
# The GitHub Release above is private (internal fork), so it can't serve end users or the
|
||||||
# Squirrel auto-updater. Those are served from healthchat.ch/packages/desktop/, which is
|
# Squirrel auto-updater. Those are served from packages.healthchat.ch/desktop/, which is
|
||||||
# published by the SEPARATE, MANUALLY DISPATCHED "Deploy HealthChat Desktop" workflow
|
# published by the SEPARATE, MANUALLY DISPATCHED "Deploy HealthChat Desktop" workflow
|
||||||
# (deploy-healthchat-desktop.yaml) — releasing never touches the live update feed.
|
# (deploy-healthchat-desktop.yaml) — releasing never touches the live update feed.
|
||||||
# This job only *stages* that feed and attaches it to the Release as a tarball, so the
|
# This job only *stages* that feed and attaches it to the Release as a tarball, so the
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
name: Deploy HealthChat Desktop
|
name: Deploy HealthChat Desktop
|
||||||
|
|
||||||
# Publishes an already-released desktop build to healthchat.ch/packages/desktop/ over FTPS.
|
# Publishes an already-released desktop build to packages.healthchat.ch/desktop/ over FTPS.
|
||||||
#
|
#
|
||||||
# This is the DEPLOY half of the desktop pipeline, deliberately split from the release half
|
# This is the DEPLOY half of the desktop pipeline, deliberately split from the release half
|
||||||
# (build-healthchat-desktop.yaml). Cutting a `healthchat-v*` tag builds, signs and attaches the
|
# (build-healthchat-desktop.yaml). Cutting a `healthchat-v*` tag builds, signs and attaches the
|
||||||
# installers plus a staged update-feed tarball to the GitHub Release, but never touches the live
|
# installers plus a staged update-feed tarball to the GitHub Release, but never touches the live
|
||||||
# feed. Nothing reaches installed apps until this workflow is dispatched by hand.
|
# feed. Nothing reaches installed apps until this workflow is dispatched by hand.
|
||||||
#
|
#
|
||||||
# Why that split matters: the feed under .../packages/desktop/update/ is what the Squirrel
|
# Why that split matters: the feed under .../desktop/update/ is what the Squirrel
|
||||||
# auto-updater polls. Writing to it pushes an update to every installed client, so it is a
|
# auto-updater polls. Writing to it pushes an update to every installed client, so it is a
|
||||||
# deployment, not a publication step — the same reason the ansible playbook's deploy is a manual
|
# deployment, not a publication step — the same reason the ansible playbook's deploy is a manual
|
||||||
# dispatch rather than a release trigger.
|
# dispatch rather than a release trigger.
|
||||||
@@ -38,7 +38,7 @@ concurrency:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy:
|
deploy:
|
||||||
name: Publish update feed to healthchat.ch
|
name: Publish update feed to packages.healthchat.ch
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 30
|
timeout-minutes: 30
|
||||||
steps:
|
steps:
|
||||||
@@ -126,11 +126,21 @@ jobs:
|
|||||||
# *.nupkg are preserved (Squirrel.Windows delta history) and only the staged files
|
# *.nupkg are preserved (Squirrel.Windows delta history) and only the staged files
|
||||||
# are written/overwritten. If the host's FTPS cert is untrusted, set
|
# are written/overwritten. If the host's FTPS cert is untrusted, set
|
||||||
# ssl:verify-certificate to no.
|
# ssl:verify-certificate to no.
|
||||||
|
#
|
||||||
|
# Dual-publish during the URL migration: /public_html/packages is the docroot of
|
||||||
|
# packages.healthchat.ch (the canonical feed URL since builds > 1.5.0), while
|
||||||
|
# /public_html/healthchat.ch/packages/desktop serves the legacy
|
||||||
|
# healthchat.ch/packages/desktop URL that clients built <= 1.5.0 still poll —
|
||||||
|
# they only learn the new URL by installing an update delivered over the old
|
||||||
|
# feed. Drop the legacy mirror (and its verify checks below) once the installed
|
||||||
|
# base is on a build carrying the new update_base_url.
|
||||||
lftp -u "$FTP_USERNAME" --env-password "$FTP_SERVER" <<LFTP
|
lftp -u "$FTP_USERNAME" --env-password "$FTP_SERVER" <<LFTP
|
||||||
set cmd:fail-exit true
|
set cmd:fail-exit true
|
||||||
set ftp:ssl-force true
|
set ftp:ssl-force true
|
||||||
set ftp:ssl-protect-data true
|
set ftp:ssl-protect-data true
|
||||||
set ssl:verify-certificate true
|
set ssl:verify-certificate true
|
||||||
|
mkdir -pf /public_html/packages/desktop
|
||||||
|
mirror -R $MIRROR_OPTS feed/ /public_html/packages/desktop/
|
||||||
mkdir -pf /public_html/healthchat.ch/packages/desktop
|
mkdir -pf /public_html/healthchat.ch/packages/desktop
|
||||||
mirror -R $MIRROR_OPTS feed/ /public_html/healthchat.ch/packages/desktop/
|
mirror -R $MIRROR_OPTS feed/ /public_html/healthchat.ch/packages/desktop/
|
||||||
bye
|
bye
|
||||||
@@ -140,13 +150,19 @@ jobs:
|
|||||||
if: ${{ !inputs.dry_run }}
|
if: ${{ !inputs.dry_run }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
base="https://healthchat.ch/packages/desktop"
|
base="https://packages.healthchat.ch/desktop"
|
||||||
|
# The legacy healthchat.ch URLs keep clients built <= 1.5.0 updating; drop them
|
||||||
|
# together with the legacy mirror above once the installed base has migrated.
|
||||||
|
legacy="https://healthchat.ch/packages/desktop"
|
||||||
fail=0
|
fail=0
|
||||||
for url in "$base/update/macos/releases.json" \
|
for url in "$base/update/macos/releases.json" \
|
||||||
"$base/update/win32/x64/RELEASES" \
|
"$base/update/win32/x64/RELEASES" \
|
||||||
"$base/update/win32/arm64/RELEASES" \
|
"$base/update/win32/arm64/RELEASES" \
|
||||||
"$base/install/macos/HealthChat.dmg" \
|
"$base/install/macos/HealthChat.dmg" \
|
||||||
"$base/install/win32/x64/HealthChat-Setup.exe"; do
|
"$base/install/win32/x64/HealthChat-Setup.exe" \
|
||||||
|
"$legacy/update/macos/releases.json" \
|
||||||
|
"$legacy/update/win32/x64/RELEASES" \
|
||||||
|
"$legacy/update/win32/arm64/RELEASES"; do
|
||||||
code=$(curl -fsS -o /dev/null -w '%{http_code}' -I "$url" 2>/dev/null || echo "000")
|
code=$(curl -fsS -o /dev/null -w '%{http_code}' -I "$url" 2>/dev/null || echo "000")
|
||||||
if [[ "$code" == "200" ]]; then echo "ok $code $url"; else echo "FAIL $code $url"; fail=1; fi
|
if [[ "$code" == "200" ]]; then echo "ok $code $url"; else echo "FAIL $code $url"; fail=1; fi
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -98,14 +98,14 @@ runs can reach the signing credentials.
|
|||||||
|
|
||||||
Auto-update + public installer hosting
|
Auto-update + public installer hosting
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
The apps self-update over a feed hosted on healthchat.ch (the GitHub Release is private to this
|
The apps self-update over a feed hosted on packages.healthchat.ch (the GitHub Release is private
|
||||||
internal fork, so it can serve neither end users nor the Squirrel auto-updater). Both the update
|
to this internal fork, so it can serve neither end users nor the Squirrel auto-updater). Both the
|
||||||
feed and the public installers live under https://healthchat.ch/packages/desktop/ (FTP web root
|
update feed and the public installers live under https://packages.healthchat.ch/desktop/ (the
|
||||||
/public_html/healthchat.ch maps to https://healthchat.ch/; no packages. subdomain, so it's a path):
|
subdomain's docroot on the healthchat.ch FTP account is /public_html/packages):
|
||||||
|
|
||||||
update/ the Squirrel feed the installed apps poll hourly. config.json sets
|
update/ the Squirrel feed the installed apps poll hourly. config.json sets
|
||||||
"update_base_url": "https://healthchat.ch/packages/desktop/update/"
|
"update_base_url": "https://packages.healthchat.ch/desktop/update/"
|
||||||
and the macos job passes base-url: https://healthchat.ch/packages/desktop so the
|
and the macos job passes base-url: https://packages.healthchat.ch/desktop so the
|
||||||
generated releases.json points the *-mac.zip at this origin.
|
generated releases.json points the *-mac.zip at this origin.
|
||||||
update/macos/releases.json + HealthChat-<ver>-mac.zip (Squirrel.Mac)
|
update/macos/releases.json + HealthChat-<ver>-mac.zip (Squirrel.Mac)
|
||||||
update/win32/<arch>/RELEASES + HealthChat-<ver>-full.nupkg (Squirrel.Windows; x64 + arm64)
|
update/win32/<arch>/RELEASES + HealthChat-<ver>-full.nupkg (Squirrel.Windows; x64 + arm64)
|
||||||
@@ -113,14 +113,20 @@ feed and the public installers live under https://healthchat.ch/packages/desktop
|
|||||||
install/macos/HealthChat-<ver>.dmg + HealthChat.dmg (stable "latest")
|
install/macos/HealthChat-<ver>.dmg + HealthChat.dmg (stable "latest")
|
||||||
install/win32/<arch>/HealthChat-Setup-<ver>.exe + HealthChat-Setup.exe (stable) + *.msi
|
install/win32/<arch>/HealthChat-Setup-<ver>.exe + HealthChat-Setup.exe (stable) + *.msi
|
||||||
|
|
||||||
The `release` job in build-healthchat-desktop.yaml stages these trees and uploads them via lftp/FTPS
|
The `release` job in build-healthchat-desktop.yaml stages these trees; the manually dispatched
|
||||||
(mirror -R, no-delete so prior nupkgs survive for delta history). Add these repo secrets:
|
deploy-healthchat-desktop.yaml uploads them via lftp/FTPS (mirror -R, no-delete so prior nupkgs
|
||||||
|
survive for delta history). Add these repo secrets:
|
||||||
FTP_SERVER hostname only (explicit FTPS / AUTH TLS on port 21; if the host cert is untrusted,
|
FTP_SERVER hostname only (explicit FTPS / AUTH TLS on port 21; if the host cert is untrusted,
|
||||||
flip ssl:verify-certificate to no in the workflow)
|
flip ssl:verify-certificate to no in the workflow)
|
||||||
FTP_USERNAME
|
FTP_USERNAME
|
||||||
FTP_PASSWORD
|
FTP_PASSWORD
|
||||||
|
|
||||||
Caveats:
|
Caveats:
|
||||||
|
- URL migration: builds <= 1.5.0 poll the legacy feed at
|
||||||
|
https://healthchat.ch/packages/desktop/ (docroot /public_html/healthchat.ch/packages/) —
|
||||||
|
they only learn the new URL by installing an update delivered over that old feed. The
|
||||||
|
deploy workflow therefore dual-publishes to both directories; drop the legacy mirror and
|
||||||
|
its verify checks once the installed base is on a build carrying the new update_base_url.
|
||||||
- First install is manual. Apps already installed without update_base_url (<= 1.1.2) cannot
|
- First install is manual. Apps already installed without update_base_url (<= 1.1.2) cannot
|
||||||
self-update to the first build that carries it; users must download once from the install/ URL.
|
self-update to the first build that carries it; users must download once from the install/ URL.
|
||||||
Every release after that updates automatically.
|
Every release after that updates automatically.
|
||||||
|
|||||||
@@ -88,7 +88,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"show_labs_settings": false,
|
"show_labs_settings": false,
|
||||||
"update_base_url": "https://healthchat.ch/packages/desktop/update/",
|
"update_base_url": "https://packages.healthchat.ch/desktop/update/",
|
||||||
"modules": ["/modules/healthchat-module.js"],
|
"modules": ["/modules/healthchat-module.js"],
|
||||||
"ch.healthchat": { "api_base_url": "https://api.healthchat.ch", "elements_base_url": "/webapp/modules/elements" }
|
"ch.healthchat": { "api_base_url": "https://api.healthchat.ch", "elements_base_url": "/webapp/modules/elements" }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user