diff --git a/buildinfo/buildinfo.go b/buildinfo/buildinfo.go index b748b4f426..bce2e5bb0c 100644 --- a/buildinfo/buildinfo.go +++ b/buildinfo/buildinfo.go @@ -1,7 +1,7 @@ package buildinfo import ( - "path" + "fmt" "runtime/debug" "sync" "time" @@ -14,6 +14,12 @@ var ( buildInfoValid bool readBuildInfo sync.Once + externalURL string + readExternalURL sync.Once + + version string + readVersion sync.Once + // Injected with ldflags at build! tag string ) @@ -21,29 +27,37 @@ var ( // 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 + readVersion.Do(func() { + revision, valid := revision() + if valid { + revision = "+" + revision[:7] + } + if tag == "" { + version = "v0.0.0-devel" + revision + return + } + if semver.Build(tag) == "" { + tag += revision + } + version = "v" + tag + }) + return version } // 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) + readExternalURL.Do(func() { + repo := "https://github.com/coder/coder" + revision, valid := revision() + if !valid { + externalURL = repo + return + } + externalURL = fmt.Sprintf("%s/commit/%s", repo, revision) + }) + return externalURL } // Time returns when the Git revision was published. diff --git a/provisionerd/provisionerd_test.go b/provisionerd/provisionerd_test.go index 776e3730a4..e38df5cf70 100644 --- a/provisionerd/provisionerd_test.go +++ b/provisionerd/provisionerd_test.go @@ -501,6 +501,7 @@ func TestProvisionerd(t *testing.T) { t.Run("ShutdownFromJob", func(t *testing.T) { t.Parallel() + var completed sync.Once var updated sync.Once updateChan := make(chan struct{}) completeChan := make(chan struct{}) @@ -532,7 +533,9 @@ func TestProvisionerd(t *testing.T) { }, nil }, failJob: func(ctx context.Context, job *proto.FailedJob) (*proto.Empty, error) { - close(completeChan) + completed.Do(func() { + close(completeChan) + }) return &proto.Empty{}, nil }, }), nil