mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: add version to footer (#882)
* Add endpoint for getting build info * Add build info XService * Add version with link to page footer Partially addresses #376. * Lift buildinfo package
This commit is contained in:
@@ -1,83 +0,0 @@
|
||||
package buildinfo
|
||||
|
||||
import (
|
||||
"path"
|
||||
"runtime/debug"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/mod/semver"
|
||||
)
|
||||
|
||||
var (
|
||||
buildInfo *debug.BuildInfo
|
||||
buildInfoValid bool
|
||||
readBuildInfo sync.Once
|
||||
|
||||
// Injected with ldflags at build!
|
||||
tag string
|
||||
)
|
||||
|
||||
// Version returns the semantic version of the build.
|
||||
// Use golang.org/x/mod/semver to compare versions.
|
||||
func Version() string {
|
||||
revision, valid := revision()
|
||||
if valid {
|
||||
revision = "+" + revision[:7]
|
||||
}
|
||||
if tag == "" {
|
||||
return "v0.0.0-devel" + revision
|
||||
}
|
||||
if semver.Build(tag) == "" {
|
||||
tag += revision
|
||||
}
|
||||
return "v" + tag
|
||||
}
|
||||
|
||||
// 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.
|
||||
func ExternalURL() string {
|
||||
repo := "https://github.com/coder/coder"
|
||||
revision, valid := revision()
|
||||
if !valid {
|
||||
return repo
|
||||
}
|
||||
return path.Join(repo, "commit", revision)
|
||||
}
|
||||
|
||||
// Time returns when the Git revision was published.
|
||||
func Time() (time.Time, bool) {
|
||||
value, valid := find("vcs.time")
|
||||
if !valid {
|
||||
return time.Time{}, false
|
||||
}
|
||||
parsed, err := time.Parse(time.RFC3339, value)
|
||||
if err != nil {
|
||||
panic("couldn't parse time: " + err.Error())
|
||||
}
|
||||
return parsed, true
|
||||
}
|
||||
|
||||
// revision returns the Git hash of the build.
|
||||
func revision() (string, bool) {
|
||||
return find("vcs.revision")
|
||||
}
|
||||
|
||||
// find panics if a setting with the specific key was not
|
||||
// found in the build info.
|
||||
func find(key string) (string, bool) {
|
||||
readBuildInfo.Do(func() {
|
||||
buildInfo, buildInfoValid = debug.ReadBuildInfo()
|
||||
})
|
||||
if !buildInfoValid {
|
||||
panic("couldn't read build info")
|
||||
}
|
||||
for _, setting := range buildInfo.Settings {
|
||||
if setting.Key != key {
|
||||
continue
|
||||
}
|
||||
return setting.Value, true
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package buildinfo_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/mod/semver"
|
||||
|
||||
"github.com/coder/coder/cli/buildinfo"
|
||||
)
|
||||
|
||||
func TestBuildInfo(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("Version", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
version := buildinfo.Version()
|
||||
require.True(t, semver.IsValid(version))
|
||||
prerelease := semver.Prerelease(version)
|
||||
require.Equal(t, "-devel", prerelease)
|
||||
require.Equal(t, "v0", semver.Major(version))
|
||||
})
|
||||
t.Run("ExternalURL", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
require.Equal(t, "https://github.com/coder/coder", buildinfo.ExternalURL())
|
||||
})
|
||||
// Tests don't include Go build info.
|
||||
t.Run("NoTime", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, valid := buildinfo.Time()
|
||||
require.False(t, valid)
|
||||
})
|
||||
}
|
||||
+1
-1
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/mattn/go-isatty"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/coder/coder/cli/buildinfo"
|
||||
"github.com/coder/coder/buildinfo"
|
||||
"github.com/coder/coder/cli/cliui"
|
||||
"github.com/coder/coder/cli/config"
|
||||
"github.com/coder/coder/codersdk"
|
||||
|
||||
Reference in New Issue
Block a user