Skip to content

feat(update): detect install method to tailor or suppress update notices#107

Open
pjcdawkins wants to merge 1 commit into
mainfrom
feat/update-message-install-detection
Open

feat(update): detect install method to tailor or suppress update notices#107
pjcdawkins wants to merge 1 commit into
mainfrom
feat/update-message-install-detection

Conversation

@pjcdawkins

Copy link
Copy Markdown
Contributor

Summary

Detects how the CLI was installed and adjusts the "new release available" notice accordingly, instead of showing the same generic GitHub link to everyone after every command.

  • System package managers (apt, yum/dnf, apk) are detected via a marker file installed by the nfpm packages. The notice is suppressed and the network check is skipped, since the OS handles updates.
  • Homebrew, Scoop, npm, and the bash installer get the exact upgrade command, built from config fields so vendor builds stay correct.
  • Unknown installs keep the generic GitHub link.

The notice is now shown before the command runs, using a latest-version cache in state.json refreshed by the background check, and is throttled to once a week. This removes the per-run nagging.

Detection precedence

Explicit override (<PREFIX>INSTALL_METHOD env or wrapper.install_method config) → package marker → resolved executable path (npm / scoop / homebrew) → standard bin dirs (script) → unknown.

Changes

  • internal/install.go: InstallMethod type, DetectInstallMethod, cheap IsAutoUpdating.
  • internal/update.go: cache KnownLatestVersion; PendingNotification / MarkNotified with a weekly throttle; suppress checks for auto-updating installs.
  • commands/root.go: show the notice in PersistentPreRun from the cache; per-method upgrade command.
  • Config: Wrapper.NpmPackage, Wrapper.InstallerURL, Wrapper.InstallMethod.
  • Packaging: packaging/install-source marker added to both nfpm entries.
  • Docs: README, CLAUDE.md, and docs/design/update-message-install-detection.md (which also describes the planned Phase 2: opt-in self-update).

Scope

This is Phase 1 (detection + tailored/suppressed messages + weekly throttle + show-before-via-cache). Phase 2 (interactive prompt + auto-update + re-exec) and the external docs update are tracked separately in the design doc.

Verification

  • Unit tests for detection, method parsing, the weekly throttle, and per-method upgrade commands.
  • Live TTY smoke test confirming npm/homebrew wording, silence for package installs, and that the weekly throttle persists.
  • Confirmed the three pre-existing integration-test failures (set-remote, db:dump, project:create) also fail on main and are unrelated.

🤖 Generated with Claude Code

Detect how the CLI was installed and adjust the "new release available"
notice accordingly:

- System package managers (apt, yum/dnf, apk) are detected via a marker
  file installed by the nfpm packages. The notice is suppressed and the
  network check is skipped, since the OS handles updates.
- Homebrew, Scoop, npm, and the bash installer get the exact upgrade
  command, built from config fields so vendor builds stay correct.
- Unknown installs keep the generic GitHub link.

Detection precedence: an explicit override (<PREFIX>INSTALL_METHOD env or
wrapper.install_method config), then the package marker, then the resolved
executable path (npm/scoop/homebrew), then standard bin dirs (script).

The notice is now shown before the command runs, using a latest-version
cache in state.json refreshed by the background check, and throttled to
once a week (LastNotified). This removes the per-run nagging.

Adds Wrapper.NpmPackage, Wrapper.InstallerURL, and Wrapper.InstallMethod
config fields, and the packaging/install-source marker to both nfpm
entries. Documents the behavior in README and the design doc; Phase 2
(opt-in self-update) is planned in docs/design.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pjcdawkins pjcdawkins marked this pull request as ready for review June 16, 2026 09:17
Copilot AI review requested due to automatic review settings June 16, 2026 09:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds install-method detection to tailor (or suppress) update notifications, moves the “new release available” notice to run before command execution using a cached latest-version in state.json, and throttles notices to once per week while skipping update checks entirely for auto-updating package-manager installs.

Changes:

  • Introduces install-method detection (homebrew, scoop, npm, package, script, unknown) and a cheap IsAutoUpdating gate to suppress notices and network checks for system packages.
  • Adds cached update metadata (KnownLatestVersion, LastNotified) to state.json and uses it to show notices in PersistentPreRun.
  • Adds tailored per-method upgrade commands and updates packaging/docs/config to support detection and messaging.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
README.md Documents new update-notification behavior and env overrides.
packaging/install-source Adds package-manager marker file content used for suppression.
internal/update.go Caches latest version in state; adds weekly throttle + notification helpers; skips checks for auto-updating installs.
internal/update_test.go Unit tests for cached-notification/throttle logic.
internal/state/state.go Extends persisted state with LastNotified and KnownLatestVersion.
internal/install.go Adds install-method detection + cheap auto-updating check.
internal/install_test.go Unit tests for method detection and parsing.
internal/config/upsun-cli.yaml Populates npm/installer fields used to build upgrade commands.
internal/config/schema.go Extends wrapper config schema with npm/installer/install_method fields.
internal/config/platformsh-cli.yaml Adds installer URL for the platform flavor (see review comments).
docs/design/update-message-install-detection.md Design doc describing approach, precedence, and planned Phase 2.
commands/root.go Moves notice to PersistentPreRun; prints from cache; runs background refresh; adds per-method upgrade commands.
commands/root_test.go Tests upgrade-command selection per install method.
CLAUDE.md Updates internal documentation about update checks and install detection.
.goreleaser.yaml Installs package marker file in nfpm packages to enable suppression.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread commands/root.go
Comment on lines +206 to 210
fmt.Fprintf(w, "\n%s %s → %s\n",
color.YellowString(fmt.Sprintf("A new release of the %s is available:", cnf.Application.Name)),
color.CyanString(config.Version),
color.CyanString(newRelease.Version),
)
Comment on lines 6 to +9
wrapper:
homebrew_tap: upsun/tap/platformsh-cli
github_repo: upsun/cli
installer_url: https://raw.githubusercontent.com/upsun/cli/main/installer.sh
Comment thread commands/root.go
Comment on lines +244 to +247
case internal.InstallScript:
if cnf.Wrapper.InstallerURL != "" {
return "curl -fsSL " + cnf.Wrapper.InstallerURL + " | bash"
}
Comment on lines +309 to +312
Populate `npm_package` and `installer_url` in `internal/config/upsun-cli.yaml` and
`internal/config/platformsh-cli.yaml`. A channel with an empty config field
simply falls back to the generic GitHub link for that branch (graceful for vendor
builds that don't ship that channel).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants