Skip to content

Notify users about new gh-stack releases - #545

Merged
skarim merged 3 commits into
mainfrom
skarim/cli-update-notification
Oct 2, 2026
Merged

skarim merged 3 commits into
mainfrom
skarim/cli-update-notification

Conversation

@skarim

@skarim skarim commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Adds a lightweight upgrade nudge for users running an older gh-stack release, pointing them to gh extension upgrade stack without upgrading automatically.

Functionality and user impact

  • Check the official repository's /releases/latest endpoint—the same release source used by extension upgrades—and require a newer stable version with a matching platform binary.
  • Cache successful checks for 24 hours and remind at most once every 24 hours during normal sequential use. Failed or canceled attempts can retry after a 15-minute cooldown. Separate attempt/check/reminder timestamps and the latest version are stored in StateDir()/gh-stack/state.yml, shared across repositories for the user.
  • Run the check in the background with a two-second deadline. Completed commands append ready notices to stderr after success or an operational failure, including in non-interactive use. The original error appears first; stdout, JSON output, and exit codes stay unchanged. GH_STACK_NO_UPDATE_NOTIFIER=1 disables the notifier; update-check failures are diagnostic-only under GH_DEBUG.

Boundary: commands never wait for the network check. Short commands may miss a notice; completed results can be shown later. Local/development, prerelease, and pinned installations are excluded, as are help, version, and completion commands. Usage errors and explicit user cancellations do not display a notice.

Delivery stays independent of core gh to cover failures, non-interactive use, and pending notices that core may not deliver. A modern interactive gh can therefore show its own notice as well after a successful command; that overlap is an intentional tradeoff. Concurrent processes may also occasionally duplicate a check or reminder.

Key areas to review

  • internal/update/update.go
    • check, noticeDue, readState, and writeState separate attempts from successful checks and reminder delivery, enforce the cooldowns, recover invalid state, and replace the YAML file atomically.
    • eligible and fetchLatest restrict notices to official, unpinned installs and avoid downgrade or unsupported-platform suggestions.
  • cmd/root.go: pre-run startup, buffered result delivery, and execution finalization deliver notices after the original command diagnostics without waiting or changing exit codes. Cancellation markers in command handlers distinguish user cancellations from already-reported operational failures.

Related issues

@skarim
skarim force-pushed the skarim/cli-update-notification branch from 7e100f2 to 0b05b27 Compare October 2, 2026 15:04
@skarim
skarim marked this pull request as ready for review October 2, 2026 15:05
Copilot AI balanced review requested due to automatic review settings October 2, 2026 15:05

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.

Copilot review overview

🟢 Approval recommended

The implementation is non-blocking, failure-isolated, and comprehensively tested across its key behaviors.

Review effort: Balanced
Findings: None

What changed in this PR

Adds a background release notifier that preserves command output and exit behavior.

Changes:

  • Checks official releases and caches daily check/reminder state.
  • Integrates non-blocking notifications into successful commands.
  • Adds comprehensive tests and user documentation.
File Description
README.md Documents updates and notifier behavior.
cmd/​root.go Integrates background checks into command lifecycle.
cmd/​root_test.go Tests notifier integration and exclusions.
internal/​update/​update.go Implements eligibility, release checks, caching, and notices.
internal/​update/​update_test.go Covers update-check behavior and failure modes.
go.mod Adds direct notifier dependencies.
go.sum Records module checksums.
docs/​src/​content/​docs/​reference/​cli.md Adds detailed notifier reference documentation.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@francisfuzz francisfuzz 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.

✨ This is thoughtful work. The install validation, pre-request reservation, state recovery, and test coverage are all much stronger than the spike I put together.

❓ Asking to learn: are we intentionally choosing successful commands as the delivery point for the gh-stack notice?

I spiked the inverse on spike/update-notifier: let core gh own successful invocations, then have gh-stack cover failures because core gh skips its extension PostRun notice when the extension returns an error.

With the current approach, a modern gh installation can potentially show both notices after a successful command:

A new release of gh-stack is available: 0.1.0 -> 0.1.1
To upgrade, run: gh extension upgrade stack

A new release of stack is available: 0.1.0 → 0.1.1
To upgrade, run: gh extension upgrade stack

Meanwhile, a failed command, which is when someone is most likely to file a bug, does not show either notice.

I am not suggesting we replace this implementation with the spike. The implementation here is stronger. I mainly want to confirm that accepting possible duplication on success, while leaving failures untouched, is the intended product tradeoff. If so, could we capture that rationale in the Boundary section?

Not blocking my approval. I want to make sure this behavior is deliberate rather than incidental to PersistentPostRun. ✅

@skarim

skarim commented Oct 2, 2026

Copy link
Copy Markdown
Collaborator Author

@francisfuzz Thanks for the review and feedback 🙏

❓ Asking to learn: are we intentionally choosing successful commands as the delivery point for the gh-stack notice?

That's a good point. I did this originally thinking it would be less annoying, but you are absolutely right that those failures (especially when a fix may be available in an update) are probably where the upgrade notice would be most valuable. I've made this update in c8e7b43 to also show the notice on failures, while also preserving the standard error outputs.

With the current approach, a modern gh installation can potentially show both notices after a successful command:

In my experience (and those reported by users), the upgrade prompt that should be coming from gh is not showing up for gh stack. It may be related to how this extension is designed, or perhaps because no one ever runs merely gh stack but subcommands like gh stack rebase or gh stack submit. I'll investigate this further and discuss with the gh CLI team.

In the meantime, I think a potential duplication is acceptable, and if we hear lots of reports of that from users, we can adjust our approach in the next release.

@skarim
skarim merged commit d4ab7ab into main Oct 2, 2026
7 checks passed
@skarim
skarim deleted the skarim/cli-update-notification branch October 2, 2026 20:23
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.

3 participants