feat(cli): add self-update command with tag namespace filtering#3859
feat(cli): add self-update command with tag namespace filtering#3859douglarek wants to merge 1 commit into
Conversation
Introduces 'reasonix update [--check] [--force]' that checks GitHub Releases for a newer CLI version, downloads the platform-matched archive, verifies its SHA-256 checksum, and atomically replaces the running binary. Uses /releases (list) instead of /releases/latest to filter by CLI tag namespace (v*), correctly skipping desktop-v* and npm-v* releases that share the same repository.
f1e35c3 to
81c389c
Compare
esengine
left a comment
There was a problem hiding this comment.
This is a well-built foundation — the tag-namespace filter is exactly right for our three-namespace release layout (v* / npm-v* / desktop-v*), the GoReleaser asset-name matching and SHA256SUMS parsing line up with what the release workflow actually publishes, and the helper coverage is thorough. Three things need fixing before this can ship, two of them Windows/integrity critical:
1. The install step breaks on Windows. atomicReplace renames the temp file over exePath — but on Windows the running executable is memory-mapped, and os.Rename onto it fails with ERROR_ACCESS_DENIED. The standard dance is: rename the running exe aside (reasonix.exe → reasonix.exe.old, allowed even while running), rename the new binary into place, then best-effort delete the .old (and clean up stale .old files on a later run, since the delete fails while the old image is still loaded). The desktop updater under desktop/internal/update already deals with this — worth borrowing its approach. As written, reasonix update will download, verify, and then error out on the platform with the most users.
2. Checksum verification must fail closed. Right now a failed SHA256SUMS download (or a missing entry) prints a warning and installs the unverified binary anyway. The checksum is the only integrity gate on something we're about to execute; a CDN hiccup shouldn't silently degrade into an unverified install. Make it a hard error, and if you want an escape hatch, an explicit --skip-verify flag is fine.
3. Filter prereleases. fetchLatestRelease takes the first v* entry from /releases, which includes prereleases — a published v1.6.0-rc.1 would be offered to every stable user (and compareSemver strips the suffix, so it also reads as equal to v1.6.0). Skip releases with "prerelease": true and tags containing - unless an opt-in flag asks for them.
Two non-blocking notes: the i18n catalogues gained entries but updateCommand prints hardcoded English — fine to unify in a follow-up; and a one-line warning when the binary lives under an npm or Homebrew install root would save users from package-manager drift, but I won't hold the PR on it.
Happy to merge promptly once the three above are addressed — the structure is right, it's the platform edges that need finishing.
|
Heads-up: #3941 is a parallel implementation of the same command. I've reviewed both against the same checklist — your namespace filter is the part that PR got wrong, while it has the fail-closed checksum and i18n that this one is missing; the Windows running-exe replacement blocks both. First PR to address all points lands and the other gets closed with credit to both — or feel free to team up on one branch, the complete implementation already exists across your two diffs. |
…ngine#3859 Merge the best of both PRs per owner review feedback: - List /releases + isCLITag filter instead of /releases/latest (from esengine#3859) Fixes 100% breakage when newest release is desktop-v* or npm-v*. - Add --force flag for reinstalling the same version (from esengine#3859) - Add humanSize for download progress display (from esengine#3859) - Windows two-phase rename (.old) with rollback (new, based on minio/selfupdate) - Keep fail-closed checksum verification from esengine#3941 (hard-abort on mismatch) - Keep full en/zh i18n catalogue from esengine#3941 - Fix extractFromZip double-.exe bug (binName already carries .exe) - Add hide_windows.go / hide_other.go with build tags Refs: esengine#3941, esengine#3859
…ngine#3859 Merge the best of both PRs per owner review feedback: - List /releases + isCLITag filter instead of /releases/latest (from esengine#3859) Fixes 100% breakage when newest release is desktop-v* or npm-v*. - Add --force flag for reinstalling the same version (from esengine#3859) - Add humanSize for download progress display (from esengine#3859) - Windows two-phase rename (.old) with rollback (new, based on minio/selfupdate) - Keep fail-closed checksum verification from esengine#3941 (hard-abort on mismatch) - Keep full en/zh i18n catalogue from esengine#3941 - Fix extractFromZip double-.exe bug (binName already carries .exe) - Add hide_windows.go / hide_other.go with build tags Refs: esengine#3941, esengine#3859
…e#4005) Adds `reasonix upgrade` / `update`: queries the GitHub releases API, filters to the CLI tag namespace (v*, skipping desktop-v*/npm-v*), compares with x/mod/semver, downloads the platform archive, fail-closed SHA256 verification (mismatch or missing entry aborts), extracts the binary in memory, and replaces the running executable (atomic rename on Unix; two-phase .old/.new rename with rollback on Windows). Includes --check and --force flags and full en/zh i18n. Closes esengine#3859
Introduces 'reasonix update [--check] [--force]' that checks GitHub Releases for a newer CLI version, downloads the platform-matched archive, verifies its SHA-256 checksum, and atomically replaces the running binary.
Uses /releases (list) instead of /releases/latest to filter by CLI tag namespace (v*), correctly skipping desktop-v* and npm-v* releases that share the same repository.