Commit Graph
3 Commits
Author SHA1 Message Date
esengine c130bd7191 Revert "chore(release): the 1.x line stops publishing the CLI to npm, Homebrew, and the CLI pointers (#10757)"
This reverts commit 1aa4a1fb3.

The 1.x line keeps the CLI's install channels (npm `reasonix`, the
Homebrew cask and the CLI update pointers) until 2.x is stable; the
studio line now publishes them only when STUDIO_PUBLISHES_CLI is set.
Without this, 1.39.1 would ship its fixes while npm and Homebrew stayed
at 1.39.0.

Restored workflow steps are pinned to the same full-length SHAs the
rest of main-v2 uses, and the contract test that cuts release-npm.yml at
setup-go matches the pinned form.
2026-09-26 00:51:06 -07:00
YHH 1aa4a1fb31 chore(release): the 1.x line stops publishing the CLI to npm, Homebrew, and the CLI pointers (#10757)
The Studio line now owns the CLI install channels: npm `reasonix` with its
`@reasonix/cli-*` platform packages, the esengine/homebrew-reasonix cask, and
the R2 CLI update pointers (`cli/{stable,preview}/latest.json`) that
`reasonix upgrade` and the site read through the release gateway. A 1.x
release must never write any of them again.

- release-npm.yml is removed, and release-promote/release-stable no longer
  call it or wait on it; the legacy recovery input publish_npm goes with it.
- release.yml no longer hands GoReleaser a tap token, no longer pushes the
  prepared cask, no longer advances the CLI channel pointers, and no longer
  requires npm `latest` to have moved. It still creates the vX.Y.Z GitHub
  release, its notes, the immutable cli/releases/<tag>/latest.json record,
  and the Desktop compatibility asset.
- .goreleaser.yaml drops homebrew_casks.
- verify-stable-release-artifacts.sh and the publication ledger stop
  requiring npm package identities, npm dist-tags, and the cask version.
- Publisher helpers with no remaining caller are removed:
  publish-homebrew-cask, finalize-npm-official-release, resolve-npm-release,
  npm/publish-candidate, decide-cli-pointer-update, compare-cli-release-tags.
- release-workflows.test.sh now fails if any workflow holds NPM_TOKEN or
  HOMEBREW_TAP_TOKEN, names the tap, runs npm publish or dist-tag, or
  writes a CLI channel pointer.

Candidate preparation, tags (including npm-vX.Y.Z), Desktop publication, the
Stable manifest, Pages, and the release-event record are unchanged.
2026-09-24 22:55:29 -07:00
SivanColaandffff2004 ac814a5040 fix(release): complete and harden Stable/Preview channels / 补全并加固正式版与预览版渠道 (#6997)
* complete stable and preview channel loop

* fix(site): harden release-channel fallbacks and version scopes

Problem:
Website CLI Stable fallbacks pointed at GitHub releases/latest asset
URLs, incomplete GitHub releases were turned into 404 download links,
and Desktop/CLI Stable races overwrote every .rxv version chip.

Root cause:
CLI releases set make_latest:false so Latest belongs to Desktop Stable;
releaseAssetMap synthesized missing CLI assets; updateStableVersion was
shared across both product surfaces.

Fix:
- CLI fallback always uses the releases page, never /releases/latest.
- Require all 7 CLI assets before accepting a release (match Worker).
- Scope package-manager .rxv updates to CLI Stable only; desktop
  version chips use data-release-version="desktop".

Verification:
node --test site/src/scripts/release-channels.test.mjs
site/src/scripts/download-link.test.mjs

* fix(desktop): unify update channel controls

Problem: The desktop settings page separated channel selection, update status, and install actions across detached rows.

Root cause: The channel picker and updater state machine were rendered as independent controls, so switching channels did not read as one actionable workflow.

Fix: Merge current version/status, Stable and Preview selection, manual refresh, auto-check guidance, and state-specific download/install actions into one compact settings flow. Add the localized channel auto-check hint for English, Simplified Chinese, and Traditional Chinese.

Verification: pnpm --dir desktop/frontend run typecheck; pnpm --dir desktop/frontend run check:css; pnpm --dir desktop/frontend run test:updater (18 passed); pnpm --dir desktop/frontend run build; git diff --cached --check.

* feat(cli): persist release channel selection

Problem:
CLI users had to repeat the verbose --channel flag, and a plain upgrade always returned to Stable instead of following the user's selected public channel.

Root cause:
The native updater had no user-global channel preference, while the website and docs exposed only one-off flag syntax.

Fix:
Add a user-global [cli].update_channel setting, support upgrade stable|preview as persistent switches, retain --channel as a one-off compatibility override, reject conflicting arguments, and synchronize English/Chinese docs plus website commands.

Verification:
- env -u DEEPSEEK_API_KEY GOCACHE=/private/tmp/reasonix-go-cache go test ./...
- env GOCACHE=/private/tmp/reasonix-go-cache go vet ./internal/cli ./internal/config
- npm test (site)
- npm run build (site)
- git diff --check

* fix(release): keep CLI channel pointers monotonic

Problem: Older Stable recovery runs and out-of-order Preview publishers could overwrite a newer public CLI channel pointer.

Root cause: The release workflow wrote cli/<channel>/latest.json unconditionally and had no channel-scoped serialization or strict version comparison.

Fix: Serialize CLI releases by channel, publish immutable per-tag metadata first, validate the current pointer, and move it only when a strict Stable or Preview version tuple is newer.

Verification: bash scripts/release-workflows.test.sh; bash -n scripts/compare-cli-release-tags.sh scripts/release-workflows.test.sh; git diff --check.

* fix(config): preserve symlinked config files

Problem: Persisting the selected CLI update channel could replace a symlinked user config with a regular file.

Root cause: AtomicWriteFile renamed a temporary file over the symlink path instead of the symlink's final target.

Fix: Resolve complete config symlink chains before atomic writes and route both incremental saves and Config.WriteFile through the shared helper.

Verification: go test ./internal/config; focused writable-target and multi-level symlink regression tests; go test ./...; go vet ./internal/cli ./internal/config.

* fix(release): harden stable and preview end-to-end

Problem:
The Stable/Preview loop still allowed stale or cross-channel release pointers, unsafe Desktop release origins and retries, updater events detached from their checked target, and concurrent config writers that could lose user changes.

Root cause:
Release publication lacked one immutable candidate and strict manifest/recovery contracts; Desktop operations were not bound to request, channel, and version; config locks followed logical paths and several writers loaded stale or malformed snapshots.

Fix:
- authorize Desktop candidates from protected main-v2, separate the current control plane from recovered source commits, validate immutable assets, and make GitHub/R2 publication monotonic and resumable
- bind Desktop checks, downloads, verification, and installs to one request/channel/version state machine with strict size and manifest validation
- validate CLI, Desktop, website, and Worker release data consistently across Stable and Preview
- canonicalize and pin config targets, serialize all affected writers, preserve safe symlinks, and fail closed on malformed configuration

Verification:
- go test -race ./...; go vet ./...; go build ./...
- cd desktop && go test -race ./... && go vet ./... && go build ./...
- frontend typecheck, updater tests (31), CSS checks, and production build
- site tests (44) and production build
- Worker typecheck and tests (74)
- release workflow contracts, actionlint, cache guard, shell syntax, diff check, and Linux/Windows cross-builds

Co-authored-by: ffff2004 <[email protected]>

* fix(config): remove obsolete edit wrappers

Problem:
The release-channel hardening left two private config edit wrappers unreachable, causing the pinned golangci-lint unused check to fail.

Root cause:
Callers now resolve and pin final config targets through the transactional edit path, but the superseded convenience wrappers remained in place.

Fix:
Remove only the two unreferenced wrappers while preserving the resolved-target and timeout helpers used by production code and concurrency tests.

Verification:
- go test ./internal/config
- go vet ./...
- golangci-lint v2.12.2 run --timeout=5m
- git diff --check

* fix(release): satisfy workflow shell lint

Problem:
The final CI lint job passed golangci-lint but failed actionlint because the CLI metadata publisher assigned expected_prerelease without reading it.

Root cause:
Prerelease validation moved into validate-cli-release-manifest.sh, leaving duplicate channel-specific shell assignments in the workflow.

Fix:
Remove the unused assignments and keep prerelease validation centralized in the manifest validator.

Verification:
- actionlint v1.7.7 on all release workflows
- bash scripts/release-workflows.test.sh
- bash -n on release helper scripts
- git diff --check

* fix(release): close desktop channel blockers

Problem:
Desktop Preview-to-Stable switches failed for older Debian Stable builds, updater Wails methods broke older one-argument callers, and config edit locks could split across TMPDIR or macOS case aliases.

Root cause:
The privileged helper rejected every downgrade, strict request binding reused legacy exported method names, and lock identity depended on process-local temp directories without Darwin path folding.

Fix:
Allow only signed public Preview-to-Stable Debian downgrades, preserve legacy updater methods beside strict request-bound APIs, and use a stable hardened per-user lock registry with Darwin alias normalization.

Verification:
Root and Desktop tests, Desktop race, Go vet/build, updater 31/31, site 44/44, Worker 74/74, release workflow contracts, cache guard, actionlint, golangci-lint, frontend typecheck/CSS/build, and focused cross-process/security regressions.

---------

Co-authored-by: ffff2004 <[email protected]>
2026-07-29 15:09:26 +08:00