Skip to content

fix(desktop): gate updater by stable build identity / 按正式构建身份限制桌面更新器 - #10406

Merged
SivanCola merged 2 commits into
esengine:main-v2from
SivanCola:feature/desktop-updater-policy
Sep 16, 2026
Merged

SivanCola merged 2 commits into
esengine:main-v2from
SivanCola:feature/desktop-updater-policy

Conversation

@SivanCola

Copy link
Copy Markdown
Collaborator

Summary

  • gate every production-updater boundary behind immutable build identity: exact stable channel plus an exact vX.Y.Z release version
  • expose updaterEnabled through the Desktop startup/settings contract and default missing or invalid frontend values to disabled
  • rename the user-facing Updates page to About while preserving the internal updates route for compatibility
  • hide all update controls and production download links in canary, preview, test, dev, and prerelease builds
  • throttle automatic checks across startup, focus, visibility, timers, remounts, and restarts to one attempt per six hours; manual checks still bypass the throttle
  • keep stable updates explicit: checks only read metadata, and download/install/restart only begins after the user clicks the action

Compatibility

  • no config.toml schema or persisted user preference migration
  • old frontends ignore the additive RPC field
  • new frontends treat a missing updaterEnabled field or startup-settings failure as disabled
  • the existing desktop.check_updates preference remains intact for users returning from a test build to a stable build

Security and privacy

  • non-stable builds cannot create the updater HTTP client, download payloads, launch installers, open the production download page, or trigger updater restart paths
  • this change adds no dependency, telemetry, credential access, or new update endpoint

Related PR

Verification

  • cd desktop && go test -timeout 20m ./...
  • pnpm --dir desktop/frontend test:updater
  • pnpm --dir desktop/frontend test:app-lifecycle
  • pnpm --dir desktop/frontend typecheck
  • pnpm --dir desktop/frontend build
  • Desktop contract regeneration and drift checks passed
  • Windows x64 Electron shell packaging reached the unsigned NSIS stage in a Win11 ARM64 VM using x64 emulation

Packaged installation validation was intentionally not performed for this PR.

Documentation-impact: none - the user-facing behavior and explanatory copy are updated in the About settings surface; no external configuration schema or release procedure changes.

@SivanCola
SivanCola requested a review from esengine as a code owner September 16, 2026 10:54
@github-actions github-actions Bot added v2 Go rewrite (1.x) — main-v2 branch, active development desktop Wails desktop app (desktop/**) updater Auto-update / installer / release packaging labels Sep 16, 2026
@SivanCola
SivanCola force-pushed the feature/desktop-updater-policy branch from 4f39cc9 to f4bfba8 Compare September 16, 2026 11:39
Problem:
Desktop test and prerelease builds could still expose and invoke the production updater, while automatic checks could run on every focus or visibility event.

Root cause:
Updater availability was inferred from normalized configuration instead of immutable build identity, and automatic checks had no persisted throttle shared across lifecycle triggers.

Fix:
Gate every updater boundary behind exact stable channel and vX.Y.Z build identity, expose the capability through the Desktop RPC contract, hide updater controls for non-stable builds, rename the user-facing settings page to About, and persist a six-hour automatic-check throttle while keeping manual checks explicit.

Verification:
- cd desktop && go test -timeout 20m ./...
- pnpm --dir desktop/frontend test:updater
- pnpm --dir desktop/frontend test:app-lifecycle
- pnpm --dir desktop/frontend typecheck
- pnpm --dir desktop/frontend build
- Windows x64 Electron shell packaging reached the unsigned NSIS stage in a Win11 ARM64 VM using x64 emulation; packaged installation validation was intentionally not performed.
Problem:
The updater policy implementation added lines to three files already governed by repolint carry-forward budgets, causing the PR lint job to fail.

Root cause:
The new build policy, policy regressions, and startup settings contract were placed in existing oversized owner files instead of focused package-local files.

Fix:
Move the build capability helper, its regression tests, and the lightweight startup settings view into dedicated files without changing runtime behavior or the generated Desktop contract.

Verification:
- go run ./tools/repolint
- cd desktop && go test -run 'TestDesktopUpdaterEnabledRequiresExactStableReleaseBuild|TestDisabledDesktopUpdaterBoundariesHaveNoSideEffects|TestDesktopUpdaterCapabilityAndConfigFailureDefaults|TestUpdaterReconcilesBeforeDownloading|TestHostContractFilesAreCurrent' ./...
- cd desktop && go test -timeout 20m ./...
- Desktop contract drift comparison passed
- git diff --check
@SivanCola
SivanCola force-pushed the feature/desktop-updater-policy branch from f4bfba8 to 6b129e7 Compare September 16, 2026 12:00
@SivanCola

Copy link
Copy Markdown
Collaborator Author

Author review summary (not an approval)

Reviewed head 6b129e76ed5b4f6953863529e741bd25722bfad8 against base 95b21354e367f991363ae3e3dc507a554a9f4ef6. I found no blocking correctness, security, compatibility, race, or performance issue in the updater changes.

Architecture and behavior:

  • The immutable build capability gates CheckUpdate, ApplyUpdateRequest, OpenDownloadPage, and AbandonPendingUpdate before network, cache, installer, browser, or restart side effects.
  • Only exact stable + vX.Y.Z builds can use the production updater; canary, preview, test, dev, and prerelease identities fail closed.
  • Automatic checks persist an attempt timestamp before the RPC and are throttled across startup, timers, focus, visibility, remounts, and restarts to one attempt per six hours. Manual checks remain explicit and bypass the throttle.
  • Available updates only publish UI state. Download, verification, installation, and restart remain behind the user action.

Compatibility and security:

  • updaterEnabled is additive in the Desktop contract. Old frontends ignore it; new frontends treat a missing or failed value as disabled.
  • The existing desktop.check_updates preference and config schema are unchanged.
  • No dependency, credential access, telemetry, hidden persistence, or updater endpoint was added. The change reduces non-stable build privileges.

Verification:

  • go test -timeout 20m ./... passed locally
  • focused updater policy tests and focused -race tests passed
  • updater scheduling and About capability tests passed
  • app lifecycle tests, typecheck, production frontend build, contract drift check, repolint, and git diff --check passed
  • all PR checks passed, including desktop-go-race, Windows Go groups, desktop frontend/browser jobs, CodeQL, and app-memory screening

Residual validation boundary:

The PR is technically ready for an independent maintainer review and merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

desktop Wails desktop app (desktop/**) updater Auto-update / installer / release packaging v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant