Skip to content

Add user-initiated release-bundle upgrades #91

Description

@Staphylococcus

Problem statement

LG Buddy already detects newer GitHub releases and sends low-frequency desktop notifications, but release-bundle users still have to open GitHub, download and extract the archive, and run the installer manually.

Add a user-initiated upgrade path that performs those mechanical steps for a host installation that passes the release-bundle upgrade compatibility checks:

lg-buddy updates install

This is an assisted upgrade, not an unattended updater. The user chooses when to run it and approves the existing privilege escalation needed to update system-owned files.

Unified update-channel preference

updates.channel is the sole authority for manual checks, background checks, notifications, and installation.

The public UX should be:

lg-buddy updates check
lg-buddy updates check --notify
lg-buddy updates install

lg-buddy settings set updates.channel stable
lg-buddy settings set updates.channel prerelease

Remove the per-command --channel override from updates check, and do not add one to updates install.

Selection semantics:

  • stable considers stable releases only and selects the latest stable release.
  • prerelease considers both stable and prerelease releases and selects whichever has the highest semantic version.
  • Draft releases and legacy non-version tags remain excluded.
  • The default preference is stable.
  • The installed binary's own stable/prerelease identity does not implicitly override the saved preference.
  • Installation preserves the preference.

This guarantees that the release reported by updates check, shown in a notification, and installed by updates install is selected by one persistent policy.

Desired UX

When a newer release is available:

LG Buddy 1.4.0 is available.
Run `lg-buddy updates install` to upgrade.

The notification should include that command in its body regardless of whether notification actions are supported. Keep the existing View Release and Never Notify Again actions.

Manual updates check output should provide the same install-command next step when an update is available. There is no channel-dependent command variant in either surface.

A terminal-driven install should:

  1. Show the current and target versions and ask for confirmation.
  2. Download the matching release archive and checksum metadata without opening a browser.
  3. Verify the artifact before executing anything from it.
  4. Apply the upgrade without re-running interactive setup or TV pairing.
  5. Request sudo only for system-owned installation steps.
  6. Restart/reload the affected integration and verify the installed version.

Functional scope

Host upgrade compatibility

  • Perform an installed-state preflight before release discovery, downloading, confirmation, sudo, or mutation.
  • Inspect observable runtime and installation facts such as executable location, filesystem topology, path containment, configuration discovery, integration state, service-manager availability, and detectable conflicting ownership.
  • Refuse incompatible hosts with actionable check failures rather than declared installation provenance or distribution classification.
  • After verifying the candidate bundle, run a second candidate-specific non-mutating preflight before privileged mutation.
  • Treat the initial check set as a conservative, evolving safety boundary that can be refined after the updater ships.

The detailed compatibility model and its ongoing refinement are tracked in #100.

Release discovery and artifact selection

  • Make manual and background release discovery load the same updates.channel preference.
  • For prerelease, select the highest semantic version across eligible stable and prerelease releases.
  • Extend the release model with asset metadata.
  • Select the exact supported target archive, initially x86_64-unknown-linux-musl.
  • Require the expected archive and sha256sums.txt; reject missing or ambiguous assets.
  • Refuse equal-version installs and downgrades.
  • Restrict production downloads to the LG Buddy GitHub repository and HTTPS release assets.

Download and verification

  • Stage downloads under the user's LG Buddy cache with restrictive permissions.
  • Prevent concurrent upgrade attempts.
  • Verify the GitHub-provided asset digest and the published checksum entry.
  • Validate archive paths before extraction.
  • Verify that the bundled binary reports the expected version, release channel, and tagged commit before invoking the installer.
  • Clean up incomplete staging after failures.

This matches the trust boundary of the current manual GitHub release-bundle flow. Stronger independent release signing or attestations may be added separately.

Installer upgrade mode

Add an explicit non-interactive upgrade mode to the release-bundle installer.

It must:

  • load and preserve the existing configuration, including updates.channel
  • preserve native webOS credentials
  • avoid interactive discovery, configuration, or pairing
  • avoid unnecessary Python environment recreation for native-only installations
  • update the runtime and owned system/user integration files
  • reload/restart affected services in a defined order
  • verify the final installed version and report partial failures clearly

Notification behavior

Update the existing notification and manual-check rendering only after updates install exists:

  • include lg-buddy updates install when an update is available
  • retain the release URL
  • retain View Release
  • retain Never Notify Again
  • preserve the current once-per-release notification policy
  • render no per-command channel choice

Testing scope

  • the default update preference is stable
  • stable preference selects only the latest stable release
  • prerelease preference selects the highest semantic version across stable and prerelease releases
  • manual check, background check, notification, and install resolve the same candidate
  • stable/prerelease binary identity does not override the saved preference
  • public help and parsing expose no per-command --channel option
  • missing, duplicate, wrong-target, or malformed release assets
  • interrupted downloads and cache cleanup
  • digest and checksum mismatch
  • archive traversal and unexpected bundle layout
  • bundled version/channel/commit mismatch
  • equal-version and downgrade refusal
  • concurrent-upgrade exclusion
  • compatible mutable host acceptance and refusal of incompatible layouts before network or mutation
  • candidate-specific compatibility refusal before sudo or mutation
  • non-interactive in-place upgrade preserving config, update preference, and native credentials
  • service/unit/hook replacement and restart behavior
  • post-install version verification
  • cross-version release smoke from a pinned previous updater-capable bundle to the candidate bundle
  • notification and manual-check output include the unconditional install command

Explicit non-goals

  • per-command release-channel overrides
  • unattended or timer-triggered installation
  • a graphical Install Update notification action
  • opening a terminal or Polkit flow from a notification action
  • GUI progress or cancellation UX
  • host- or distribution-specific upgrade branches
  • publishing or updating .deb/.rpm repositories
  • treating the initial host compatibility check set as permanent or exhaustive
  • arbitrary-version installation or downgrade support

The existing user timer remains detection-and-notification only.

Relationships

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions