diff --git a/go.mod b/go.mod index 9997bce..d0f4150 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/charmbracelet/bubbletea v0.24.1 github.com/charmbracelet/lipgloss v0.9.1 github.com/cli/go-gh v1.2.1 - github.com/hashicorp/go-version v1.6.0 + github.com/hashicorp/go-version v1.7.0 github.com/spf13/cobra v1.8.0 ) diff --git a/go.sum b/go.sum index a6f4a29..5d48cf1 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= -github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= -github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= +github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/henvic/httpretty v0.0.6 h1:JdzGzKZBajBfnvlMALXXMVQWxWMF/ofTy8C3/OSUTxs= github.com/henvic/httpretty v0.0.6/go.mod h1:X38wLjWXHkXT7r2+uK8LjCMne9rsuNaBLJ+5cU2/Pmo= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= diff --git a/go/cmd/cmd.go b/go/cmd/cmd.go index 85d5de5..7ab5a41 100644 --- a/go/cmd/cmd.go +++ b/go/cmd/cmd.go @@ -34,7 +34,7 @@ import ( "github.com/vitessio/vitess-releaser/go/releaser/utils" ) -const VERSION = "v1.0" +const VERSION = "v1.0.2" var ( releaseVersion string @@ -73,7 +73,7 @@ func init() { rootCmd.PersistentFlags().IntVarP(&rcIncrement, flags.RCIncrement, "", 0, "Define the release as an RC release, value is used to determine the number of the RC.") rootCmd.PersistentFlags().StringVarP(&releaseVersion, flags.MajorRelease, "r", "", "Number of the major release on which we want to create a new release.") rootCmd.PersistentFlags().StringVarP(&vtopReleaseVersion, flags.VtOpRelease, "", "", "Number of the major and minor release on which we want to create a new release, i.e. '2.11', leave empty for no vtop release.") - rootCmd.PersistentFlags().BoolVarP(&version, "version", "v", false, "Prints the version and git commit hash.") + rootCmd.PersistentFlags().BoolVarP(&version, "version", "v", false, "Prints the version.") err := cobra.MarkFlagRequired(rootCmd.PersistentFlags(), flags.MajorRelease) if err != nil { @@ -223,9 +223,7 @@ func getGitRepos() (vitessRepo, vtopRepo string) { } func printVersionAndExit() { - commit, shortHash := getGitCommit() - fmt.Printf("Version: %s.%s\n", VERSION, shortHash) - fmt.Printf("Last Commit: %s\n", commit) + fmt.Printf("Version: %s\n", VERSION) os.Exit(0) } diff --git a/main.go b/main.go index 9eda618..3d526e4 100644 --- a/main.go +++ b/main.go @@ -17,13 +17,76 @@ limitations under the License. package main import ( + "encoding/json" "fmt" - "github.com/vitessio/vitess-releaser/go/cmd" + "log" + "net/http" "os" "os/exec" "runtime/debug" + "time" + + "github.com/hashicorp/go-version" + "github.com/vitessio/vitess-releaser/go/cmd" ) +// Struct to hold the GitHub API response +type githubRelease struct { + TagName string `json:"tag_name"` +} + +// getLatestVersionFromGitHub queries the GitHub API for the latest release version +func getLatestVersionFromGitHub() (string, error) { + const url = "https://api.github.com/repos/vitessio/vitess-releaser/releases/latest" + + client := &http.Client{ + Timeout: 10 * time.Second, + } + + resp, err := client.Get(url) + if err != nil { + return "", fmt.Errorf("error fetching latest release info: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("failed to fetch latest version, status code: %d", resp.StatusCode) + } + + var release githubRelease + if err := json.NewDecoder(resp.Body).Decode(&release); err != nil { + return "", fmt.Errorf("error decoding response: %w", err) + } + + return release.TagName, nil +} + +// compareVersions checks if the current version is the latest and prints a message +func compareVersions() { + latestVersionStr, err := getLatestVersionFromGitHub() + if err != nil { + fmt.Println("Could not check for updates:", err.Error()) + os.Exit(1) + } + + currentVersion, err := version.NewVersion(cmd.VERSION[1:]) + if err != nil { + log.Fatalf("Error parsing current version: %v", err) + } + + latestVersion, err := version.NewVersion(latestVersionStr[1:]) + if err != nil { + log.Fatalf("Error parsing latest version: %v", err) + } + + if currentVersion.LessThan(latestVersion) { + fmt.Printf("A new version of the tool is available: %s (you have %s)\n", latestVersionStr, cmd.VERSION) + fmt.Println("Please update to the latest version.") + fmt.Println("\n\tgo install github.com/vitessio/vitess-releaser@latest\n") + os.Exit(1) + } +} + // On some shells the terminal is left in a bad state possibly because the debug output is large or // it contains control characters. This function restores the terminal to a sane state on a panic. func restoreTerminal() { @@ -43,5 +106,7 @@ func main() { } }() + compareVersions() + cmd.Execute() }