mirror of
https://github.com/Novaloop-AG/healthchat-web.git
synced 2026-11-07 15:08:24 +00:00
ci: link desktop installers instead of attaching them
This commit is contained in:
@@ -19,16 +19,19 @@ Releases are driven by git tags of the form `healthchat-v<semver>` pushed to
|
|||||||
`:<sha>`, so you can deploy them deliberately by overriding the image ref (see
|
`:<sha>`, so you can deploy them deliberately by overriding the image ref (see
|
||||||
"Deploying the release"), but they can never become production by accident.
|
"Deploying the release"), but they can never become production by accident.
|
||||||
- `.github/workflows/build-healthchat-desktop.yaml` (desktop) — builds the Electron
|
- `.github/workflows/build-healthchat-desktop.yaml` (desktop) — builds the Electron
|
||||||
app for macOS (universal, signed+notarised) and Windows (x64/arm64, signed), and
|
app for macOS (universal, signed+notarised) and Windows (x64/arm64, signed) and
|
||||||
attaches the installers (.dmg/.zip/.exe/.msi) to the **same** GitHub Release. The two
|
publishes to the **same** GitHub Release as the web workflow (both create-if-missing,
|
||||||
workflows create-if-missing then upload, so they race safely. (Linux is intentionally
|
so they race safely). (Linux is intentionally not built — the upstream Linux reusable
|
||||||
not built — the upstream Linux reusable pulls a build-env Docker image keyed by commit
|
pulls a build-env Docker image keyed by commit SHA that only exists in the upstream
|
||||||
SHA that only exists in the upstream element-hq registry, so it cannot succeed in this
|
element-hq registry, so it cannot succeed in this fork.) The `release` job **stages**
|
||||||
fork.) The `release` job also **stages** the Squirrel update feed and public installers and
|
the Squirrel update feed and public installers and attaches them to the Release as
|
||||||
attaches them to the Release as `healthchat-desktop-feed-<version>.tar.gz` — but it
|
split `healthchat-desktop-feed-<version>.tar.gz.part*` assets (the compressed feed
|
||||||
**does not publish them**. See "Deploying the desktop release" below.
|
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.
|
||||||
- `.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 and reassembles those feed parts and mirrors the feed to
|
||||||
`https://packages.healthchat.ch/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), plus the legacy
|
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
|
`https://healthchat.ch/packages/desktop/` path while clients built <= 1.5.0 are still
|
||||||
@@ -37,8 +40,8 @@ Releases are driven by git tags of the form `healthchat-v<semver>` pushed to
|
|||||||
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).
|
||||||
|
|
||||||
Publish target: **ghcr.io Docker image + GitHub Release (web bundle + desktop
|
Publish target: **ghcr.io Docker image + GitHub Release (web bundle + desktop feed
|
||||||
installers).** No npm, no mobile fan-out.
|
parts, with installer download links).** No npm, no mobile fan-out.
|
||||||
|
|
||||||
## Release ≠ deploy
|
## Release ≠ deploy
|
||||||
|
|
||||||
@@ -186,7 +189,8 @@ 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 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
|
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.
|
||||||
@@ -319,9 +323,10 @@ warning. Prefer fixing the changelog over relying on the fallback.
|
|||||||
For an `-rc`/`-hotfix`/`-dryrun` tag the opposite is expected: `:latest` must
|
For an `-rc`/`-hotfix`/`-dryrun` tag the opposite is expected: `:latest` must
|
||||||
be **unchanged**.
|
be **unchanged**.
|
||||||
- [ ] The desktop workflow run ("Build HealthChat Desktop") is green and the
|
- [ ] The desktop workflow run ("Build HealthChat Desktop") is green and the
|
||||||
GitHub Release has the desktop installers attached (.dmg, *-mac.zip, *.msi,
|
GitHub Release carries the split feed assets
|
||||||
"* Setup*.exe") **plus** `healthchat-desktop-feed-<version>.tar.gz`. Without that
|
`healthchat-desktop-feed-<version>.tar.gz.part*` plus a "## Downloads" section
|
||||||
tarball the desktop deploy has nothing to publish.
|
in its notes linking the public installers. Without those parts 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://packages.healthchat.ch/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>`
|
||||||
|
|||||||
@@ -10,10 +10,11 @@ name: Build HealthChat Desktop
|
|||||||
# (via `webapp-artifact`) and the per-platform build_desktop_{macos,windows}.yaml reusables.
|
# (via `webapp-artifact`) and the per-platform build_desktop_{macos,windows}.yaml reusables.
|
||||||
#
|
#
|
||||||
# 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 a staged update-feed tarball (split
|
||||||
# tarball to the GitHub Release; the live auto-update feed at packages.healthchat.ch/desktop/ is
|
# into <2 GiB parts) to the GitHub Release and links the public installer URLs in the Release
|
||||||
# only touched by the manually dispatched deploy-healthchat-desktop.yaml. So cutting a tag never
|
# notes; the live auto-update feed at packages.healthchat.ch/desktop/ is only touched by the
|
||||||
# pushes an update to already-installed apps until a human decides to ship it.
|
# 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.
|
||||||
# - 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
|
||||||
# shell, icons (apps/desktop/build/icon.*) and the healthchat:// deep-link handler
|
# shell, icons (apps/desktop/build/icon.*) and the healthchat:// deep-link handler
|
||||||
# (apps/desktop/src/protocol.ts) are all fork-branded. Branding values come from
|
# (apps/desktop/src/protocol.ts) are all fork-branded. Branding values come from
|
||||||
@@ -246,19 +247,12 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
path: dist-artifacts
|
path: dist-artifacts
|
||||||
|
|
||||||
- name: Collect installers
|
# Installers are NOT attached to the Release: they ship inside the feed tarball and are
|
||||||
run: |
|
# served from packages.healthchat.ch after the deploy — the Release body links to them
|
||||||
set -euo pipefail
|
# there (see "Link public downloads in the Release notes" below). Attaching them here
|
||||||
mkdir -p release-files
|
# would duplicate ~1 GiB per release and the x64/arm64 Setup.exe share a filename, so
|
||||||
# macOS: .dmg installer + .zip (Squirrel.Mac update payload)
|
# they'd clobber each other as flat Release assets anyway.
|
||||||
find dist-artifacts -type f \( -iname '*.dmg' -o -iname '*-mac.zip' \) -exec cp -v {} release-files/ \;
|
- name: Ensure GitHub Release exists
|
||||||
# Windows: per-machine MSI + Squirrel "Setup" installer
|
|
||||||
find dist-artifacts -type f \( -iname '*.msi' -o -iname '* Setup*.exe' \) -exec cp -v {} release-files/ \;
|
|
||||||
echo "--- release files ---"
|
|
||||||
ls -la release-files
|
|
||||||
test -n "$(ls -A release-files)" || { echo "::error::No installer files collected"; exit 1; }
|
|
||||||
|
|
||||||
- name: Upload to GitHub Release
|
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ github.token }}
|
GH_TOKEN: ${{ github.token }}
|
||||||
GH_REPO: ${{ github.repository }}
|
GH_REPO: ${{ github.repository }}
|
||||||
@@ -266,11 +260,10 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
# The web workflow (build-healthchat.yaml) also creates this release for the same tag.
|
# The web workflow (build-healthchat.yaml) also creates this release for the same tag.
|
||||||
# Create-if-missing (without touching existing notes) then upload --clobber so the two
|
# Create-if-missing (without touching existing notes) so the two workflows race
|
||||||
# workflows race safely regardless of ordering.
|
# safely regardless of ordering.
|
||||||
gh release view "$TAG" >/dev/null 2>&1 || \
|
gh release view "$TAG" >/dev/null 2>&1 || \
|
||||||
gh release create "$TAG" --title "$TAG" --notes "HealthChat desktop installers for $TAG"
|
gh release create "$TAG" --title "$TAG" --notes "HealthChat $TAG"
|
||||||
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 packages.healthchat.ch/desktop/, which is
|
# Squirrel auto-updater. Those are served from packages.healthchat.ch/desktop/, which is
|
||||||
@@ -356,3 +349,38 @@ jobs:
|
|||||||
ls -lh "${TARBALL}".part*
|
ls -lh "${TARBALL}".part*
|
||||||
gh release upload "$TAG" "${TARBALL}".part* --clobber
|
gh release upload "$TAG" "${TARBALL}".part* --clobber
|
||||||
echo "::notice::Update feed attached as ${TARBALL}.part*. The live feed at packages.healthchat.ch is UNCHANGED — run the 'Deploy HealthChat Desktop' workflow to publish it."
|
echo "::notice::Update feed attached as ${TARBALL}.part*. The live feed at packages.healthchat.ch is UNCHANGED — run the 'Deploy HealthChat Desktop' workflow to publish it."
|
||||||
|
|
||||||
|
# The Release carries no installer binaries (see "Ensure GitHub Release exists"), so
|
||||||
|
# point readers at the public download URLs instead. The links are derived from the
|
||||||
|
# staged feed/install tree, so they stay correct if electron-builder ever renames the
|
||||||
|
# artifacts. They resolve once "Deploy HealthChat Desktop" has published this version.
|
||||||
|
- name: Link public downloads in the Release notes
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
GH_REPO: ${{ github.repository }}
|
||||||
|
TAG: ${{ github.ref_name }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
BASE="https://packages.healthchat.ch/desktop"
|
||||||
|
BODY=$(gh release view "$TAG" --json body --jq .body)
|
||||||
|
if [[ "$BODY" == *"## Downloads"* ]]; then
|
||||||
|
echo "Release notes already carry a Downloads section — leaving them untouched."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
{
|
||||||
|
printf '%s\n\n' "$BODY"
|
||||||
|
echo "## Downloads"
|
||||||
|
echo ""
|
||||||
|
echo "Public installers, live once this version is deployed via \"Deploy HealthChat Desktop\":"
|
||||||
|
echo ""
|
||||||
|
for f in feed/install/macos/* feed/install/win32/x64/* feed/install/win32/arm64/*; do
|
||||||
|
name=$(basename "$f")
|
||||||
|
# Skip the stable "latest" aliases — they track whatever is deployed, not this version.
|
||||||
|
case "$name" in HealthChat.dmg|HealthChat-Setup.exe) continue ;; esac
|
||||||
|
dir=$(dirname "${f#feed/}")
|
||||||
|
enc=$(jq -rn --arg s "$name" '$s|@uri')
|
||||||
|
echo "- [$name]($BASE/$dir/$enc)"
|
||||||
|
done
|
||||||
|
} > release-body.md
|
||||||
|
gh release edit "$TAG" --notes-file release-body.md
|
||||||
|
echo "::notice::Release notes now link the public installers under $BASE/install/."
|
||||||
|
|||||||
@@ -49,7 +49,9 @@ feeds it into build_desktop_prepare.yaml (`config: element.io/healthchat`,
|
|||||||
reusables. It runs on every `healthchat-v*` tag (alongside the web build) and via
|
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
|
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
|
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 to the GitHub Release.
|
`release` job attaches the staged update feed as split healthchat-desktop-feed-<ver>.tar.gz.part*
|
||||||
|
assets (the compressed feed exceeds GitHub's 2 GiB per-asset cap) and links the public installer
|
||||||
|
URLs on packages.healthchat.ch in the Release notes — installer binaries are not attached.
|
||||||
(Linux is not built: the upstream build_desktop_linux.yaml needs a build-env Docker image
|
(Linux is not built: the upstream build_desktop_linux.yaml needs a build-env Docker image
|
||||||
keyed by commit SHA that only exists in the upstream element-hq registry, so it can't run here.)
|
keyed by commit SHA that only exists in the upstream element-hq registry, so it can't run here.)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user