From ce569ab36e961cc8cb4409becfef3e5431b2e5f8 Mon Sep 17 00:00:00 2001 From: Luis Pater Date: Thu, 13 Nov 2025 08:38:03 +0800 Subject: [PATCH] feat(buildinfo): add build metadata and expose via HTTP headers Introduce a new `buildinfo` package to store version, commit, and build date metadata. Update HTTP handlers to include build metadata in response headers and modify initialization to set `buildinfo` values during runtime. --- cmd/server/main.go | 8 ++++++-- internal/api/handlers/management/handler.go | 5 +++++ internal/buildinfo/buildinfo.go | 15 +++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 internal/buildinfo/buildinfo.go diff --git a/cmd/server/main.go b/cmd/server/main.go index 0a941b7c..ab9b9a35 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -17,6 +17,7 @@ import ( "github.com/joho/godotenv" configaccess "github.com/router-for-me/CLIProxyAPI/v6/internal/access/config_access" + "github.com/router-for-me/CLIProxyAPI/v6/internal/buildinfo" "github.com/router-for-me/CLIProxyAPI/v6/internal/cmd" "github.com/router-for-me/CLIProxyAPI/v6/internal/config" "github.com/router-for-me/CLIProxyAPI/v6/internal/logging" @@ -41,13 +42,16 @@ var ( // init initializes the shared logger setup. func init() { logging.SetupBaseLogger() + buildinfo.Version = Version + buildinfo.Commit = Commit + buildinfo.BuildDate = BuildDate } // main is the entry point of the application. // It parses command-line flags, loads configuration, and starts the appropriate // service based on the provided flags (login, codex-login, or server mode). func main() { - fmt.Printf("CLIProxyAPI Version: %s, Commit: %s, BuiltAt: %s\n", Version, Commit, BuildDate) + fmt.Printf("CLIProxyAPI Version: %s, Commit: %s, BuiltAt: %s\n", buildinfo.Version, buildinfo.Commit, buildinfo.BuildDate) // Command-line flags to control the application's behavior. var login bool @@ -386,7 +390,7 @@ func main() { log.Fatalf("failed to configure log output: %v", err) } - log.Infof("CLIProxyAPI Version: %s, Commit: %s, BuiltAt: %s", Version, Commit, BuildDate) + log.Infof("CLIProxyAPI Version: %s, Commit: %s, BuiltAt: %s", buildinfo.Version, buildinfo.Commit, buildinfo.BuildDate) // Set the log level based on the configuration. util.SetLogLevel(cfg) diff --git a/internal/api/handlers/management/handler.go b/internal/api/handlers/management/handler.go index 5371f9fd..ef6f400a 100644 --- a/internal/api/handlers/management/handler.go +++ b/internal/api/handlers/management/handler.go @@ -13,6 +13,7 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/router-for-me/CLIProxyAPI/v6/internal/buildinfo" "github.com/router-for-me/CLIProxyAPI/v6/internal/config" "github.com/router-for-me/CLIProxyAPI/v6/internal/usage" sdkAuth "github.com/router-for-me/CLIProxyAPI/v6/sdk/auth" @@ -91,6 +92,10 @@ func (h *Handler) Middleware() gin.HandlerFunc { const banDuration = 30 * time.Minute return func(c *gin.Context) { + c.Header("X-CPA-VERSION", buildinfo.Version) + c.Header("X-CPA-COMMIT", buildinfo.Commit) + c.Header("X-CPA-BUILD-DATE", buildinfo.BuildDate) + clientIP := c.ClientIP() localClient := clientIP == "127.0.0.1" || clientIP == "::1" cfg := h.cfg diff --git a/internal/buildinfo/buildinfo.go b/internal/buildinfo/buildinfo.go new file mode 100644 index 00000000..0bdfaf8b --- /dev/null +++ b/internal/buildinfo/buildinfo.go @@ -0,0 +1,15 @@ +// Package buildinfo exposes compile-time metadata shared across the server. +package buildinfo + +// The following variables are overridden via ldflags during release builds. +// Defaults cover local development builds. +var ( + // Version is the semantic version or git describe output of the binary. + Version = "dev" + + // Commit is the git commit SHA baked into the binary. + Commit = "none" + + // BuildDate records when the binary was built in UTC. + BuildDate = "unknown" +)