Skip to content

Commit

Permalink
[CLI] Add ability to self update binary (#247)
Browse files Browse the repository at this point in the history
* add go-update

* Add assets to the gh release struct

* Add prompt to auto update the binary

* ignore version if running in dev
  • Loading branch information
jhnstn authored Mar 12, 2024
1 parent 286cb49 commit 77eed4a
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 11 deletions.
3 changes: 2 additions & 1 deletion gbm-cli/cmd/release/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package release

import (
"fmt"
"reflect"
"time"

"github.com/fatih/color"
Expand Down Expand Up @@ -39,7 +40,7 @@ var StatusCmd = &cobra.Command{
// Check to see if the release has been published
rel, _ := release.GetGbmRelease(version)

if (rel != gh.Release{}) {
if (!reflect.DeepEqual(rel, gh.Release{})) {
console.Print(heading, "\n🎉 Release %s has been published!\n %s\n", version, rel.Url)
}

Expand Down
13 changes: 3 additions & 10 deletions gbm-cli/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import (
"github.com/spf13/cobra"
"github.com/wordpress-mobile/release-toolkit-gutenberg-mobile/gbm-cli/cmd/release"
"github.com/wordpress-mobile/release-toolkit-gutenberg-mobile/gbm-cli/cmd/render"
"github.com/wordpress-mobile/release-toolkit-gutenberg-mobile/gbm-cli/cmd/utils"
"github.com/wordpress-mobile/release-toolkit-gutenberg-mobile/gbm-cli/pkg/console"
"github.com/wordpress-mobile/release-toolkit-gutenberg-mobile/gbm-cli/pkg/gh"
)

const Version = "v1.5.0"
Expand All @@ -20,20 +20,13 @@ var rootCmd = &cobra.Command{
func Execute() {
err := rootCmd.Execute()
console.ExitIfError(err)

}

func init() {
// Add the render command
rootCmd.AddCommand(render.RenderCmd)
rootCmd.AddCommand(release.ReleaseCmd)

// Check to see if the user is running the latest version
// of the CLI. If not, let them know.
latestRelease, err := gh.GetLatestRelease("release-toolkit-gutenberg-mobile")
console.ExitIfError(err)

if latestRelease.TagName != Version {
console.Warn("You are running an older version of the CLI. Please update to %s", latestRelease.TagName)
if !utils.CheckIfTempRun() {
utils.CheckExeVersion(Version)
}
}
76 changes: 76 additions & 0 deletions gbm-cli/cmd/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@ package utils

import (
"fmt"
"net/http"
"os"
"os/exec"
"path/filepath"
"strings"

"github.com/inconshreveable/go-update"
"github.com/wordpress-mobile/release-toolkit-gutenberg-mobile/gbm-cli/pkg/console"
"github.com/wordpress-mobile/release-toolkit-gutenberg-mobile/gbm-cli/pkg/gh"
"github.com/wordpress-mobile/release-toolkit-gutenberg-mobile/gbm-cli/pkg/semver"
)

Expand Down Expand Up @@ -35,3 +41,73 @@ func Exit(code int, deferred ...func()) {
return code
}())
}

// Checks if running from a temp directory (go build)
// Useful for checking if running via `go run main.go`
// We ignore errors since this only relevant to local development
func CheckIfTempRun() bool {
ex, _ := os.Executable()
dir := filepath.Dir(ex)
return strings.Contains(dir, "go-build")
}

// Updates the currently running executable.
func UpdateExe(url string) error {
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
if err := update.Apply(resp.Body, update.Options{}); err != nil {
return err
}

return nil
}

// Gets the download url for the gbm-cli executable
func exeDownloadUrl(release gh.Release) string {
for _, asset := range release.Assets {
if strings.Contains(asset.Name, "gbm-cli") {
return asset.DownloadUrl
}
}
return ""
}

// Checks if the currently running executable is the latest version
// If not, prompts the user to update.
// If update is confirmed, the executable is updated and the process is restarted
func CheckExeVersion(version string) {
latestRelease, err := gh.GetLatestRelease("release-toolkit-gutenberg-mobile")
console.ExitIfError(err)

if latestRelease.TagName != version {
if console.Confirm("You are running an older version of the CLI. Would you like to update?") {

if url := exeDownloadUrl(latestRelease); url != "" {
if err := UpdateExe(url); err != nil {
console.ExitError("Could not update the CLI: %v", err)
} else {
console.Info("CLI updated successfully")
reStart()
}
} else {
console.ExitError("Could not find download url for latest release")
}
}
}
}

// Restarts the process
func reStart() {
args := os.Args
cmd := exec.Command(args[0], args[1:]...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
if err := cmd.Run(); err != nil {
os.Exit(1)
}
os.Exit(0)
}
1 change: 1 addition & 0 deletions gbm-cli/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ toolchain go1.21.2
require (
github.com/davecgh/go-spew v1.1.1
github.com/fatih/color v1.15.0
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf
github.com/kylelemons/godebug v1.1.0
github.com/mikefarah/yq/v4 v4.35.2
github.com/spf13/cobra v1.7.0
Expand Down
2 changes: 2 additions & 0 deletions gbm-cli/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ github.com/henvic/httpretty v0.1.2 h1:EQo556sO0xeXAjP10eB+BZARMuvkdGqtfeS4Ntjvki
github.com/henvic/httpretty v0.1.2/go.mod h1:ViEsly7wgdugYtymX54pYp6Vv2wqZmNHayJ6q8tlKCc=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf h1:WfD7VjIE6z8dIvMsI4/s+1qr5EL+zoIGev1BQj1eoJ8=
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
Expand Down
9 changes: 9 additions & 0 deletions gbm-cli/pkg/gh/gh.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,15 @@ type Release struct {
Prerelease bool
Target string `json:"target_commitish"`
PublishedAt string `json:"published_at"`
Checksum string
Assets []ReleaseAsset
}

type ReleaseAsset struct {
Name string
ContentType string `json:"content_type"`
Size int
DownloadUrl string `json:"browser_download_url"`
}

type Commit struct {
Expand Down

0 comments on commit 77eed4a

Please sign in to comment.