mirror of
https://github.com/Novaloop-AG/healthchat-web.git
synced 2026-11-05 12:54:39 +00:00
feat(desktop): show what's changed in auto-update prompt
Publish HEALTHCHAT_CHANGES.md release notes into the update feeds so users see what changed. macOS gets them natively via releases.json's notes field; Windows fetches a published notes.txt, since Squirrel.Windows only delivers releaseName through the update-downloaded event.
This commit is contained in:
@@ -231,6 +231,12 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
steps:
|
steps:
|
||||||
|
# Needed so the staging step can read HEALTHCHAT_CHANGES.md to extract release notes.
|
||||||
|
# Lands at the workspace root; download-artifact below writes to dist-artifacts/, no conflict.
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Download all build artifacts
|
- name: Download all build artifacts
|
||||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||||
with:
|
with:
|
||||||
@@ -269,11 +275,36 @@ jobs:
|
|||||||
- name: Stage update feed + public installers
|
- name: Stage update feed + public installers
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
# --- Release notes: extract this version's section from HEALTHCHAT_CHANGES.md ---
|
||||||
|
# Same extraction as build-healthchat.yaml (web). Surfaced to desktop users in the
|
||||||
|
# auto-update "See changes" dialog: macOS reads it from releases.json's `notes`
|
||||||
|
# field natively, Windows fetches notes.txt (Squirrel.Windows can't carry notes
|
||||||
|
# through the update-downloaded event — only releaseName is available).
|
||||||
|
VERSION="${GITHUB_REF_NAME#healthchat-v}"
|
||||||
|
NOTES=$(awk -v ver="$VERSION" '
|
||||||
|
/^## Changes in / {
|
||||||
|
if (found) { exit }
|
||||||
|
if ($0 ~ "## Changes in " ver "( |$|\\()") { found = 1; next }
|
||||||
|
}
|
||||||
|
found { print }
|
||||||
|
' HEALTHCHAT_CHANGES.md | sed '/^[[:space:]]*$/{N;/^\n$/D;}')
|
||||||
|
if [[ -z "$NOTES" ]]; then
|
||||||
|
NOTES="HealthChat ${VERSION} — automated build from ${GITHUB_REF_NAME}."
|
||||||
|
echo "::warning::No HEALTHCHAT_CHANGES.md section found for $VERSION — using fallback"
|
||||||
|
fi
|
||||||
|
printf '%s\n' "$NOTES" > notes.txt
|
||||||
|
echo "--- release notes ---"; cat notes.txt
|
||||||
|
|
||||||
# --- macOS update feed: releases.json (Squirrel.Mac manifest) + signed *-mac.zip payload ---
|
# --- macOS update feed: releases.json (Squirrel.Mac manifest) + signed *-mac.zip payload ---
|
||||||
mkdir -p feed/update/macos feed/install/macos
|
mkdir -p feed/update/macos feed/install/macos
|
||||||
test -f dist-artifacts/macos/releases.json || {
|
test -f dist-artifacts/macos/releases.json || {
|
||||||
echo "::error::dist-artifacts/macos/releases.json missing (did the macos job get base-url?)"; exit 1; }
|
echo "::error::dist-artifacts/macos/releases.json missing (did the macos job get base-url?)"; exit 1; }
|
||||||
cp -v dist-artifacts/macos/releases.json feed/update/macos/
|
cp -v dist-artifacts/macos/releases.json feed/update/macos/
|
||||||
|
# Splice the notes into the manifest: Squirrel.Mac maps updateTo.notes -> the
|
||||||
|
# update-downloaded event's releaseNotes, which the renderer already renders.
|
||||||
|
jq --rawfile notes notes.txt '.releases[0].updateTo.notes = $notes' \
|
||||||
|
feed/update/macos/releases.json > feed/update/macos/releases.json.tmp
|
||||||
|
mv feed/update/macos/releases.json.tmp feed/update/macos/releases.json
|
||||||
find dist-artifacts/macos -type f -iname '*-mac.zip' -exec cp -v {} feed/update/macos/ \;
|
find dist-artifacts/macos -type f -iname '*-mac.zip' -exec cp -v {} feed/update/macos/ \;
|
||||||
# --- macOS installer: versioned .dmg + a stable "latest" copy ---
|
# --- macOS installer: versioned .dmg + a stable "latest" copy ---
|
||||||
find dist-artifacts/macos -type f -iname '*.dmg' -exec cp -v {} feed/install/macos/ \;
|
find dist-artifacts/macos -type f -iname '*.dmg' -exec cp -v {} feed/install/macos/ \;
|
||||||
@@ -284,6 +315,9 @@ jobs:
|
|||||||
src="dist-artifacts/win-$arch"
|
src="dist-artifacts/win-$arch"
|
||||||
[ -d "$src" ] || { echo "::error::$src missing"; exit 1; }
|
[ -d "$src" ] || { echo "::error::$src missing"; exit 1; }
|
||||||
mkdir -p "feed/update/win32/$arch" "feed/install/win32/$arch"
|
mkdir -p "feed/update/win32/$arch" "feed/install/win32/$arch"
|
||||||
|
# Side-channel for release notes: the desktop main process fetches this and
|
||||||
|
# populates releaseNotes itself, since Squirrel.Windows can't deliver them.
|
||||||
|
cp -v notes.txt "feed/update/win32/$arch/notes.txt"
|
||||||
find "$src" -type f -iname 'RELEASES' -exec cp -v {} "feed/update/win32/$arch/" \;
|
find "$src" -type f -iname 'RELEASES' -exec cp -v {} "feed/update/win32/$arch/" \;
|
||||||
find "$src" -type f -iname '*-full.nupkg' -exec cp -v {} "feed/update/win32/$arch/" \;
|
find "$src" -type f -iname '*-full.nupkg' -exec cp -v {} "feed/update/win32/$arch/" \;
|
||||||
find "$src" -type f -iname '* Setup*.exe' -exec cp -v {} "feed/install/win32/$arch/" \;
|
find "$src" -type f -iname '* Setup*.exe' -exec cp -v {} "feed/install/win32/$arch/" \;
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ export async function start(updateBaseUrl: string): Promise<void> {
|
|||||||
if (!updateBaseUrl.endsWith("/")) {
|
if (!updateBaseUrl.endsWith("/")) {
|
||||||
updateBaseUrl = updateBaseUrl + "/";
|
updateBaseUrl = updateBaseUrl + "/";
|
||||||
}
|
}
|
||||||
|
updateFeedBaseUrl = updateBaseUrl;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let url: string;
|
let url: string;
|
||||||
@@ -184,6 +185,27 @@ interface ICachedUpdate {
|
|||||||
updateURL: string;
|
updateURL: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The feed base URL passed to start(), retained so the update-downloaded handler can fetch
|
||||||
|
// release notes out-of-band on Windows (see below).
|
||||||
|
let updateFeedBaseUrl: string | undefined;
|
||||||
|
|
||||||
|
// On Windows the autoUpdater never provides release notes: "With Squirrel.Windows only
|
||||||
|
// releaseName is available" (https://www.electronjs.org/docs/latest/api/auto-updater). We
|
||||||
|
// publish a notes.txt alongside the per-arch Squirrel feed and fetch it here so the renderer's
|
||||||
|
// update toast can show "what's changed" the same way it does on macOS (where Squirrel.Mac
|
||||||
|
// carries the notes natively via releases.json).
|
||||||
|
async function fetchWindowsReleaseNotes(): Promise<string> {
|
||||||
|
if (process.platform !== "win32" || !updateFeedBaseUrl) return "";
|
||||||
|
try {
|
||||||
|
const res = await fetch(`${updateFeedBaseUrl}win32/${process.arch}/notes.txt`);
|
||||||
|
if (!res.ok) return "";
|
||||||
|
return await res.text();
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Couldn't fetch Windows release notes", err);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// cache the latest update which has been downloaded as electron offers no api to read it
|
// cache the latest update which has been downloaded as electron offers no api to read it
|
||||||
let latestUpdateDownloaded: ICachedUpdate | undefined;
|
let latestUpdateDownloaded: ICachedUpdate | undefined;
|
||||||
autoUpdater
|
autoUpdater
|
||||||
@@ -205,7 +227,13 @@ autoUpdater
|
|||||||
});
|
});
|
||||||
|
|
||||||
autoUpdater.on("update-downloaded", (ev, releaseNotes, releaseName, releaseDate, updateURL) => {
|
autoUpdater.on("update-downloaded", (ev, releaseNotes, releaseName, releaseDate, updateURL) => {
|
||||||
// forward to renderer
|
void (async (): Promise<void> => {
|
||||||
latestUpdateDownloaded = { releaseNotes, releaseName, releaseDate, updateURL };
|
// Windows delivers no release notes via the event, so fetch them out-of-band.
|
||||||
global.mainWindow?.webContents.send("update-downloaded", latestUpdateDownloaded);
|
if (!releaseNotes) {
|
||||||
|
releaseNotes = await fetchWindowsReleaseNotes();
|
||||||
|
}
|
||||||
|
// forward to renderer
|
||||||
|
latestUpdateDownloaded = { releaseNotes, releaseName, releaseDate, updateURL };
|
||||||
|
global.mainWindow?.webContents.send("update-downloaded", latestUpdateDownloaded);
|
||||||
|
})();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user