diff --git a/cmd/omni/update_command_test.go b/cmd/omni/update_command_test.go index 6849ab5..25d883f 100644 --- a/cmd/omni/update_command_test.go +++ b/cmd/omni/update_command_test.go @@ -28,9 +28,9 @@ func TestUpdateCheckJSON(t *testing.T) { UpdateAvailable: true, CurrentVersion: "v1.2.0", LatestVersion: "v1.3.0", - ReleaseURL: "https://example.test/v1.3.0", + ReleaseURL: "https://github.com/exploreomni/cli/releases/tag/v1.3.0", Upgrade: updatecheck.UpgradeInstructions{ - Homebrew: "brew upgrade omni", + Homebrew: "brew update && brew upgrade omni", Other: "install command", }, }} diff --git a/cmd/omni/update_notice_test.go b/cmd/omni/update_notice_test.go index e247a84..86a5136 100644 --- a/cmd/omni/update_notice_test.go +++ b/cmd/omni/update_notice_test.go @@ -159,8 +159,8 @@ func TestAutomaticUpdateNotice(t *testing.T) { result := updatecheck.Result{ UpdateAvailable: true, LatestVersion: "v1.3.0", - ReleaseURL: "https://example.test/v1.3.0", - Upgrade: updatecheck.UpgradeInstructions{Homebrew: "brew upgrade omni", Other: "install command"}, + ReleaseURL: "https://github.com/exploreomni/cli/releases/tag/v1.3.0", + Upgrade: updatecheck.UpgradeInstructions{Homebrew: "brew update && brew upgrade omni", Other: "install command"}, } ch := make(chan updateOutcome, 1) ch <- updateOutcome{result: result} @@ -282,15 +282,15 @@ func TestRecentHomebrewReleaseIsSuppressed(t *testing.T) { } func TestUpgradeHint(t *testing.T) { - unix := updatecheck.UpgradeInstructions{Homebrew: "brew upgrade omni", Other: "curl ... | sh"} - if got := upgradeHint(unix, true); got != "run: brew upgrade omni" { + unix := updatecheck.UpgradeInstructions{Homebrew: "brew update && brew upgrade omni", Other: "curl ... | sh"} + if got := upgradeHint(unix, true); got != "run: brew update && brew upgrade omni" { t.Errorf("homebrew hint = %q", got) } if got := upgradeHint(unix, false); got != "run: curl ... | sh" { t.Errorf("unix hint = %q", got) } // Windows has no Homebrew and no install.sh, so the advice is prose. - windows := updatecheck.UpgradeInstructions{Other: "download the latest release from https://example.test/latest"} + windows := updatecheck.UpgradeInstructions{Other: "download the latest release from https://github.com/exploreomni/cli/releases/latest"} if got := upgradeHint(windows, false); got != windows.Other { t.Errorf("windows hint = %q", got) } diff --git a/internal/updatecheck/updatecheck.go b/internal/updatecheck/updatecheck.go index e57fb90..6ef2318 100644 --- a/internal/updatecheck/updatecheck.go +++ b/internal/updatecheck/updatecheck.go @@ -344,7 +344,8 @@ func upgradeInstructions(goos string) UpgradeInstructions { if goos == "windows" { return UpgradeInstructions{Other: "download the latest release from " + releasesPage} } - return UpgradeInstructions{Homebrew: "brew upgrade omni", Other: installCommand} + // brew upgrade only auto-refreshes taps every 24h, so it can miss a fresh release. + return UpgradeInstructions{Homebrew: "brew update && brew upgrade omni", Other: installCommand} } func (c *Checker) readState() (state, error) { diff --git a/internal/updatecheck/updatecheck_test.go b/internal/updatecheck/updatecheck_test.go index f4be88c..1b96abb 100644 --- a/internal/updatecheck/updatecheck_test.go +++ b/internal/updatecheck/updatecheck_test.go @@ -53,13 +53,13 @@ func (c *clock) advance(d time.Duration) { c.now = c.now.Add(d) } -const releaseBody = `{"tag_name":"v1.3.0","html_url":"https://example.test/v1.3.0","published_at":"2026-08-30T12:00:00Z"}` +const releaseBody = `{"tag_name":"v1.3.0","html_url":"https://github.com/exploreomni/cli/releases/tag/v1.3.0","published_at":"2026-08-30T12:00:00Z"}` func newTestChecker(t *testing.T, statePath string, clk *clock, rt roundTripFunc) *Checker { t.Helper() return &Checker{ Client: &http.Client{Transport: rt}, - Endpoint: "https://example.test/latest", + Endpoint: defaultEndpoint, StatePath: statePath, Now: clk.Now, } @@ -156,7 +156,7 @@ func TestAutomaticCheckFastPathDoesNotCreateTheLock(t *testing.T) { t.Fatal("a throttled check must not make a request") return nil, nil }) - wantRelease := Release{Version: "v1.3.0", URL: "https://example.test/v1.3.0"} + wantRelease := Release{Version: "v1.3.0", URL: "https://github.com/exploreomni/cli/releases/tag/v1.3.0"} if err := checker.writeState(state{ NextCheckAt: clk.Now().Add(checkInterval), LatestRelease: wantRelease, @@ -332,10 +332,10 @@ func TestStaleLeaseOwnerCannotOverwriteNewerState(t *testing.T) { if !ok { t.Fatal("expected the expired lease to be reclaimed") } - checker.finishCheck(fresh, Release{Version: "v1.4.0", URL: "https://example.test/v1.4.0"}, nil) + checker.finishCheck(fresh, Release{Version: "v1.4.0", URL: "https://github.com/exploreomni/cli/releases/tag/v1.4.0"}, nil) // The stale owner finally returns with an older answer. - checker.finishCheck(stale, Release{Version: "v1.3.0", URL: "https://example.test/v1.3.0"}, nil) + checker.finishCheck(stale, Release{Version: "v1.3.0", URL: "https://github.com/exploreomni/cli/releases/tag/v1.3.0"}, nil) s, err := checker.readState() if err != nil { @@ -352,7 +352,7 @@ func TestStaleLeaseOwnerCannotOverwriteNewerState(t *testing.T) { func TestConcurrentNotificationClaimsProduceOneNotice(t *testing.T) { clk := newClock() statePath := filepath.Join(t.TempDir(), "update.json") - r := result("v1.2.0", Release{Version: "v1.3.0", URL: "https://example.test/release"}) + r := result("v1.2.0", Release{Version: "v1.3.0", URL: "https://github.com/exploreomni/cli/releases/tag/v1.3.0"}) var claims atomic.Int64 var wg sync.WaitGroup @@ -376,7 +376,7 @@ func TestConcurrentNotificationClaimsProduceOneNotice(t *testing.T) { func TestNotificationThrottle(t *testing.T) { clk := newClock() checker := newTestChecker(t, filepath.Join(t.TempDir(), "update.json"), clk, nil) - r := result("v1.2.0", Release{Version: "v1.3.0", URL: "https://example.test/release"}) + r := result("v1.2.0", Release{Version: "v1.3.0", URL: "https://github.com/exploreomni/cli/releases/tag/v1.3.0"}) if !checker.ClaimNotification(r) { t.Fatal("a new release should be claimable before its first notification") } @@ -395,7 +395,7 @@ func TestNotificationThrottle(t *testing.T) { func TestNotificationFastPathDoesNotCreateTheLock(t *testing.T) { clk := newClock() checker := newTestChecker(t, filepath.Join(t.TempDir(), "update.json"), clk, nil) - r := result("v1.2.0", Release{Version: "v1.3.0", URL: "https://example.test/release"}) + r := result("v1.2.0", Release{Version: "v1.3.0", URL: "https://github.com/exploreomni/cli/releases/tag/v1.3.0"}) if err := checker.writeState(state{ NotifiedVersion: r.LatestVersion, NotifiedAt: clk.Now(), @@ -524,7 +524,7 @@ func TestUpgradeInstructionsArePlatformSpecific(t *testing.T) { } for _, goos := range []string{"darwin", "linux"} { got := upgradeInstructions(goos) - if got.Homebrew != "brew upgrade omni" || got.Other != installCommand { + if got.Homebrew != "brew update && brew upgrade omni" || got.Other != installCommand { t.Fatalf("%s instructions = %+v", goos, got) } }