Update now: download, verify and install a release in one click (#1118)

Where SolidCraft can replace itself safely, the Update window gets Update now:
- AppImage: the new AppImage is downloaded next to the old one, verified and renamed over
  it; Restart now starts it as SolidCraft exits.
- Windows MSI: the verified .msi starts (msiexec /i … /passive) once SolidCraft has closed,
  after the usual questions about unsaved designs.
- Windows portable zip / standalone exe: the running solidcraft.exe is renamed to .old, the
  new one takes its name (solidcraft-cli.exe too), Restart now; .old goes at the next start.
- macOS: the verified .dmg is opened (the app is ad-hoc signed and not notarized, so it isn't
  replaced behind the user's back).
- Flatpak, Snap, deb, rpm, tar.gz: never replaced; the window shows the command.

Every package's SHA-256 must match the release's SHA256SUMS.txt (HTTPS, same release); a
mismatch deletes the download and changes nothing. With PUBLIC_KEY set in update/install.rs,
SHA256SUMS.txt.minisig must also verify (minisign-verify, MIT) with a trusted comment naming
the release. release.yml signs the list when the UPDATE_SIGNING_KEY secret exists and fails
when the app expects signatures but the secret is missing; docs/releasing.md has the steps.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
bherbruckandClaude Opus 5.5 authored and GitHub committed 2026-10-14 11:05:40 -04:00
1 parent a8258eb63a
commit d4a7b3abf3
16 files changed
+966 -12

No files matched your search

+26
View File
@@ -429,6 +429,32 @@ jobs:
run: |
(cd artifacts && sha256sum -- * | tee SHA256SUMS.txt)
sed "s/{version}/$VERSION/g" .github/release-notes.md >notes.md
- name: Sign the checksum list for in-app updates
# Optional until the UPDATE_SIGNING_KEY secret exists (docs/releasing.md, "Update
# signing"). The trusted comment names the release, which the app checks.
env:
UPDATE_SIGNING_KEY: ${{ secrets.UPDATE_SIGNING_KEY }}
run: |
# The key the app checks against (crates/ui-egui/src/update/install.rs, PUBLIC_KEY).
public_key=$(sed -n 's/^pub const PUBLIC_KEY: Option<&str> = Some("\([^"]*\)");/\1/p' crates/ui-egui/src/update/install.rs)
if [ -z "$UPDATE_SIGNING_KEY" ]; then
if [ -n "$public_key" ]; then
echo "::error::the app expects signed updates (PUBLIC_KEY is set) but the UPDATE_SIGNING_KEY secret is missing"
exit 1
fi
echo "UPDATE_SIGNING_KEY isn't set: SHA256SUMS.txt stays unsigned"
exit 0
fi
sudo apt-get update -q
sudo apt-get install -y --no-install-recommends minisign
umask 077
printf '%s\n' "$UPDATE_SIGNING_KEY" >"$RUNNER_TEMP/update.key"
minisign -S -s "$RUNNER_TEMP/update.key" -m artifacts/SHA256SUMS.txt \
-x artifacts/SHA256SUMS.txt.minisig -t "SolidCraft v$VERSION" </dev/null
rm -f "$RUNNER_TEMP/update.key"
if [ -n "$public_key" ]; then
minisign -V -P "$public_key" -m artifacts/SHA256SUMS.txt -x artifacts/SHA256SUMS.txt.minisig
fi
- name: Publish nightly pre-release
if: github.event_name == 'schedule'
working-directory: artifacts