feat: incr sync version.
This commit is contained in:
57
go/chao-sdk-core/pkg/version/README.md
Normal file
57
go/chao-sdk-core/pkg/version/README.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# OpenIM SDK Version Management
|
||||
|
||||
OpenIM SDK uses a unique approach to version management by integrating principles from the Kubernetes project version management design.
|
||||
|
||||
## Versioning Methodology:
|
||||
|
||||
Whenever you run the server CTL via the `go build` command, the system will automatically obtain the current `git commit hash`. This commit hash is then set as the version number and written to the `pkg/version/version.go` file.
|
||||
|
||||
This approach ensures that each build is distinct and can be traced back to the specific commit hash from which it was built. It is a transparent and easy way to track changes and modifications across different versions of the SDK.
|
||||
|
||||
## How to Check Version:
|
||||
|
||||
- **Server Version**: Use the command `imctl version`.
|
||||
- **Client Version**: Execute the command `go run main.go version`.
|
||||
|
||||
## SDK Versioning:
|
||||
|
||||
1. **Traditional SDK Versioning**: The standard method of versioning that uses Major, Minor, and Patch numbers.
|
||||
2. **Client-Represented Versioning**: This is primarily managed through the Go versioning system. It helps in understanding the compatibility and dependencies.
|
||||
|
||||
## Code for Version Management:
|
||||
|
||||
### Utility to Compare Version Strings:
|
||||
|
||||
This function compares two version strings that follow the OpenIM versioning pattern.
|
||||
|
||||
```
|
||||
goCopy codefunc CompareOpenIMAwareVersionStrings(v1, v2 string) int {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### Information Structure for Version:
|
||||
|
||||
This struct contains various version-related information, making it easy to understand and process the build details.
|
||||
|
||||
```
|
||||
goCopy codetype Info struct {
|
||||
...
|
||||
}
|
||||
|
||||
func (info Info) String() string {
|
||||
...
|
||||
}
|
||||
|
||||
func Get() Info {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## Conclusion:
|
||||
|
||||
Effective version management is crucial for the growth and stability of any SDK. With OpenIM SDK's approach, users can be confident about the build's origin and its compatibility. The code snippets provided above can be utilized to integrate this versioning mechanism into any project seamlessly.
|
||||
|
||||
------
|
||||
|
||||
Hope this helps!
|
||||
47
go/chao-sdk-core/pkg/version/base.go
Normal file
47
go/chao-sdk-core/pkg/version/base.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package version
|
||||
|
||||
// Base version information.
|
||||
//
|
||||
// This is the fallback data used when version information from git is not
|
||||
// provided via go ldflags. It provides an approximation of the OpenIM
|
||||
// version for ad-hoc builds (e.g. `go build`) that cannot get the version
|
||||
// information from git.
|
||||
//
|
||||
// If you are looking at these fields in the git tree, they look
|
||||
// strange. They are modified on the fly by the build process. The
|
||||
// in-tree values are dummy values used for "git archive", which also
|
||||
// works for GitHub tar downloads.
|
||||
//
|
||||
// When releasing a new OpenIM version, this file is updated by
|
||||
// build/mark_new_version.sh to reflect the new version, and then a
|
||||
// git annotated tag (using format vX.Y where X == Major version and Y
|
||||
// == Minor version) is created to point to the commit that updates
|
||||
// pkg/version/base.go.
|
||||
var (
|
||||
// TODO: Deprecate gitMajor and gitMinor, use only gitVersion
|
||||
// instead. First step in deprecation, keep the fields but make
|
||||
// them irrelevant. (Next we'll take it out, which may muck with
|
||||
// scripts consuming the imctl version output - but most of
|
||||
// these should be looking at gitVersion already anyways.)
|
||||
gitMajor string = "" // major version, always numeric
|
||||
gitMinor string = "" // minor version, numeric possibly followed by "+"
|
||||
|
||||
// semantic version, derived by build scripts (see
|
||||
// https://git.k8s.io/community/contributors/design-proposals/release/versioning.md
|
||||
// for a detailed discussion of this field)
|
||||
//
|
||||
// TODO: This field is still called "gitVersion" for legacy
|
||||
// reasons. For prerelease versions, the build metadata on the
|
||||
// semantic version is a git hash, but the version itself is no
|
||||
// longer the direct output of "git describe", but a slight
|
||||
// translation to be semver compliant.
|
||||
|
||||
// NOTE: The $Format strings are replaced during 'git archive' thanks to the
|
||||
// companion .gitattributes file containing 'export-subst' in this same
|
||||
// directory. See also https://git-scm.com/docs/gitattributes
|
||||
gitVersion string = "v0.0.0-main+$Format:%h$"
|
||||
gitCommit string = "$Format:%H$" // sha1 from git, output of $(git rev-parse HEAD)
|
||||
gitTreeState string = "" // state of git tree, either "clean" or "dirty"
|
||||
|
||||
buildDate string = "1970-01-01T00:00:00Z" // build date in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ')
|
||||
)
|
||||
72
go/chao-sdk-core/pkg/version/helpers.go
Normal file
72
go/chao-sdk-core/pkg/version/helpers.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package version
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type versionType int
|
||||
|
||||
const (
|
||||
// Bigger the version type number, higher priority it is
|
||||
versionTypeAlpha versionType = iota
|
||||
versionTypeBeta
|
||||
versionTypeGA
|
||||
)
|
||||
|
||||
var OpenIMVersionRegex = regexp.MustCompile("^v([\\d]+)(?:(alpha|beta)([\\d]+))?$")
|
||||
|
||||
func parseOpenIMVersion(v string) (majorVersion int, vType versionType, minorVersion int, ok bool) {
|
||||
var err error
|
||||
submatches := OpenIMVersionRegex.FindStringSubmatch(v)
|
||||
if len(submatches) != 4 {
|
||||
return 0, 0, 0, false
|
||||
}
|
||||
switch submatches[2] {
|
||||
case "alpha":
|
||||
vType = versionTypeAlpha
|
||||
case "beta":
|
||||
vType = versionTypeBeta
|
||||
case "":
|
||||
vType = versionTypeGA
|
||||
default:
|
||||
return 0, 0, 0, false
|
||||
}
|
||||
if majorVersion, err = strconv.Atoi(submatches[1]); err != nil {
|
||||
return 0, 0, 0, false
|
||||
}
|
||||
if vType != versionTypeGA {
|
||||
if minorVersion, err = strconv.Atoi(submatches[3]); err != nil {
|
||||
return 0, 0, 0, false
|
||||
}
|
||||
}
|
||||
return majorVersion, vType, minorVersion, true
|
||||
}
|
||||
|
||||
// CompareOpenIMAwareVersionStrings compares two OpenIM-like version strings.
|
||||
// OpenIM-like version strings are starting with a v, followed by a major version, optional "alpha" or "beta" strings
|
||||
// followed by a minor version (e.g. v1, v2beta1). Versions will be sorted based on GA/alpha/beta first and then major
|
||||
// and minor versions. e.g. v2, v1, v1beta2, v1beta1, v1alpha1.
|
||||
func CompareOpenIMAwareVersionStrings(v1, v2 string) int {
|
||||
if v1 == v2 {
|
||||
return 0
|
||||
}
|
||||
v1major, v1type, v1minor, ok1 := parseOpenIMVersion(v1)
|
||||
v2major, v2type, v2minor, ok2 := parseOpenIMVersion(v2)
|
||||
switch {
|
||||
case !ok1 && !ok2:
|
||||
return strings.Compare(v2, v1)
|
||||
case !ok1 && ok2:
|
||||
return -1
|
||||
case ok1 && !ok2:
|
||||
return 1
|
||||
}
|
||||
if v1type != v2type {
|
||||
return int(v1type) - int(v2type)
|
||||
}
|
||||
if v1major != v2major {
|
||||
return v1major - v2major
|
||||
}
|
||||
return v1minor - v2minor
|
||||
}
|
||||
105
go/chao-sdk-core/pkg/version/helpers_test.go
Normal file
105
go/chao-sdk-core/pkg/version/helpers_test.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package version
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCompareOpenIMAwareVersionStrings(t *testing.T) {
|
||||
tests := []*struct {
|
||||
v1, v2 string
|
||||
expectedGreater bool
|
||||
}{
|
||||
{"v1", "v2", false},
|
||||
{"v2", "v1", true},
|
||||
{"v10", "v2", true},
|
||||
{"v1", "v2alpha1", true},
|
||||
{"v1", "v2beta1", true},
|
||||
{"v1alpha2", "v1alpha1", true},
|
||||
{"v1beta1", "v2alpha3", true},
|
||||
{"v1alpha10", "v1alpha2", true},
|
||||
{"v1beta10", "v1beta2", true},
|
||||
{"foo", "v1beta2", false},
|
||||
{"bar", "foo", true},
|
||||
{"version1", "version2", true}, // Non OpenIM-like versions are sorted alphabetically
|
||||
{"version1", "version10", true}, // Non OpenIM-like versions are sorted alphabetically
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
if e, a := tc.expectedGreater, CompareOpenIMAwareVersionStrings(tc.v1, tc.v2) > 0; e != a {
|
||||
if e {
|
||||
t.Errorf("expected %s to be greater than %s", tc.v1, tc.v2)
|
||||
} else {
|
||||
t.Errorf("expected %s to be less than %s", tc.v1, tc.v2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_parseOpenIMVersion(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
v string
|
||||
wantMajorVersion int
|
||||
wantVType versionType
|
||||
wantMinorVersion int
|
||||
wantOk bool
|
||||
}{
|
||||
{
|
||||
name: "invaild version for ga",
|
||||
v: "v1.1",
|
||||
wantMajorVersion: 0,
|
||||
wantVType: 0,
|
||||
wantMinorVersion: 0,
|
||||
wantOk: false,
|
||||
},
|
||||
{
|
||||
name: "invaild version for alpha",
|
||||
v: "v1alpha1.1",
|
||||
wantMajorVersion: 0,
|
||||
wantVType: 0,
|
||||
wantMinorVersion: 0,
|
||||
wantOk: false,
|
||||
},
|
||||
{
|
||||
name: "alpha version",
|
||||
v: "v1alpha1",
|
||||
wantMajorVersion: 1,
|
||||
wantVType: 0,
|
||||
wantMinorVersion: 1,
|
||||
wantOk: true,
|
||||
},
|
||||
{
|
||||
name: "beta version",
|
||||
v: "v2beta10",
|
||||
wantMajorVersion: 2,
|
||||
wantVType: 1,
|
||||
wantMinorVersion: 10,
|
||||
wantOk: true,
|
||||
},
|
||||
{
|
||||
name: "ga version",
|
||||
v: "v3",
|
||||
wantMajorVersion: 3,
|
||||
wantVType: 2,
|
||||
wantMinorVersion: 0,
|
||||
wantOk: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotMajorVersion, gotVType, gotMinorVersion, gotOk := parseOpenIMVersion(tt.v)
|
||||
if gotMajorVersion != tt.wantMajorVersion {
|
||||
t.Errorf("parseOpenIMVersion() gotMajorVersion = %v, want %v", gotMajorVersion, tt.wantMajorVersion)
|
||||
}
|
||||
if gotVType != tt.wantVType {
|
||||
t.Errorf("parseOpenIMVersion() gotVType = %v, want %v", gotVType, tt.wantVType)
|
||||
}
|
||||
if gotMinorVersion != tt.wantMinorVersion {
|
||||
t.Errorf("parseOpenIMVersion() gotMinorVersion = %v, want %v", gotMinorVersion, tt.wantMinorVersion)
|
||||
}
|
||||
if gotOk != tt.wantOk {
|
||||
t.Errorf("parseOpenIMVersion() gotOk = %v, want %v", gotOk, tt.wantOk)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
21
go/chao-sdk-core/pkg/version/types.go
Normal file
21
go/chao-sdk-core/pkg/version/types.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package version
|
||||
|
||||
// Info contains versioning information.
|
||||
// TODO: Add []string of api versions supported? It's still unclear
|
||||
// how we'll want to distribute that information.
|
||||
type Info struct {
|
||||
Major string `json:"major"`
|
||||
Minor string `json:"minor"`
|
||||
GitVersion string `json:"gitVersion"`
|
||||
GitCommit string `json:"gitCommit"`
|
||||
GitTreeState string `json:"gitTreeState"`
|
||||
BuildDate string `json:"buildDate"`
|
||||
GoVersion string `json:"goVersion"`
|
||||
Compiler string `json:"compiler"`
|
||||
Platform string `json:"platform"`
|
||||
}
|
||||
|
||||
// String returns info as a human-friendly version string.
|
||||
func (info Info) String() string {
|
||||
return info.GitVersion
|
||||
}
|
||||
24
go/chao-sdk-core/pkg/version/version.go
Normal file
24
go/chao-sdk-core/pkg/version/version.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package version
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// Get returns the overall codebase version. It's for detecting
|
||||
// what code a binary was built from.
|
||||
func Get() Info {
|
||||
// These variables typically come from -ldflags settings and in
|
||||
// their absence fallback to the settings in pkg/version/base.go
|
||||
return Info{
|
||||
Major: gitMajor,
|
||||
Minor: gitMinor,
|
||||
GitVersion: gitVersion,
|
||||
GitCommit: gitCommit,
|
||||
GitTreeState: gitTreeState,
|
||||
BuildDate: buildDate,
|
||||
GoVersion: runtime.Version(),
|
||||
Compiler: runtime.Compiler,
|
||||
Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user