From 86b965a3c4df423d40a276170e7450587995a5ca Mon Sep 17 00:00:00 2001 From: Ben Schumacher Date: Fri, 20 Oct 2023 11:23:05 +0200 Subject: [PATCH] [MM-53256] Use buildinfo instead of env variables for mmctl (#23794) --- server/Makefile | 25 +------- server/cmd/mmctl/commands/version.go | 77 +++++++++++++++++------ server/cmd/mmctl/commands/version_test.go | 29 +++++++++ 3 files changed, 90 insertions(+), 41 deletions(-) create mode 100644 server/cmd/mmctl/commands/version_test.go diff --git a/server/Makefile b/server/Makefile index 88b560458b..f8fb8d17e7 100644 --- a/server/Makefile +++ b/server/Makefile @@ -34,12 +34,6 @@ BUILD_NUMBER ?= $(BUILD_NUMBER:) BUILD_DATE = $(shell date -u) BUILD_HASH = $(shell git rev-parse HEAD) -# treestate -GIT_TREESTATE = clean -DIFF = $(shell git diff --quiet >/dev/null 2>&1; if [ $$? -eq 1 ]; then echo "1"; fi) -ifeq ($(DIFF), 1) - GIT_TREESTATE = dirty -endif # Docker export COMPOSE_PROJECT_NAME=mattermost-server @@ -62,9 +56,8 @@ GOTESTSUM_JSONFILE ?= gotestsum.json MMCTL_BUILD_TAGS = MMCTL_TESTFLAGS ?= -timeout 30m MMCTL_PKG = github.com/mattermost/mattermost/server/v8/cmd/mmctl/commands -LDFLAGS += -X "$(MMCTL_PKG).gitCommit=$(BUILD_HASH)" -LDFLAGS += -X "$(MMCTL_PKG).gitTreeState=$(GIT_TREESTATE)" -LDFLAGS += -X "$(MMCTL_PKG).buildDate=$(BUILD_DATE)" +MMCTL_BUILD_DATE = $(shell date -u +'%Y-%m-%dT%H:%M:%SZ') +MMCTL_LDFLAGS += -X "$(MMCTL_PKG).buildDate=$(MMCTL_BUILD_DATE)" # Enterprise BUILD_ENTERPRISE_DIR ?= ../../enterprise @@ -91,18 +84,6 @@ endif # Webapp BUILD_WEBAPP_DIR ?= ../webapp -BUILD_CLIENT = false -BUILD_HASH_CLIENT = independent -ifneq ($(wildcard $(BUILD_WEBAPP_DIR)/.),) - ifeq ($(BUILD_CLIENT),true) - BUILD_CLIENT = true - BUILD_HASH_CLIENT = $(shell cd $(BUILD_WEBAPP_DIR) && git rev-parse HEAD) - else - BUILD_CLIENT = false - endif -else - BUILD_CLIENT = false -endif # We need current user's UID for `run-haserver` so docker compose does not run server # as root and mess up file permissions for devs. When running like this HOME will be blank @@ -813,7 +794,7 @@ ifeq ($(BUILD_ENTERPRISE_READY),true) endif mmctl-build: ## Compiles and generates the mmctl binary - go build -trimpath -ldflags '$(LDFLAGS)' -o bin/mmctl ./cmd/mmctl + go build -trimpath -ldflags '$(MMCTL_LDFLAGS)' -o bin/mmctl ./cmd/mmctl mmctl-docs: ## Generate the mmctl docs rm -rf ./cmd/mmctl/docs diff --git a/server/cmd/mmctl/commands/version.go b/server/cmd/mmctl/commands/version.go index 5b2dd991ff..8fd4699675 100644 --- a/server/cmd/mmctl/commands/version.go +++ b/server/cmd/mmctl/commands/version.go @@ -5,22 +5,19 @@ package commands import ( "fmt" - "runtime" + "runtime/debug" "github.com/mattermost/mattermost/server/public/model" "github.com/mattermost/mattermost/server/v8/cmd/mmctl/printer" + "github.com/pkg/errors" "github.com/spf13/cobra" ) var ( Version = model.CurrentVersion - // SHA1 from git, output of $(git rev-parse HEAD) - gitCommit = "dev mode" - // State of git tree, either "clean" or "dirty" - gitTreeState = "unknown" // Build date in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ') - buildDate = "unknown" + buildDate = "dev" ) var VersionCmd = &cobra.Command{ @@ -34,31 +31,73 @@ func init() { } func versionCmdF(cmd *cobra.Command, args []string) error { - v := getVersionInfo() - printer.PrintT("mmctl:\nVersion:\t{{.Version}}\nGitCommit:\t{{.GitCommit}}"+ - "\nGitTreeState:\t{{.GitTreeState}}\nBuildDate:\t{{.BuildDate}}\nGoVersion:\t{{.GoVersion}}"+ + v, err := getVersionInfo() + if err != nil { + return err + } + + printer.PrintT("mmctl:\nVersion:\t{{.Version}}\nBuiltDate:\t{{.BuildDate}}\nCommitDate:\t{{.CommitDate}}\nGitCommit:\t{{.GitCommit}}"+ + "\nGitTreeState:\t{{.GitTreeState}}\nGoVersion:\t{{.GoVersion}}"+ "\nCompiler:\t{{.Compiler}}\nPlatform:\t{{.Platform}}", v) return nil } type Info struct { Version string + BuildDate string + CommitDate string GitCommit string GitTreeState string - BuildDate string GoVersion string Compiler string Platform string } -func getVersionInfo() Info { - return Info{ - Version: Version, - GitCommit: gitCommit, - GitTreeState: gitTreeState, - BuildDate: buildDate, - GoVersion: runtime.Version(), - Compiler: runtime.Compiler, - Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH), +func getVersionInfo() (*Info, error) { + info, ok := debug.ReadBuildInfo() + if !ok { + return nil, errors.New("failed to get build info") } + + var ( + revision = "dev" + gitTreeState = "dev" + commitDate = "dev" + + os string + arch string + compiler string + ) + + for _, s := range info.Settings { + switch s.Key { + case "vcs.revision": + revision = s.Value + case "vcs.time": + commitDate = s.Value + case "vcs.modified": + if s.Value == "true" { + gitTreeState = "dirty" + } else { + gitTreeState = "clean" + } + case "GOOS": + os = s.Value + case "GOARCH": + arch = s.Value + case "-compiler": + compiler = s.Value + } + } + + return &Info{ + Version: Version, + BuildDate: buildDate, + CommitDate: commitDate, + GitCommit: revision, + GitTreeState: gitTreeState, + GoVersion: info.GoVersion, + Compiler: compiler, + Platform: fmt.Sprintf("%s/%s", arch, os), + }, nil } diff --git a/server/cmd/mmctl/commands/version_test.go b/server/cmd/mmctl/commands/version_test.go new file mode 100644 index 0000000000..fc742419cb --- /dev/null +++ b/server/cmd/mmctl/commands/version_test.go @@ -0,0 +1,29 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. +package commands + +import ( + "github.com/spf13/cobra" + + "github.com/mattermost/mattermost/server/v8/cmd/mmctl/printer" +) + +func (s *MmctlUnitTestSuite) TestVersionCmd() { + printer.Clean() + printer.SetFormat(printer.FormatPlain) + + err := versionCmdF(&cobra.Command{}, []string{}) + s.Require().NoError(err) + s.Require().Len(printer.GetErrorLines(), 0) + s.Require().Len(printer.GetLines(), 1) + line := printer.GetLines()[0] + s.Require().Contains(line, "mmctl:") + s.Require().Contains(line, "Version:") + s.Require().Contains(line, "BuiltDate:") + s.Require().Contains(line, "CommitDate:") + s.Require().Contains(line, "GitTreeState:") + s.Require().Contains(line, "GoVersion:") + s.Require().Contains(line, " go1.") + s.Require().Contains(line, "Compiler:") + s.Require().Contains(line, "Platform:") +}