feat: incr sync version.

This commit is contained in:
Gordon
2024-06-24 17:48:33 +08:00
parent e8ccae6349
commit 88b8043224
308 changed files with 55952 additions and 59 deletions

View 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!

View 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')
)

View 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
}

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

View 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
}

View 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),
}
}