Skip to content

fix(cli): combine self-update improvements from #3941 and #3859#4005

Merged
esengine merged 2 commits into
esengine:main-v2from
lanshi17:feat/cli-self-update
Jun 12, 2026
Merged

fix(cli): combine self-update improvements from #3941 and #3859#4005
esengine merged 2 commits into
esengine:main-v2from
lanshi17:feat/cli-self-update

Conversation

@lanshi17

Copy link
Copy Markdown
Contributor

Summary

Combines the best of #3941 and #3859 per owner review feedback. Addresses all four checklist items: namespace filter ✅, fail-closed checksum ✅, Windows replace ✅, i18n ✅.

What changed from the original #3941

Issue Fix
/releases/latest returns desktop/npm releases Switch to list /releases + isCLITag filter (from #3859) — skips desktop-v*, npm-v*
Windows os.Rename fails on running exe Two-phase rename: .old.new → target, with rollback + best-effort hide (based on minio/selfupdate pattern)
extractFromZip double .exe bug Match by filepath.Base(f.Name) == name — caller already passes reasonix.exe on Windows
Missing --force flag Added via flag.FlagSet (from #3859)

What's kept from #3941

  • Fail-closed checksum: SHA256 mismatch or missing entry → hard abort (not warn-and-continue)
  • Full en/zh i18n: all user-facing strings through the i18n catalogue
  • x/mod/semver for prerelease-correct comparison

New from #3859

  • isCLITag namespace filter
  • --force flag
  • humanSize for download progress

Checklist alignment

Dimension #3941 (original) #3859 This PR
Namespace filter
Fail-closed checksum
Windows replace
i18n (en/zh)

Files changed

File Change
internal/cli/upgrade.go Rewrite: tag filtering, --force, Windows .old replace, humanSize
internal/cli/upgrade_test.go Add TestIsCLITag, TestHumanSize, TestFetchLatestRelease_FiltersTags
internal/cli/hide_windows.go New: Windows SetFileAttributes hidden-file helper
internal/cli/hide_other.go New: no-op stub for non-Windows
internal/i18n/i18n.go Add UpgradeForcing field
internal/i18n/messages_en.go English: --force usage, UpgradeForcing, download size format
internal/i18n/messages_zh.go Chinese: same

Closes #3859

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

Add 'reasonix upgrade' (alias: 'reasonix update') to download and apply
the latest release from GitHub in-place. Includes '--check' flag for
version-only comparison without downloading.

The command:
- Fetches the latest release from the GitHub Releases API
- Compares semver versions (dev builds are skipped)
- Downloads the platform-appropriate binary (.tar.gz or .zip)
- Verifies SHA256 checksum against the release's SHA256SUMS file
- Atomically replaces the running binary via temp+rename

Uses the project's existing netclient proxy support so corporate
environments work transparently. All user-facing strings are
bilingual (en/zh) via the i18n catalogue.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added v2 Go rewrite (1.x) — main-v2 branch, active development tui Terminal UI / CLI (internal/cli, internal/control) and removed v2 Go rewrite (1.x) — main-v2 branch, active development labels Jun 11, 2026
…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
@lanshi17 lanshi17 force-pushed the feat/cli-self-update branch from e5fbecc to 3dcd1c2 Compare June 11, 2026 08:58
@esengine

Copy link
Copy Markdown
Owner

Solid work — combining the namespace filter (#3859) with the fail-closed checksum and i18n (#3941) is exactly what the review asked for, and the Windows two-phase rename with rollback is the right call. I verified the asset-name matching against a real release (reasonix-<os>-<arch>.{tar.gz,zip} + SHA256SUMS) and it lines up, and the checksum/extraction tests cover the security-critical paths.

One follow-up I'll take care of separately: fetchLatestRelease doesn't skip prerelease releases, so during an rc window upgrade could move a stable user onto a v*-rc. Out of scope for this PR's checklist — I'll add the prerelease skip in a small follow-up. Merging, thanks!

@esengine esengine merged commit 19f6bcd into esengine:main-v2 Jun 12, 2026
13 checks passed
esengine added a commit that referenced this pull request Jun 12, 2026
`reasonix upgrade` deliberately tracks the newest 1.x, including rc: only 1.x
carries this command and the 1.x line ships as rc on npm @next, so there is no
stable user to hold back — the original #4005 already picked the newest v*
release regardless of the prerelease flag, and that stays.

Extract the selection into a pure pickCLIRelease (foreign desktop-v/npm-v tags
skipped) and unit-test it without a network round-trip, including a case that
locks in "a newer rc wins". Remove normalizeOS, a no-op returning runtime.GOOS
unchanged behind a multi-line comment; real assets are reasonix-<goos>-<goarch>.
No behavior change.
esengine added a commit that referenced this pull request Jun 12, 2026
`reasonix upgrade` deliberately tracks the newest 1.x, including rc: only 1.x
carries this command and the 1.x line ships as rc on npm @next, so there is no
stable user to hold back — the original #4005 already picked the newest v*
release regardless of the prerelease flag, and that stays.

Extract the selection into a pure pickCLIRelease (foreign desktop-v/npm-v tags
skipped) and unit-test it without a network round-trip, including a case that
locks in "a newer rc wins". Remove normalizeOS, a no-op returning runtime.GOOS
unchanged behind a multi-line comment; real assets are reasonix-<goos>-<goarch>.
No behavior change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tui Terminal UI / CLI (internal/cli, internal/control)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants