Describe the feature or problem you’d like to solve
GitHub CLI extension authors want to ensure users are running the newest version of extensions.
Like the GitHub CLI checks for updates every 24 hours when invoked, the GitHub CLI could perform the same logic when an extension command is invoked.
This would ensure GitHub CLI extension users knew about potentially necessary or valuable updates while minimizing the amount of effort on extension authors from reimplementing the logic already within GitHub CLI.
Proposed solution
-
Refactor the update logic within cmd/gh/main.go to be reusable
|
updateCtx, updateCancel := context.WithCancel(ctx) |
|
defer updateCancel() |
|
updateMessageChan := make(chan *update.ReleaseInfo) |
|
go func() { |
|
rel, err := checkForUpdate(updateCtx, cmdFactory, buildVersion) |
|
if err != nil && hasDebug { |
|
fmt.Fprintf(stderr, "warning: checking for update failed: %v", err) |
|
} |
|
updateMessageChan <- rel |
|
}() |
|
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")) |
|
} |
-
Enhance dynamic extension command generation to ensure extension release is checked independently of one another or GitHub CLI
|
// Extensions |
|
em := f.ExtensionManager |
|
for _, e := range em.List() { |
|
extensionCmd := NewCmdExtension(io, em, e) |
|
cmd.AddCommand(extensionCmd) |
|
} |
-
Ensure latest release information logic supports GitHub Enterprise users
|
func getLatestReleaseInfo(ctx context.Context, client *http.Client, repo string) (*ReleaseInfo, error) { |
|
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("https://api.github.com/repos/%s/releases/latest", repo), nil) |
|
if err != nil { |
|
return nil, err |
|
} |
|
res, err := client.Do(req) |
|
if err != nil { |
|
return nil, err |
|
} |
|
defer func() { |
|
_, _ = io.Copy(io.Discard, res.Body) |
|
res.Body.Close() |
|
}() |
|
if res.StatusCode != 200 { |
|
return nil, fmt.Errorf("unexpected HTTP %d", res.StatusCode) |
|
} |
|
dec := json.NewDecoder(res.Body) |
|
var latestRelease ReleaseInfo |
|
if err := dec.Decode(&latestRelease); err != nil { |
|
return nil, err |
|
} |
|
return &latestRelease, nil |
|
} |
cc: @samcoe @nickfyson
Additional context
I was originally attempting to move the internal/update package to cli/go-gh, requiring the standardization on its api clients for the function. After talking with @samcoe about the process going from cli/cli api clients to cli/go-gh api clients, Sam's suggestion of having GitHub CLI do the checking would benefit all extensions without effort.
Describe the feature or problem you’d like to solve
GitHub CLI extension authors want to ensure users are running the newest version of extensions.
Like the GitHub CLI checks for updates every 24 hours when invoked, the GitHub CLI could perform the same logic when an extension command is invoked.
This would ensure GitHub CLI extension users knew about potentially necessary or valuable updates while minimizing the amount of effort on extension authors from reimplementing the logic already within GitHub CLI.
Proposed solution
Refactor the update logic within
cmd/gh/main.goto be reusablecli/cmd/gh/main.go
Lines 59 to 68 in 64f4660
cli/cmd/gh/main.go
Lines 165 to 182 in 64f4660
Enhance dynamic extension command generation to ensure extension release is checked independently of one another or GitHub CLI
cli/pkg/cmd/root/root.go
Lines 170 to 175 in 64f4660
Ensure latest release information logic supports GitHub Enterprise users
cli/internal/update/update.go
Lines 58 to 80 in 64f4660
cc: @samcoe @nickfyson
Additional context
I was originally attempting to move the
internal/updatepackage tocli/go-gh, requiring the standardization on itsapiclients for the function. After talking with @samcoe about the process going fromcli/cliapi clients tocli/go-ghapi clients, Sam's suggestion of having GitHub CLI do the checking would benefit all extensions without effort.