Skip to content

Extension update notices should be non-blocking #10235

Closed

Description

@andyfeller

Describe the bug

After #9934 was merged, @williammartin called out a problem where the logic handling extension updates is blocking, which will cause the user to wait an indeterminate amount of time for gh to check if a new version is available:

// PostRun handles communicating extension release information if found
PostRun: func(c *cobra.Command, args []string) {
releaseInfo := <-updateMessageChan
if releaseInfo != nil {
stderr := io.ErrOut
fmt.Fprintf(stderr, "\n\n%s %s → %s\n",
cs.Yellowf("A new release of %s is available:", ext.Name()),
cs.Cyan(strings.TrimPrefix(ext.CurrentVersion(), "v")),
cs.Cyan(strings.TrimPrefix(releaseInfo.Version, "v")))
if ext.IsPinned() {
fmt.Fprintf(stderr, "To upgrade, run: gh extension upgrade %s --force\n", ext.Name())
} else {
fmt.Fprintf(stderr, "To upgrade, run: gh extension upgrade %s\n", ext.Name())
}
fmt.Fprintf(stderr, "%s\n\n",
cs.Yellow(releaseInfo.URL))
}
},

This was a mistake on the author's part as the update checking logic should be non-blocking like it is with core gh update checking:

cli/internal/ghcmd/cmd.go

Lines 174 to 191 in 112552f

updateCancel() // if the update checker hasn't completed by now, abort it
newRelease := <-updateMessageChan
if newRelease != nil {
isHomebrew := isUnderHomebrew(cmdFactory.Executable())
if isHomebrew && isRecentRelease(newRelease.PublishedAt) {
// do not notify Homebrew users before the version bump had a chance to get merged into homebrew-core
return exitOK
}
fmt.Fprintf(stderr, "\n\n%s %s → %s\n",
ansi.Color("A new release of gh is available:", "yellow"),
ansi.Color(strings.TrimPrefix(buildVersion, "v"), "cyan"),
ansi.Color(strings.TrimPrefix(newRelease.Version, "v"), "cyan"))
if isHomebrew {
fmt.Fprintf(stderr, "To upgrade, run: %s\n", "brew upgrade gh")
}
fmt.Fprintf(stderr, "%s\n\n",
ansi.Color(newRelease.URL, "yellow"))
}

Steps to reproduce the behavior

  1. Create simple extension for testing

    gh ext create gh-sleep
    cd gh-sleep
    gh repo create --push --private --source .
    gh ext install andyfeller/gh-sleep
  2. Artificially extend extension update check behavior

    diff --git a/pkg/cmd/root/extension.go b/pkg/cmd/root/extension.go
    index 7f2325e1..95d4669d 100644
    --- a/pkg/cmd/root/extension.go
    +++ b/pkg/cmd/root/extension.go
    @@ -32,6 +32,9 @@ func NewCmdExtension(io *iostreams.IOStreams, em extensions.ExtensionManager, ex
                    // PreRun handles looking up whether extension has a latest version only when the command is ran.
                    PreRun: func(c *cobra.Command, args []string) {
                            go func() {
    +                               fmt.Fprintf(io.ErrOut, "Artifically delaying update check logic, sleeping for 3 minutes")
    +                               time.Sleep(3 * time.Minute)
    +                               fmt.Fprintf(io.ErrOut, "Artifically delay up!")
                                    releaseInfo, err := checkExtensionReleaseInfo(em, ext)
                                    if err != nil && hasDebug {
                                            fmt.Fprintf(io.ErrOut, "warning: checking for update failed: %v", err)
    
  3. Build and run extension, confirming blocking behavior

    make
    time ./bin/gh sleep

    resulting in:

    Artifically delaying update check logic, sleeping for 3 minutes
    Hello gh-sleep!
    Artifically delay up!
    ./bin/gh sleep  0.05s user 0.02s system 0% cpu 3:00.06 total
    

Expected vs actual behavior

Again, extension update checking logic should be non-blocking.

Logs

Paste the activity from your command line. Redact if needed.

Activity

  1. self-assigned this
    on Jan 13, 2025
  2. added a commit that references this issue on Jan 14, 2025
    bc8c46b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workinggh-extensionrelating to the gh extension command

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions