From ad6fb844aadddbf614a4fdc26ae34b38c1226367 Mon Sep 17 00:00:00 2001 From: Igor Gov Date: Sun, 6 Feb 2022 15:01:36 +0200 Subject: [PATCH] Moving from Semver to major.patch versioning (#755) * Moving from Semver to major.patch versions * version check should work with new version forma Co-authored-by: Igor Gov --- .github/workflows/release.yml | 47 +++++++------- cli/cmd/version.go | 4 +- cli/config/configStruct.go | 2 +- cli/mizu/consts.go | 2 +- cli/mizu/version/versionCheck.go | 32 +++++----- cli/pkg/version/version.go | 85 +++++++++++++++++++++++++ cli/pkg/version/version_test.go | 104 +++++++++++++++++++++++++++++++ cli/telemetry/telemetry.go | 2 +- 8 files changed, 234 insertions(+), 44 deletions(-) create mode 100644 cli/pkg/version/version.go create mode 100644 cli/pkg/version/version_test.go diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0bf858283..84511042b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,14 +32,15 @@ jobs: id: condval with: cond: ${{ github.ref == 'refs/heads/main' }} - if_true: "minor" - if_false: "patch" + if_true: "stable" + if_false: "dev" - - name: Auto increment SemVer action - uses: MCKanpolat/auto-semver-action@1.0.5 + - name: Auto Increment Ver Action + uses: docker://igorgov/auto-inc-ver:v2.0.0 id: versioning with: - releaseType: ${{ steps.condval.outputs.value }} + mode: ${{ steps.condval.outputs.value }} + suffix: 'dev' github_token: ${{ secrets.GITHUB_TOKEN }} - name: Get version parameters @@ -109,14 +110,15 @@ jobs: id: condval with: cond: ${{ github.ref == 'refs/heads/main' }} - if_true: "minor" - if_false: "patch" + if_true: "stable" + if_false: "dev" - - name: Auto increment SemVer action - uses: MCKanpolat/auto-semver-action@1.0.5 + - name: Auto Increment Ver Action + uses: docker://igorgov/auto-inc-ver:vv2.0.0 id: versioning with: - releaseType: ${{ steps.condval.outputs.value }} + mode: ${{ steps.condval.outputs.value }} + suffix: 'dev' github_token: ${{ secrets.GITHUB_TOKEN }} - name: Get version parameters @@ -175,14 +177,15 @@ jobs: id: condval with: cond: ${{ github.ref == 'refs/heads/main' }} - if_true: "minor" - if_false: "patch" + if_true: "stable" + if_false: "dev" - - name: Auto increment SemVer action - uses: MCKanpolat/auto-semver-action@1.0.5 + - name: Auto Increment Ver Action + uses: docker://igorgov/auto-inc-ver:vv2.0.0 id: versioning with: - releaseType: ${{ steps.condval.outputs.value }} + mode: ${{ steps.condval.outputs.value }} + suffix: 'dev' github_token: ${{ secrets.GITHUB_TOKEN }} - name: Get version parameters @@ -238,18 +241,20 @@ jobs: service_account_key: ${{ secrets.GCR_JSON_KEY }} export_default_credentials: true - - uses: haya14busa/action-cond@v1 + - name: Determine versioning strategy + uses: haya14busa/action-cond@v1 id: condval with: cond: ${{ github.ref == 'refs/heads/main' }} - if_true: "minor" - if_false: "patch" + if_true: "stable" + if_false: "dev" - - name: Auto Increment Semver Action - uses: MCKanpolat/auto-semver-action@1.0.5 + - name: Auto Increment Ver Action + uses: docker://igorgov/auto-inc-ver:v2.0.0 id: versioning with: - releaseType: ${{ steps.condval.outputs.value }} + mode: ${{ steps.condval.outputs.value }} + suffix: 'dev' github_token: ${{ secrets.GITHUB_TOKEN }} - name: Get version parameters diff --git a/cli/cmd/version.go b/cli/cmd/version.go index 8aa32b3b3..a3a1e3ccf 100644 --- a/cli/cmd/version.go +++ b/cli/cmd/version.go @@ -22,11 +22,11 @@ var versionCmd = &cobra.Command{ if config.Config.Version.DebugInfo { timeStampInt, _ := strconv.ParseInt(mizu.BuildTimestamp, 10, 0) - logger.Log.Infof("Version: %s \nBranch: %s (%s)", mizu.SemVer, mizu.Branch, mizu.GitCommitHash) + logger.Log.Infof("Version: %s \nBranch: %s (%s)", mizu.Ver, mizu.Branch, mizu.GitCommitHash) logger.Log.Infof("Build Time: %s (%s)", mizu.BuildTimestamp, time.Unix(timeStampInt, 0)) } else { - logger.Log.Infof("Version: %s (%s)", mizu.SemVer, mizu.Branch) + logger.Log.Infof("Version: %s (%s)", mizu.Ver, mizu.Branch) } return nil }, diff --git a/cli/config/configStruct.go b/cli/config/configStruct.go index 9d299f209..0c82546d0 100644 --- a/cli/config/configStruct.go +++ b/cli/config/configStruct.go @@ -54,7 +54,7 @@ func (config *ConfigStruct) validate() error { func (config *ConfigStruct) SetDefaults() { config.KratosImage = shared.KratosImageDefault config.KetoImage = shared.KetoImageDefault - config.AgentImage = fmt.Sprintf("%s:%s", shared.MizuAgentImageRepo, mizu.SemVer) + config.AgentImage = fmt.Sprintf("%s:%s", shared.MizuAgentImageRepo, mizu.Ver) config.ConfigFilePath = path.Join(mizu.GetMizuFolderPath(), "config.yaml") } diff --git a/cli/mizu/consts.go b/cli/mizu/consts.go index cf67a5ab4..11fd3d690 100644 --- a/cli/mizu/consts.go +++ b/cli/mizu/consts.go @@ -6,7 +6,7 @@ import ( ) var ( - SemVer = "0.0.1" + Ver = "0.0" Branch = "develop" GitCommitHash = "" // this var is overridden using ldflags in makefile when building BuildTimestamp = "" // this var is overridden using ldflags in makefile when building diff --git a/cli/mizu/version/versionCheck.go b/cli/mizu/version/versionCheck.go index 93d32d4d7..949361aeb 100644 --- a/cli/mizu/version/versionCheck.go +++ b/cli/mizu/version/versionCheck.go @@ -12,31 +12,28 @@ import ( "github.com/up9inc/mizu/cli/apiserver" "github.com/up9inc/mizu/cli/mizu" + "github.com/up9inc/mizu/cli/pkg/version" "github.com/up9inc/mizu/shared/logger" "github.com/google/go-github/v37/github" "github.com/up9inc/mizu/cli/uiUtils" - "github.com/up9inc/mizu/shared/semver" ) func CheckVersionCompatibility(apiServerProvider *apiserver.Provider) (bool, error) { - apiSemVer, err := apiServerProvider.GetVersion() + apiVer, err := apiServerProvider.GetVersion() if err != nil { return false, err } - if !semver.SemVersion(apiSemVer).IsValid() { - logger.Log.Errorf(uiUtils.Red, fmt.Sprintf("api version (%s) is not a valid SemVer", apiSemVer)) + if equals, err := version.AreEquals(apiVer, mizu.Ver); err != nil { + return false, fmt.Errorf("Failed to check version equality between mizuVer: %s and apiVer: %s, error: %w", mizu.Ver, apiVer, err) + } else if !equals { + logger.Log.Errorf(uiUtils.Red, fmt.Sprintf("cli version (%s) is not compatible with api version (%s)", mizu.Ver, apiVer)) return false, nil } - if semver.SemVersion(apiSemVer).Major() == semver.SemVersion(mizu.SemVer).Major() && - semver.SemVersion(apiSemVer).Minor() == semver.SemVersion(mizu.SemVer).Minor() { - return true, nil - } - - logger.Log.Errorf(uiUtils.Red, fmt.Sprintf("cli version (%s) is not compatible with api version (%s)", mizu.SemVer, apiSemVer)) - return false, nil + logger.Log.Debug("cli version %s is compatible with api version %s", mizu.Ver, apiVer) + return true, nil } func CheckNewerVersion(versionChan chan string) { @@ -84,24 +81,23 @@ func CheckNewerVersion(versionChan chan string) { gitHubVersion := string(data) gitHubVersion = gitHubVersion[:len(gitHubVersion)-1] - gitHubVersionSemVer := semver.SemVersion(gitHubVersion) - currentSemVer := semver.SemVersion(mizu.SemVer) - if !gitHubVersionSemVer.IsValid() || !currentSemVer.IsValid() { - logger.Log.Debugf("[ERROR] Semver version is not valid, github version %v, current version %v", gitHubVersion, currentSemVer) + greater, err := version.GreaterThen(gitHubVersion, mizu.Ver) + if err != nil { + logger.Log.Debugf("[ERROR] Semver version is not valid, github version %v, current version %v", gitHubVersion, mizu.Ver) versionChan <- "" return } - logger.Log.Debugf("Finished version validation, github version %v, current version %v, took %v", gitHubVersion, currentSemVer, time.Since(start)) + logger.Log.Debugf("Finished version validation, github version %v, current version %v, took %v", gitHubVersion, mizu.Ver, time.Since(start)) - if gitHubVersionSemVer.GreaterThan(currentSemVer) { + if greater { var downloadMessage string if runtime.GOOS == "windows" { downloadMessage = fmt.Sprintf("curl -LO %v/mizu.exe", strings.Replace(*latestRelease.HTMLURL, "tag", "download", 1)) } else { downloadMessage = fmt.Sprintf("curl -Lo mizu %v/mizu_%s_%s && chmod 755 mizu", strings.Replace(*latestRelease.HTMLURL, "tag", "download", 1), runtime.GOOS, runtime.GOARCH) } - versionChan <- fmt.Sprintf("Update available! %v -> %v (%s)", mizu.SemVer, gitHubVersion, downloadMessage) + versionChan <- fmt.Sprintf("Update available! %v -> %v (%s)", mizu.Ver, gitHubVersion, downloadMessage) } else { versionChan <- "" } diff --git a/cli/pkg/version/version.go b/cli/pkg/version/version.go new file mode 100644 index 000000000..2de444c01 --- /dev/null +++ b/cli/pkg/version/version.go @@ -0,0 +1,85 @@ +package version + +import ( + "fmt" + "regexp" + "strconv" +) + +type Version struct { + Major int + Patch int + Incremental int +} + +func Parse(ver string) (*Version, error) { + re := regexp.MustCompile(`^(\d+)\.(\d+)(?:-\w+(\d+))?$`) + match := re.FindStringSubmatch(ver) + if len(match) != 4 { + return nil, fmt.Errorf("invalid format expected .(-)? %s,", ver) + } + major, err := strconv.Atoi(match[1]) + if err != nil { + return nil, fmt.Errorf("error parsing major int: %s, err %w", match[1], err) + } + patch, err := strconv.Atoi(match[2]) + if err != nil { + return nil, fmt.Errorf("error parsing patch int: %s, err %w", match[2], err) + } + + if match[3] == "" { + return &Version{Major: major, Patch: patch, Incremental: -1}, nil + } + + inc, err := strconv.Atoi(match[3]) + if err != nil { + return nil, fmt.Errorf("Error parsing incremental int: %s, err %w", match[3], err) + } + return &Version{Major: major, Patch: patch, Incremental: inc}, nil + +} + +func AreEquals(first string, second string) (bool, error) { + firstVer, err := Parse(first) + if err != nil { + return false, fmt.Errorf("Failed parsing fist version: %s, error: %w", first, err) + } + secondVer, err := Parse(second) + if err != nil { + return false, fmt.Errorf("Failed parsing second version: %s, error: %w", second, err) + } + + return *firstVer == *secondVer, nil +} + +func GreaterThen(first string, second string) (bool, error) { + firstVer, err := Parse(first) + if err != nil { + return false, fmt.Errorf("Failed parsing fist version: %s, error: %w", first, err) + } + secondVer, err := Parse(second) + if err != nil { + return false, fmt.Errorf("Failed parsing second version: %s, error: %w", second, err) + } + + if firstVer.Major > secondVer.Major { + return true, nil + } else if firstVer.Major < secondVer.Major { + return false, nil + } + + if firstVer.Patch > secondVer.Patch { + return true, nil + } else if firstVer.Patch < secondVer.Patch { + return false, nil + } + + if firstVer.Incremental == -1 && secondVer.Incremental > -1 { + return true, nil + } + + if firstVer.Incremental > secondVer.Incremental { + return true, nil + } + return false, nil +} diff --git a/cli/pkg/version/version_test.go b/cli/pkg/version/version_test.go new file mode 100644 index 000000000..a08fee0ba --- /dev/null +++ b/cli/pkg/version/version_test.go @@ -0,0 +1,104 @@ +package version + +import ( + "testing" +) + +func TestEqualsEquality(t *testing.T) { + tests := []struct { + Name string + First string + Second string + }{ + {Name: "major", First: "1.0", Second: "1.0"}, + {Name: "patch", First: "1.1", Second: "1.1"}, + {Name: "incremental", First: "1.0-dev0", Second: "1.0-dev0"}, + } + for _, test := range tests { + t.Run(test.Name, func(t *testing.T) { + if equal, _ := AreEquals(test.First, test.Second); !equal { + t.Fatalf("Expected %s == %s", test.First, test.Second) + } + }) + } +} + +func TestEqualsInvalidVersion(t *testing.T) { + tests := []struct { + Name string + First string + Second string + }{ + {Name: "first semver", First: "1.0.0", Second: "1.0"}, + {Name: "second semver", First: "1.1", Second: "1.1.0"}, + {Name: "incremental invalid", First: "1.0-dev0de", Second: "1.0-dev0"}, + } + for _, test := range tests { + t.Run(test.Name, func(t *testing.T) { + if _, err := AreEquals(test.First, test.Second); err == nil { + t.Fatalf("Expected error") + } + }) + } +} + +func TestEqualsNoEquality(t *testing.T) { + tests := []struct { + Name string + First string + Second string + }{ + {Name: "major", First: "1.0", Second: "2.0"}, + {Name: "patch", First: "1.0", Second: "1.1"}, + {Name: "incremental", First: "1.0-dev2", Second: "1.0-dev3"}, + } + for _, test := range tests { + t.Run(test.Name, func(t *testing.T) { + if equal, _ := AreEquals(test.First, test.Second); equal { + t.Fatalf("Expected %s != %s", test.First, test.Second) + } + }) + } +} + +func TestGreaterThenGreater(t *testing.T) { + tests := []struct { + Name string + First string + Second string + }{ + {Name: "major", First: "2.0", Second: "1.0"}, + {Name: "patch", First: "1.1", Second: "1.0"}, + {Name: "incremental", First: "1.0-dev1", Second: "1.0-dev0"}, + {Name: "major vs incremental", First: "1.0", Second: "1.0-dev1"}, + } + for _, test := range tests { + t.Run(test.Name, func(t *testing.T) { + if greater, _ := GreaterThen(test.First, test.Second); !greater { + t.Fatalf("Expected %s > %s", test.First, test.Second) + } + }) + } +} + +func TestGreaterThenLessThen(t *testing.T) { + tests := []struct { + Name string + First string + Second string + }{ + {Name: "major", First: "1.0", Second: "2.0"}, + {Name: "major equals", First: "1.0", Second: "1.0"}, + {Name: "patch", First: "1.0", Second: "1.1"}, + {Name: "patch equals", First: "1.1", Second: "1.1"}, + {Name: "incremental", First: "1.0-dev0", Second: "1.0-dev1"}, + {Name: "incremental equals", First: "1.0-dev0", Second: "1.0-dev0"}, + } + for _, test := range tests { + t.Run(test.Name, func(t *testing.T) { + if greater, _ := GreaterThen(test.First, test.Second); greater { + t.Fatalf("Expected %s < %s", test.First, test.Second) + } + }) + } +} diff --git a/cli/telemetry/telemetry.go b/cli/telemetry/telemetry.go index 3eeab29d2..cc7e68202 100644 --- a/cli/telemetry/telemetry.go +++ b/cli/telemetry/telemetry.go @@ -83,7 +83,7 @@ func sendTelemetry(argsMap map[string]interface{}) error { argsMap["component"] = "mizu_cli" argsMap["buildTimestamp"] = mizu.BuildTimestamp argsMap["branch"] = mizu.Branch - argsMap["version"] = mizu.SemVer + argsMap["version"] = mizu.Ver argsMap["platform"] = mizu.Platform if machineId, err := machineid.ProtectedID("mizu"); err == nil {