Skip to content

feat(cli): add self-update command (reasonix upgrade/update)#3941

Closed
lanshi17 wants to merge 1 commit into
esengine:main-v2from
lanshi17:feat/cli-self-update
Closed

feat(cli): add self-update command (reasonix upgrade/update)#3941
lanshi17 wants to merge 1 commit into
esengine:main-v2from
lanshi17:feat/cli-self-update

Conversation

@lanshi17

Copy link
Copy Markdown
Contributor

Summary

Add reasonix upgrade (alias: reasonix update) to download and apply the latest CLI release from GitHub Releases in-place.

Changes

  • New command: reasonix upgrade [--check] — fetches the latest release, compares semver, downloads the platform binary, verifies SHA256, and replaces the running executable atomically.
  • --check flag: version-only comparison without downloading — useful for scripts/CI.
  • Proxy support: uses the project's existing netclient proxy infrastructure so corporate environments work transparently.
  • i18n: all user-facing strings are bilingual (en/zh) via the i18n catalogue.
  • Tests: unit tests for version normalization, SHA256 checksum verification, and tar.gz extraction.

How it works

  1. Calls the GitHub Releases API for esengine/DeepSeek-Reasonix/releases/latest
  2. Compares the running version against the release tag using golang.org/x/mod/semver
  3. Downloads the platform-appropriate archive (.tar.gz for Linux/macOS, .zip for Windows)
  4. Verifies SHA256 against the release's SHA256SUMS file
  5. Extracts the reasonix binary and replaces the running executable via temp-file + rename

Safety

  • Dev builds (version = "dev") are skipped — they never self-update.
  • SHA256 checksum is verified before any binary replacement.
  • Atomic replace via temp-file + rename (no partial writes).
  • Respects the existing proxy configuration for network access.

Usage

# Check if an update is available
reasonix upgrade --check

# Download and apply the latest release
reasonix upgrade
# or equivalently:
reasonix update

Files changed

File Change
internal/cli/upgrade.go New: upgrade command implementation
internal/cli/upgrade_test.go New: unit tests
internal/cli/cli.go Register upgrade/update in command router
internal/i18n/i18n.go Add upgrade message fields to Messages struct
internal/i18n/messages_en.go English strings + usage text
internal/i18n/messages_zh.go Chinese strings + usage text
go.mod / go.sum Add golang.org/x/mod (semver comparison)

@github-actions github-actions Bot added v2 Go rewrite (1.x) — main-v2 branch, active development tui Terminal UI / CLI (internal/cli, internal/control) labels Jun 11, 2026
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>
@lanshi17 lanshi17 force-pushed the feat/cli-self-update branch from 1b6d45e to 50c0725 Compare June 11, 2026 04:15

@esengine esengine left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — the structure is clean, and two things here are genuinely better than the parallel attempt in #3859: every user-facing string goes through the i18n catalogue, and checksum verification fails closed (mismatch/missing-entry abort the install instead of warning and proceeding). Both of those are the bar.

But two of the same blockers from the #3859 review apply here too, and one of them fires on every single run today:

1. /releases/latest is the wrong endpoint for this repository (blocker — currently 100% broken). This repo publishes three release namespaces: v* (CLI), npm-v*, and desktop-v*. /releases/latest returns whichever release is marked Latest — which right now is desktop-v1.5.0. semver.IsValid("desktop-v1.5.0") is false, so as merged this command would error out on the invalid-tag path every time (and if a desktop release ever passed validation, it would try to download CLI archives from a desktop tag). You need to list /releases and select the newest tag matching ^v[0-9] — see the namespace filter in #3859, which got this part right. Skip "prerelease": true entries while you're there.

2. Windows cannot rename over the running executable (blocker). os.Rename(tmpName, resolved) fails with ERROR_ACCESS_DENIED while reasonix.exe is memory-mapped — the standard dance is rename the running exe aside to .old (allowed while running), rename the new binary into place, best-effort delete the .old and sweep stale ones on a later run. desktop/internal/update already implements this pattern.

On the overlap with #3859: two PRs are now solving the same feature; I've reviewed both against the same checklist (namespace filter ✅ there / ❌ here; fail-closed checksum ❌ there / ✅ here; Windows replace ❌ both; i18n ❌ there / ✅ here). Whichever lands first with all four points addressed gets merged, and I'll close the other crediting both. You two are also welcome to combine forces on one branch — between #3859's release-selection logic and this PR's verification/i18n, the complete implementation already exists across the two diffs.

@esengine

Copy link
Copy Markdown
Owner

Closing in favor of #3859 as the base implementation 鈥?see the cross-review there. The deciding issues were structural: /releases/latest doesn't filter our three tag namespaces (whenever the newest release is npm-v*/desktop-v*, update breaks entirely), and the Windows zip path searches for reasonix.exe.exe (binName already carries .exe, extractFromZip appends another) so Windows update can't work as shipped. What we're carrying over from yours into #3859's revision list, with credit: x/mod/semver for prerelease-correct comparison, hard-fail on checksum mismatch, and the full en/zh message catalogue. Thanks for the thorough work 鈥?the polish here genuinely raised the bar for the surviving PR.

@esengine esengine closed this Jun 11, 2026
lanshi17 added a commit to lanshi17/DeepSeek-Reasonix that referenced this pull request 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 added a commit to lanshi17/DeepSeek-Reasonix that referenced this pull request 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
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) v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants