From 9ac0974bcfb5ee502e11e14c25fd5d63e27ef291 Mon Sep 17 00:00:00 2001
From: Florent Gluck <florent.gluck@hesge.ch>
Date: Wed, 4 Sep 2024 15:42:56 +0200
Subject: [PATCH] server and clients: display build date and git commit hash at
 startup

---
 Makefile                            | 22 +++++++++++++---------
 src/client/nexus-cli/go.mod         |  5 ++++-
 src/client/nexus-cli/nexus-cli.go   |  4 +++-
 src/client/nexus-exam/go.mod        |  5 ++++-
 src/client/nexus-exam/nexus-exam.go |  8 ++++++++
 src/client/nexush/go.mod            |  5 ++++-
 src/client/nexush/nexush.go         |  4 +++-
 src/common/buildversion/go.mod      |  3 +++
 src/common/buildversion/version.go  | 15 +++++++++++++++
 src/server/go.mod                   |  5 ++++-
 src/server/nexus-server.go          |  4 +++-
 11 files changed, 64 insertions(+), 16 deletions(-)
 create mode 100644 src/common/buildversion/go.mod
 create mode 100644 src/common/buildversion/version.go

diff --git a/Makefile b/Makefile
index 2acc917d..8a99c7b8 100644
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,7 @@
+CURRENT_DATE=$(shell eval "date -u +'%Y-%m-%d at %H:%M:%S'")
+GIT_COMMIT=$(shell eval "git rev-parse HEAD")
+BUILD_FLAGS=-ldflags="-X 'nexus-common/buildversion.buildDate=$(CURRENT_DATE)' -X 'nexus-common/buildversion.gitCommit=$(GIT_COMMIT)'"
+
 SERVER_BASEDIR=$(PREFIX)/nexus-server
 SERVER_CERTS_DIR=$(SERVER_BASEDIR)/certs
 SERVER_CERT=$(SERVER_CERTS_DIR)/server-cert.pem
@@ -60,10 +64,10 @@ check_prefix_var:
 
 build_srv: src/server tools/genpwd
 	@echo "[Building nexus-server]"
-	@cd src/server && go build .
+	@cd src/server && go build $(BUILD_FLAGS) .
 	@echo "OK"
 	@echo "Building genpwd"
-	@cd tools/genpwd && go build .
+	@cd tools/genpwd && go build $(BUILD_FLAGS) .
 	@echo "OK"
 
 clean_srv:
@@ -198,7 +202,7 @@ set_permissions_srv:
 
 #-------------------------------------------------------------------------
 
-BUILD_CLIENT_FLAGS=build -buildvcs=false
+BUILD_CLIENT_FLAGS=-buildvcs=false
 # To force a full recompile:
 # BUILD_FLAGS=build -a
 BUILD_DIR_CLIENT=build
@@ -279,11 +283,11 @@ xbuild_client: check_bin_var check_server_var copy_resources_client $(SRC_CLIENT
 				cd $(SRC_ABS_CLIENT)/$(BIN) ;\
 				go clean . ;\
 				if [ $$os = "linux" ]; then \
-					GOARCH=$$arch GOOS=$$os CGO_ENABLED=0 go $(BUILD_CLIENT_FLAGS) -o $(BUILD_ABS_CLIENT)/$$arch/$$os/ ;\
+					GOARCH=$$arch GOOS=$$os CGO_ENABLED=0 go build $(BUILD_FLAGS) $(BUILD_CLIENT_FLAGS) -o $(BUILD_ABS_CLIENT)/$$arch/$$os/ ;\
 					#strip -s $(BUILD_ABS_CLIENT)/$$arch/$$os/$(BIN) ;\
 					#upx $(BUILD_ABS_CLIENT)/$$arch/$$os/$(BIN) ;\
 				else \
-					GOARCH=$$arch GOOS=$$os go $(BUILD_CLIENT_FLAGS) -o $(BUILD_ABS_CLIENT)/$$arch/$$os/ ;\
+					GOARCH=$$arch GOOS=$$os go build $(BUILD_FLAGS) $(BUILD_CLIENT_FLAGS) -o $(BUILD_ABS_CLIENT)/$$arch/$$os/ ;\
 				fi \
 			fi \
 		done \
@@ -294,17 +298,17 @@ $(BUILD_DIR_CLIENT):
 
 build_nexush: check_server_var copy_resources_client $(BUILD_DIR_CLIENT) $(SRC_CLIENT)/nexush
 	@echo "[Building nexush into $(BUILD_DIR_CLIENT) directory]" 
-	@cd $(SRC_CLIENT)/nexush && go $(BUILD_CLIENT_FLAGS) && mv nexush $(BUILD_ABS_CLIENT)
+	@cd $(SRC_CLIENT)/nexush && go build $(BUILD_FLAGS) $(BUILD_CLIENT_FLAGS) && mv nexush $(BUILD_ABS_CLIENT)
 
 build_nexus-cli: check_server_var copy_resources_client $(BUILD_DIR_CLIENT) $(SRC_CLIENT)/nexus-cli
 	@echo "[Building nexus-cli into $(BUILD_DIR_CLIENT) directory]" 
-	@cd $(SRC_CLIENT)/nexus-cli && go $(BUILD_CLIENT_FLAGS) && mv nexus-cli $(BUILD_ABS_CLIENT)
+	@cd $(SRC_CLIENT)/nexus-cli && go build $(BUILD_FLAGS) $(BUILD_CLIENT_FLAGS) && mv nexus-cli $(BUILD_ABS_CLIENT)
 
 build_nexus-exam: check_server_var check_nexus_exam_vars copy_resources_client $(BUILD_DIR_CLIENT) $(SRC_CLIENT)/nexus-exam
 	@echo "[Building nexus-exam into $(BUILD_DIR_CLIENT) directory]"
 	@echo -n '$(value EXAM_USER)' > $(NEXUS_EXAM_USER_CREDS_FILE)
 	@echo -n '$(value EXAM_PWD)' > $(NEXUS_EXAM_PWD_CREDS_FILE)
-	@cd $(SRC_CLIENT)/nexus-exam && go $(BUILD_CLIENT_FLAGS) && mv nexus-exam $(BUILD_ABS_CLIENT)
+	@cd $(SRC_CLIENT)/nexus-exam && go build $(BUILD_FLAGS) $(BUILD_CLIENT_FLAGS) && mv nexus-exam $(BUILD_ABS_CLIENT)
 	@strip -s $(BUILD_DIR_CLIENT)/nexus-exam
 	@upx -q $(BUILD_DIR_CLIENT)/nexus-exam
 	@rm $(NEXUS_EXAM_USER_CREDS_FILE) $(NEXUS_EXAM_PWD_CREDS_FILE)
@@ -324,7 +328,7 @@ tests: check_login_var tests/run_tests build_nexus-cli $(BUILD_DIR_CLIENT)/nexus
 .PHONY: clean_client tests
 
 # To build a static executable:
-# CGO_ENABLED=0 go build
+# CGO_ENABLED=0 go build $(BUILD_FLAGS)
 
 # 	@echo "  build_client      build $(BIN) binaries for the specified OS/architecture"
 # 	@echo "                    valid OS values: linux, windows, darwin"
diff --git a/src/client/nexus-cli/go.mod b/src/client/nexus-cli/go.mod
index 00c72579..da735969 100644
--- a/src/client/nexus-cli/go.mod
+++ b/src/client/nexus-cli/go.mod
@@ -1,6 +1,8 @@
 module nexus-cli
 
-go 1.18
+go 1.22.2
+
+replace nexus-common/buildversion => ../../common/buildversion
 
 replace nexus-common/caps => ../../common/caps
 
@@ -69,6 +71,7 @@ require (
 	golang.org/x/term v0.18.0 // indirect
 	golang.org/x/text v0.14.0 // indirect
 	nexus-client/exec v0.0.0-00010101000000-000000000000 // indirect
+	nexus-common/buildversion v0.0.0-00010101000000-000000000000 // indirect
 	nexus-common/caps v0.0.0-00010101000000-000000000000 // indirect
 	nexus-common/params v0.0.0-00010101000000-000000000000 // indirect
 	nexus-common/template v0.0.0-00010101000000-000000000000 // indirect
diff --git a/src/client/nexus-cli/nexus-cli.go b/src/client/nexus-cli/nexus-cli.go
index 77e6c260..6d24cf41 100644
--- a/src/client/nexus-cli/nexus-cli.go
+++ b/src/client/nexus-cli/nexus-cli.go
@@ -5,6 +5,7 @@ import (
     "path"
     "strings"
     "nexus-common/utils"
+    "nexus-common/buildversion"
     u "nexus-client/utils"
     g "nexus-client/globals"
     "nexus-client/defaults"
@@ -68,7 +69,8 @@ var cmdList = []cmd.Command {
 func run() int {
     var appname = path.Base(os.Args[0])
     clientVersion := version.Get()
-    u.PrintlnErr(appname+" version "+clientVersion.String())
+    u.PrintlnErr(appname+" version "+clientVersion.String()+" (commit "+buildversion.GitCommit()+")")
+    u.PrintlnErr("Built on "+buildversion.BuildDate())
 
     if len(os.Args) < 2 {
         u.PrintlnErr("USAGE: "+appname+" CMD")
diff --git a/src/client/nexus-exam/go.mod b/src/client/nexus-exam/go.mod
index aabdefab..a601602b 100644
--- a/src/client/nexus-exam/go.mod
+++ b/src/client/nexus-exam/go.mod
@@ -1,6 +1,8 @@
 module nexus-exam
 
-go 1.18
+go 1.22.2
+
+replace nexus-common/buildversion => ../../common/buildversion
 
 replace nexus-common/caps => ../../common/caps
 
@@ -84,6 +86,7 @@ require (
 	nexus-client/globals v0.0.0-00010101000000-000000000000 // indirect
 	nexus-client/utils v0.0.0-00010101000000-000000000000 // indirect
 	nexus-client/version v0.0.0-00010101000000-000000000000 // indirect
+	nexus-common/buildversion v0.0.0-00010101000000-000000000000 // indirect
 	nexus-common/caps v0.0.0-00010101000000-000000000000 // indirect
 	nexus-common/params v0.0.0-00010101000000-000000000000 // indirect
 	nexus-common/utils v0.0.0-00010101000000-000000000000 // indirect
diff --git a/src/client/nexus-exam/nexus-exam.go b/src/client/nexus-exam/nexus-exam.go
index 846d19a9..041cd84b 100644
--- a/src/client/nexus-exam/nexus-exam.go
+++ b/src/client/nexus-exam/nexus-exam.go
@@ -2,6 +2,7 @@ package main
 
 import (
     "os"
+    "path"
     "time"
     "bytes"
     "errors"
@@ -11,9 +12,11 @@ import (
     "encoding/json"
     "nexus-common/vm"
     "nexus-common/params"
+    "nexus-common/buildversion"
     e "nexus-client/exec"
     u "nexus-client/utils"
     g "nexus-client/globals"
+    "nexus-client/version"
     "nexus-client/defaults"
     "nexus-client/cmdLogin"
     "fyne.io/fyne/v2"
@@ -160,6 +163,11 @@ func refreshToken(parent fyne.Window) {
 }
 
 func run() int {
+    var appname = path.Base(os.Args[0])
+    clientVersion := version.Get()
+    u.PrintlnErr(appname+" version "+clientVersion.String()+" (commit "+buildversion.GitCommit()+")")
+    u.PrintlnErr("Built on "+buildversion.BuildDate())
+
     hypervisorCheck()
 
     if err := e.CheckRemoteViewer(); err != nil {
diff --git a/src/client/nexush/go.mod b/src/client/nexush/go.mod
index 4ca9722a..30d7fd43 100644
--- a/src/client/nexush/go.mod
+++ b/src/client/nexush/go.mod
@@ -1,6 +1,8 @@
 module nexush
 
-go 1.18
+go 1.22.2
+
+replace nexus-common/buildversion => ../../common/buildversion
 
 replace nexus-common/caps => ../../common/caps
 
@@ -72,6 +74,7 @@ require (
 	golang.org/x/sys v0.19.0 // indirect
 	golang.org/x/text v0.14.0 // indirect
 	nexus-client/exec v0.0.0-00010101000000-000000000000 // indirect
+	nexus-common/buildversion v0.0.0-00010101000000-000000000000 // indirect
 	nexus-common/caps v0.0.0-00010101000000-000000000000 // indirect
 	nexus-common/params v0.0.0-00010101000000-000000000000 // indirect
 	nexus-common/template v0.0.0-00010101000000-000000000000 // indirect
diff --git a/src/client/nexush/nexush.go b/src/client/nexush/nexush.go
index 8dd6aee5..bbd5ef19 100644
--- a/src/client/nexush/nexush.go
+++ b/src/client/nexush/nexush.go
@@ -11,6 +11,7 @@ import (
     "golang.org/x/term"
     u "nexus-client/utils"
     "nexus-common/utils"
+    "nexus-common/buildversion"
     g "nexus-client/globals"
     "nexus-client/defaults"
     "nexus-client/version"
@@ -80,7 +81,8 @@ var savedTermState *term.State = nil
 func run() int {
     var appname = path.Base(os.Args[0])
     clientVersion := version.Get()
-    u.PrintlnErr(appname+" version "+clientVersion.String())
+    u.PrintlnErr(appname+" version "+clientVersion.String()+" (commit "+buildversion.GitCommit()+")")
+    u.PrintlnErr("Built on "+buildversion.BuildDate())
 
     if len(os.Args) < 2 {
         u.PrintlnErr("USAGE: "+appname+" EMAIL")
diff --git a/src/common/buildversion/go.mod b/src/common/buildversion/go.mod
new file mode 100644
index 00000000..d6fed8cc
--- /dev/null
+++ b/src/common/buildversion/go.mod
@@ -0,0 +1,3 @@
+module nexus-common/buildversion
+
+go 1.22.2
diff --git a/src/common/buildversion/version.go b/src/common/buildversion/version.go
new file mode 100644
index 00000000..a184bf14
--- /dev/null
+++ b/src/common/buildversion/version.go
@@ -0,0 +1,15 @@
+package buildversion
+
+var (
+	// These variables are replaced by ldflags at build time
+	gitCommit = "n/a"
+	buildDate = "n/a"
+)
+
+func GitCommit() string {
+	return gitCommit
+}
+
+func BuildDate() string {
+	return buildDate
+}
\ No newline at end of file
diff --git a/src/server/go.mod b/src/server/go.mod
index d2012684..f3ad7f59 100644
--- a/src/server/go.mod
+++ b/src/server/go.mod
@@ -1,6 +1,8 @@
 module nexus-server
 
-go 1.18
+go 1.22.2
+
+replace nexus-common/buildversion => ../common/buildversion
 
 replace nexus-common/template => ../common/template
 
@@ -64,6 +66,7 @@ require (
 	golang.org/x/text v0.14.0 // indirect
 	golang.org/x/time v0.5.0 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
+	nexus-common/buildversion v0.0.0-00010101000000-000000000000 // indirect
 	nexus-common/caps v0.0.0-00010101000000-000000000000 // indirect
 	nexus-common/params v0.0.0-00010101000000-000000000000 // indirect
 	nexus-common/template v0.0.0-00010101000000-000000000000 // indirect
diff --git a/src/server/nexus-server.go b/src/server/nexus-server.go
index 5ecf6749..eb5a200d 100644
--- a/src/server/nexus-server.go
+++ b/src/server/nexus-server.go
@@ -12,6 +12,7 @@ import (
     "nexus-server/config"
     "nexus-server/cleaner"
     "nexus-server/version"
+    "nexus-common/buildversion"
     "github.com/sirupsen/logrus"
 )
 
@@ -22,7 +23,8 @@ func main() {
 
     var appname = path.Base(os.Args[0])
     serverVersion := version.Get()
-    log.Info(appname+" version "+serverVersion.String())
+    log.Info(appname+" version "+serverVersion.String()+" (commit "+buildversion.GitCommit()+")")
+    log.Info("Built on "+buildversion.BuildDate())
 
     // Initialize the RNG' seed to the current time.
     utils.RandInit()
-- 
GitLab