From b740d39db440bd24ce485998c3237524df6b34a3 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Wed, 24 Sep 2025 15:38:59 -0400 Subject: [PATCH] feat: server: add version endpoint and client method --- .goreleaser.yml | 2 +- internal/client/client.go | 15 +++++++++++++++ internal/proto/version.go | 8 ++++++++ internal/server/proto.go | 11 +++++++++++ internal/server/server.go | 1 + internal/version/version.go | 5 ++++- 6 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 internal/proto/version.go diff --git a/.goreleaser.yml b/.goreleaser.yml index c0da1c50aec71d899b0cffe09be64e3756e92f51..41136df53dfd905cb009db7e818b48fc3db380b8 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -70,7 +70,7 @@ builds: - goos: windows goarch: arm ldflags: - - -s -w -X github.com/charmbracelet/crush/internal/version.Version={{.Version}} + - -s -w -X github.com/charmbracelet/crush/internal/version.Version={{.Version}} -X github.com/charmbracelet/crush/internal/version.Commit={{.Commit}} flags: - -trimpath diff --git a/internal/client/client.go b/internal/client/client.go index 81ca596acad7af4517c505fe46f546db14a15409..eb4f814fc5f8cac006d5980433b5918e256592fb 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -10,6 +10,7 @@ import ( "time" "github.com/charmbracelet/crush/internal/config" + "github.com/charmbracelet/crush/internal/proto" "github.com/charmbracelet/crush/internal/server" ) @@ -91,3 +92,17 @@ func (c *Client) Health() error { } return nil } + +// VersionInfo retrieves the server's version information. +func (c *Client) VersionInfo() (*proto.VersionInfo, error) { + var vi proto.VersionInfo + rsp, err := c.h.Get("http://localhost/v1/version") + if err != nil { + return nil, err + } + defer rsp.Body.Close() + if err := json.NewDecoder(rsp.Body).Decode(&vi); err != nil { + return nil, err + } + return &vi, nil +} diff --git a/internal/proto/version.go b/internal/proto/version.go new file mode 100644 index 0000000000000000000000000000000000000000..23a386fb8e20d19868a566913037b34631108eac --- /dev/null +++ b/internal/proto/version.go @@ -0,0 +1,8 @@ +package proto + +type VersionInfo struct { + Version string `json:"version"` + Commit string `json:"commit"` + GoVersion string `json:"go_version"` + Platform string `json:"platform"` +} diff --git a/internal/server/proto.go b/internal/server/proto.go index 638de277d8bb2fdfecd9181eedb96ae1fc7b69c8..5e8562b7b4e85b8fb710e39802cc03e9346993f6 100644 --- a/internal/server/proto.go +++ b/internal/server/proto.go @@ -7,6 +7,7 @@ import ( "net/http" "os" "path/filepath" + "runtime" "github.com/charmbracelet/crush/internal/app" "github.com/charmbracelet/crush/internal/config" @@ -14,6 +15,7 @@ import ( "github.com/charmbracelet/crush/internal/lsp" "github.com/charmbracelet/crush/internal/proto" "github.com/charmbracelet/crush/internal/session" + "github.com/charmbracelet/crush/internal/version" "github.com/google/uuid" ) @@ -25,6 +27,15 @@ func (c *controllerV1) handleGetHealth(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) } +func (c *controllerV1) handleGetVersion(w http.ResponseWriter, r *http.Request) { + jsonEncode(w, proto.VersionInfo{ + Version: version.Version, + Commit: version.Commit, + GoVersion: runtime.Version(), + Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH), + }) +} + func (c *controllerV1) handleGetConfig(w http.ResponseWriter, r *http.Request) { jsonEncode(w, c.cfg) } diff --git a/internal/server/server.go b/internal/server/server.go index cf3d18e49d76cd5a938de80711976e034a8d6f80..10ee9194fea94dc40b4e3b7f24f260bb1fe122fd 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -113,6 +113,7 @@ func NewServer(cfg *config.Config, network, address string) *Server { c := &controllerV1{Server: s} mux := http.NewServeMux() mux.HandleFunc("GET /v1/health", c.handleGetHealth) + mux.HandleFunc("GET /v1/version", c.handleGetVersion) mux.HandleFunc("GET /v1/config", c.handleGetConfig) mux.HandleFunc("GET /v1/instances", c.handleGetInstances) mux.HandleFunc("POST /v1/instances", c.handlePostInstances) diff --git a/internal/version/version.go b/internal/version/version.go index 0b616e122dcf4ffb3fbbf4cb7d3b8665300c23ef..430412e050668fd598f206bf7073c12f27c8d004 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -4,7 +4,10 @@ import "runtime/debug" // Build-time parameters set via -ldflags -var Version = "unknown" +var ( + Version = "unknown" + Commit = "unknown" +) // A user may install crush using `go install github.com/charmbracelet/crush@latest`. // without -ldflags, in which case the version above is unset. As a workaround