diff --git a/.github/workflows/server-ci.yml b/.github/workflows/server-ci.yml index 98ce2aa2032..c0e0dbb2013 100644 --- a/.github/workflows/server-ci.yml +++ b/.github/workflows/server-ci.yml @@ -77,8 +77,6 @@ jobs: defaults: run: working-directory: server - env: - GOFLAGS: -buildvcs=false # TODO: work around "error obtaining VCS status: exit status 128" in a container steps: - name: Checkout mattermost project uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -275,7 +273,6 @@ jobs: run: working-directory: server env: - GOFLAGS: -buildvcs=false # TODO: work around "error obtaining VCS status: exit status 128" in a container BUILD_NUMBER: "${GITHUB_HEAD_REF}-${GITHUB_RUN_ID}" FIPS_ENABLED: false steps: diff --git a/server/Makefile b/server/Makefile index e07964a88d8..bb5a460909e 100644 --- a/server/Makefile +++ b/server/Makefile @@ -52,7 +52,13 @@ MMCTL_BUILD_TAGS = MMCTL_TESTFLAGS ?= -timeout 30m MMCTL_PKG = github.com/mattermost/mattermost/server/v8/cmd/mmctl/commands MMCTL_BUILD_DATE = $(shell date -u +'%Y-%m-%dT%H:%M:%SZ') +MMCTL_GIT_COMMIT = $(shell git rev-parse HEAD) +MMCTL_GIT_TREE_STATE = $(shell if [ -n "$$(git status --porcelain 2>/dev/null)" ]; then echo "dirty"; else echo "clean"; fi) +MMCTL_COMMIT_DATE = $(shell TZ=UTC git log -1 --date=format-local:'%Y-%m-%dT%H:%M:%SZ' --format='%cd' 2>/dev/null || echo "dev") MMCTL_LDFLAGS += -X "$(MMCTL_PKG).buildDate=$(MMCTL_BUILD_DATE)" +MMCTL_LDFLAGS += -X "$(MMCTL_PKG).gitCommit=$(MMCTL_GIT_COMMIT)" +MMCTL_LDFLAGS += -X "$(MMCTL_PKG).gitTreeState=$(MMCTL_GIT_TREE_STATE)" +MMCTL_LDFLAGS += -X "$(MMCTL_PKG).commitDate=$(MMCTL_COMMIT_DATE)" # Enterprise BUILD_ENTERPRISE_DIR ?= ../../enterprise @@ -106,7 +112,8 @@ ifeq ($(HOME),/) endif # Go Flags -GOFLAGS ?= $(GOFLAGS:) +# Use -buildvcs=false to avoid embedding VCS info which can cause false positives in container scanning tools +export GOFLAGS ?= -buildvcs=false # We need to export GOBIN to allow it to be set # for processes spawned from the Makefile export GOBIN ?= $(PWD)/bin @@ -852,11 +859,11 @@ ifeq ($(BUILD_ENTERPRISE_READY),true) endif mmctl-build: ## Compiles and generates the mmctl binary - go build -trimpath -ldflags '$(MMCTL_LDFLAGS)' -o bin/mmctl ./cmd/mmctl + $(GO) build $(GOFLAGS) -trimpath -ldflags '$(MMCTL_LDFLAGS)' -o bin/mmctl ./cmd/mmctl mmctl-docs: ## Generate the mmctl docs rm -rf ./cmd/mmctl/docs - cd ./cmd/mmctl && go run mmctl.go docs + cd ./cmd/mmctl && $(GO) run mmctl.go docs ## Help documentation à la https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html help: diff --git a/server/cmd/mmctl/commands/version.go b/server/cmd/mmctl/commands/version.go index 8fd46996751..e68a30089d7 100644 --- a/server/cmd/mmctl/commands/version.go +++ b/server/cmd/mmctl/commands/version.go @@ -5,19 +5,23 @@ package commands import ( "fmt" - "runtime/debug" + "runtime" "github.com/mattermost/mattermost/server/public/model" "github.com/mattermost/mattermost/server/v8/cmd/mmctl/printer" - "github.com/pkg/errors" "github.com/spf13/cobra" ) +// Version defaults to model.CurrentVersion. buildDate, gitCommit, +// gitTreeState, and commitDate are set via -X ldflags at build time. +// See MMCTL_LDFLAGS in the Makefile. var ( - Version = model.CurrentVersion - // Build date in ISO8601 format, output of $(date -u +'%Y-%m-%dT%H:%M:%SZ') - buildDate = "dev" + Version = model.CurrentVersion + buildDate = "dev" + gitCommit = "dev" + gitTreeState = "dev" + commitDate = "dev" ) var VersionCmd = &cobra.Command{ @@ -31,14 +35,9 @@ func init() { } func versionCmdF(cmd *cobra.Command, args []string) error { - 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) + "\nCompiler:\t{{.Compiler}}\nPlatform:\t{{.Platform}}", getVersionInfo()) return nil } @@ -53,51 +52,15 @@ type Info struct { Platform string } -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 - } - } - +func getVersionInfo() *Info { return &Info{ Version: Version, BuildDate: buildDate, CommitDate: commitDate, - GitCommit: revision, + GitCommit: gitCommit, GitTreeState: gitTreeState, - GoVersion: info.GoVersion, - Compiler: compiler, - Platform: fmt.Sprintf("%s/%s", arch, os), - }, nil + GoVersion: runtime.Version(), + Compiler: runtime.Compiler, + Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH), + } }