Auto-update pipeline: in-process self-updater + workflow maintains latest.txt#8
Conversation
Replaces the rex706/Updater external-binary update path with an in-process self-updater so newer releases land on running installs without manual intervention. - Core/SelfUpdater.cs: downloads the release SAM.exe alongside the current binary as SAM.exe.new, validates it is >=4 MB (matching the Costura embedding threshold the release workflow already enforces), writes a one-shot cmd script to %TEMP% that waits for the current PID to exit, atomically moves the new EXE over the old, relaunches SAM.exe and deletes itself. info.dat / samsettings.ini / .sambackup are untouched because only SAM.exe is replaced. - Core/UpdateHelper: latest.txt is now read as 2 lines (version + direct download URL). CheckForUpdate also exposes latestDownloadUrl so StartUpdate doesn't have to re-fetch. StartUpdate now defers to SelfUpdater and falls back to opening the releases page if the download URL is missing or the self-update throws. Update-available prompt now explicitly says info.dat and samsettings.ini are preserved. - AccountsWindow: updateCheckUrl / repositoryUrl now point at matisseduffield/SAM (was rex706/SAM, which would never serve this fork's releases). UpdateResponse.Update path no longer detours through the legacy "PRIVATE_KEY rebuild yourself" warning — the self-updater preserves data regardless of whether the user has a DPAPI-sealed key or the legacy build-time constant, since both old and new builds resolve eKey identically. - latest.txt: rewritten in the new 2-line format pointing at this fork's release URL pattern. The placeholder version (26727) gets overwritten by the workflow on the next tag push. - .github/workflows/release.yml: after creating the GitHub Release, checks out master, rewrites latest.txt with the freshly-tagged version + matching SAM.exe asset URL, and pushes back with "[skip ci]" to avoid re-triggering. Wrapped in continue-on-error so a transient git failure can't fail an otherwise-successful release.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4854029845
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return; | ||
| } | ||
|
|
||
| await UpdateHelper.StartUpdate(updateCheckUrl, releasesUrl); |
There was a problem hiding this comment.
Preserve the legacy-key update guard
When the update prompt is accepted by a user whose samsettings.ini does not contain a DPAPI-sealed key, EncryptionKey.Get() falls back to the legacy build key, and this path now replaces the executable directly. The removed guard was the only thing preventing legacy-key users from auto-updating across releases where the embedded key changes (the file even notes keys change before releases), so those users can restart into a build that cannot decrypt their existing info.dat; keep the manual/migration path for EncryptionKey.IsUsingLegacyKey before calling the updater.
Useful? React with 👍 / 👎.
Summary
Makes auto-update actually work for this fork. The existing flow checked
rex706/SAM'slatest.txt(so it would never see this fork's releases) and required an externalrex706/Updaterbinary. Replaced with an in-process self-updater + a workflow step that maintainslatest.txtautomatically.How the new flow works
CheckForUpdatessetting enabled), SAM fetcheshttps://raw.githubusercontent.com/matisseduffield/SAM/master/latest.txt. New 2-line format:SelfUpdater.DownloadAndApplyAsync:SAM.exe.newnext to the running EXE%TEMP%\sam_update_*.cmdthat polls the current PID, atomically moves the new EXE over the old when it exits, relaunches SAM, deletes itselfApplication.Current.Shutdown()info.dat/samsettings.ini/.sambackupfiles, picks up the DPAPI-sealed key fromsamsettings.inior falls back to the legacyPRIVATE_KEYconstant (which is identical between builds), and just works.Maintaining
latest.txtrelease.ymlgains a final step that runs after the GitHub Release is created:Wrapped in
continue-on-errorso a transient git push race can't fail an otherwise-successful release.[skip ci]keeps it from re-triggering the workflow.What happens for older installs
Anyone running a previously-installed SAM (pre-this-PR) is still pointed at
rex706/SAM'slatest.txt— they have to download this PR's release once manually. From the next release after that, auto-update takes over.Files
Core/SelfUpdater.csCore/UpdateHelper.cs— 2-line format,latestDownloadUrl, delegates toSelfUpdaterViews/AccountsWindow.xaml.cs— fork URLs + removes legacy "rebuild yourself" warninglatest.txt— new format, points at this fork.github/workflows/release.yml— auto-commitlatest.txton releaseSAM.csproj— registerSelfUpdater.csTest plan
v1.5.9331.26727) → workflow builds, creates Release, then commitslatest.txtbump to masterlatest.txtto an older version → relaunch → no promptlatest.txtto a newer version → relaunch → update prompt appears with the "info.dat preserved" messageSAM.exe.newappears briefly, SAM exits,%TEMP%\sam_update_*.cmdswaps it in, SAM relaunches on the new versioninfo.dat,samsettings.ini, any.sambackupfiles untouched after updatelatest.txtis broken: error dialog points to the releases pageGenerated by Claude Code