mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
feat: add version checking to CLI (#2643)
* feat: add version checking to CLI
This commit is contained in:
+21
-1
@@ -3,6 +3,7 @@ package buildinfo
|
||||
import (
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -24,6 +25,11 @@ var (
|
||||
tag string
|
||||
)
|
||||
|
||||
const (
|
||||
// develPrefix is prefixed to developer versions of the application.
|
||||
develPrefix = "v0.0.0-devel"
|
||||
)
|
||||
|
||||
// Version returns the semantic version of the build.
|
||||
// Use golang.org/x/mod/semver to compare versions.
|
||||
func Version() string {
|
||||
@@ -35,7 +41,7 @@ func Version() string {
|
||||
if tag == "" {
|
||||
// This occurs when the tag hasn't been injected,
|
||||
// like when using "go run".
|
||||
version = "v0.0.0-devel" + revision
|
||||
version = develPrefix + revision
|
||||
return
|
||||
}
|
||||
version = "v" + tag
|
||||
@@ -48,6 +54,20 @@ func Version() string {
|
||||
return version
|
||||
}
|
||||
|
||||
// VersionsMatch compares the two versions. It assumes the versions match if
|
||||
// the major and the minor versions are equivalent. Patch versions are
|
||||
// disregarded. If it detects that either version is a developer build it
|
||||
// returns true.
|
||||
func VersionsMatch(v1, v2 string) bool {
|
||||
// Developer versions are disregarded...hopefully they know what they are
|
||||
// doing.
|
||||
if strings.HasPrefix(v1, develPrefix) || strings.HasPrefix(v2, develPrefix) {
|
||||
return true
|
||||
}
|
||||
|
||||
return semver.MajorMinor(v1) == semver.MajorMinor(v2)
|
||||
}
|
||||
|
||||
// ExternalURL returns a URL referencing the current Coder version.
|
||||
// For production builds, this will link directly to a release.
|
||||
// For development builds, this will link to a commit.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package buildinfo_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -29,4 +30,70 @@ func TestBuildInfo(t *testing.T) {
|
||||
_, valid := buildinfo.Time()
|
||||
require.False(t, valid)
|
||||
})
|
||||
|
||||
t.Run("VersionsMatch", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
type testcase struct {
|
||||
name string
|
||||
v1 string
|
||||
v2 string
|
||||
expectMatch bool
|
||||
}
|
||||
|
||||
cases := []testcase{
|
||||
{
|
||||
name: "OK",
|
||||
v1: "v1.2.3",
|
||||
v2: "v1.2.3",
|
||||
expectMatch: true,
|
||||
},
|
||||
// Test that we return true if a developer version is detected.
|
||||
// Developers do not need to be warned of mismatched versions.
|
||||
{
|
||||
name: "DevelIgnored",
|
||||
v1: "v0.0.0-devel+123abac",
|
||||
v2: "v1.2.3",
|
||||
expectMatch: true,
|
||||
},
|
||||
// Our CI instance uses a "-devel" prerelease
|
||||
// flag. This is not the same as a developer WIP build.
|
||||
{
|
||||
name: "DevelPreleaseNotIgnored",
|
||||
v1: "v1.1.1-devel+123abac",
|
||||
v2: "v1.2.3",
|
||||
expectMatch: false,
|
||||
},
|
||||
{
|
||||
name: "MajorMismatch",
|
||||
v1: "v1.2.3",
|
||||
v2: "v0.1.2",
|
||||
expectMatch: false,
|
||||
},
|
||||
{
|
||||
name: "MinorMismatch",
|
||||
v1: "v1.2.3",
|
||||
v2: "v1.3.2",
|
||||
expectMatch: false,
|
||||
},
|
||||
// Different patches are ok, breaking changes are not allowed
|
||||
// in patches.
|
||||
{
|
||||
name: "PatchMismatch",
|
||||
v1: "v1.2.3+hash.whocares",
|
||||
v2: "v1.2.4+somestuff.hm.ok",
|
||||
expectMatch: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
c := c
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
require.Equal(t, c.expectMatch, buildinfo.VersionsMatch(c.v1, c.v2),
|
||||
fmt.Sprintf("expected match=%v for version %s and %s", c.expectMatch, c.v1, c.v2),
|
||||
)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user