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 <igor.govorov1@gmail.com>
This commit is contained in:
Igor Gov 2022-02-06 15:01:36 +02:00 committed by GitHub
parent 9cddb0c7e8
commit ad6fb844aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 234 additions and 44 deletions

View File

@ -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

View File

@ -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
},

View File

@ -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")
}

View File

@ -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

View File

@ -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 <- ""
}

View File

@ -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 <major>.<patch>(-<suffix><incremental>)? %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
}

View File

@ -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)
}
})
}
}

View File

@ -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 {