Merged in feature/expose-version (pull request #186)

expose version to api

* expose version
This commit is contained in:
Jay Brown
2025-09-19 19:18:37 +00:00
parent a6e081e5cd
commit c9eef574c0
4 changed files with 95 additions and 7 deletions
+2 -1
View File
@@ -36,6 +36,7 @@ ENV CC=musl-gcc
ARG GIT_VERSION=dev
ARG GIT_COMMIT=unknown
ARG BUILD_TIME=unknown
# Build with debug symbols (remove -s -w flags)
RUN go build \
@@ -44,7 +45,7 @@ RUN go build \
-trimpath \
-installsuffix cgo \
-gcflags="all=-N -l" \
-ldflags "-linkmode external -extldflags '-static -Wl,--as-needed -Wl,--gc-sections -Wl,-O1' -X main.version=${GIT_VERSION} -X main.gitCommit=${GIT_COMMIT}" \
-ldflags "-linkmode external -extldflags '-static -Wl,--as-needed -Wl,--gc-sections -Wl,-O1' -X queryorchestration/internal/serviceconfig/build.version=${GIT_VERSION} -X queryorchestration/internal/serviceconfig/build.gitCommit=${GIT_COMMIT} -X queryorchestration/internal/serviceconfig/build.buildTime=${BUILD_TIME}" \
-o bin/ ./cmd/...
FROM golang:${GO_VERSION}-alpine AS final
+8 -2
View File
@@ -16,6 +16,7 @@ import (
"queryorchestration/internal/cognitoauth"
"queryorchestration/internal/document/batch"
documentupload "queryorchestration/internal/document/upload"
"queryorchestration/internal/serviceconfig/build"
"queryorchestration/internal/serviceconfig/objectstore"
"queryorchestration/internal/server"
@@ -277,9 +278,14 @@ func New(ctx context.Context, cfg Config) (*Server, error) {
e.GET("/metrics", echoprometheus.NewHandler())
}
// Health endpoint
// Health endpoint with version information
e.GET("/health", func(c echo.Context) error {
return c.NoContent(http.StatusOK)
return c.JSON(http.StatusOK, map[string]interface{}{
"status": "healthy",
"version": build.GetVersion(),
"buildTime": build.GetBuildTime(),
"commit": build.GetGitCommit(),
})
})
e.Use(getSlogCustomEchoMiddleware(cfg.GetLogger()))
+66 -4
View File
@@ -2,6 +2,7 @@ package api
import (
"context"
"encoding/json"
"log/slog"
"net/http"
"net/http/httptest"
@@ -12,6 +13,7 @@ import (
"queryorchestration/internal/backgroundtask"
"queryorchestration/internal/database/repository"
"queryorchestration/internal/serviceconfig"
"queryorchestration/internal/serviceconfig/build"
"queryorchestration/internal/serviceconfig/logger"
"queryorchestration/internal/test"
@@ -192,9 +194,14 @@ func TestHealthEndpoint(t *testing.T) {
// Create a new Echo instance
e := echo.New()
// Register health endpoint
// Register health endpoint with version information
e.GET("/health", func(c echo.Context) error {
return c.NoContent(http.StatusOK)
return c.JSON(http.StatusOK, map[string]interface{}{
"status": "healthy",
"version": build.GetVersion(),
"buildTime": build.GetBuildTime(),
"commit": build.GetGitCommit(),
})
})
// Create a request to the health endpoint
@@ -207,8 +214,63 @@ func TestHealthEndpoint(t *testing.T) {
// Assert the response status code
assert.Equal(t, http.StatusOK, rec.Code)
// Assert the response body is empty
assert.Empty(t, rec.Body.String())
// Parse the JSON response
var response map[string]interface{}
err := json.Unmarshal(rec.Body.Bytes(), &response)
require.NoError(t, err)
// Assert the response contains expected fields
assert.Equal(t, "healthy", response["status"])
assert.NotEmpty(t, response["version"])
assert.NotEmpty(t, response["buildTime"])
assert.NotEmpty(t, response["commit"])
}
func TestHealthEndpointWithVersionInfo(t *testing.T) {
// Create a new Echo instance
e := echo.New()
// Register health endpoint with version information (matching actual implementation)
e.GET("/health", func(c echo.Context) error {
return c.JSON(http.StatusOK, map[string]interface{}{
"status": "healthy",
"version": build.GetVersion(),
"buildTime": build.GetBuildTime(),
"commit": build.GetGitCommit(),
})
})
// Create a request to the health endpoint
req := httptest.NewRequest(http.MethodGet, "/health", nil)
rec := httptest.NewRecorder()
// Serve the request
e.ServeHTTP(rec, req)
// Assert the response status code
assert.Equal(t, http.StatusOK, rec.Code)
// Check that Content-Type starts with application/json (may or may not include charset)
contentType := rec.Header().Get("Content-Type")
assert.True(t, strings.HasPrefix(contentType, "application/json"), "Content-Type should be application/json, got: %s", contentType)
// Parse the JSON response
var response map[string]interface{}
err := json.Unmarshal(rec.Body.Bytes(), &response)
require.NoError(t, err)
// Verify all expected fields are present
assert.Contains(t, response, "status", "Response should contain status field")
assert.Contains(t, response, "version", "Response should contain version field")
assert.Contains(t, response, "buildTime", "Response should contain buildTime field")
assert.Contains(t, response, "commit", "Response should contain commit field")
// Verify status is healthy
assert.Equal(t, "healthy", response["status"], "Status should be healthy")
// Verify version fields match the build package values
assert.Equal(t, build.GetVersion(), response["version"], "Version should match build.GetVersion()")
assert.Equal(t, build.GetBuildTime(), response["buildTime"], "BuildTime should match build.GetBuildTime()")
assert.Equal(t, build.GetGitCommit(), response["commit"], "Commit should match build.GetGitCommit()")
}
func TestGetSlogCustomEchoMiddleware(t *testing.T) {
+19
View File
@@ -99,3 +99,22 @@ tasks:
echo "AWS_ACCESS_KEY_ID_TEXTRACT=$(echo $CREDENTIALS_JSON | jq -r '.AccessKeyId')" >> .env
echo "AWS_SECRET_ACCESS_KEY_TEXTRACT=$(echo $CREDENTIALS_JSON | jq -r '.SecretAccessKey')" >> .env
echo "AWS_SESSION_TOKEN_TEXTRACT=$(echo $CREDENTIALS_JSON | jq -r '.SessionToken')" >> .env
dev:queryAPI:
desc: "Run queryAPI locally with version info"
vars:
BUILD_TIME:
sh: date -u +"%Y-%m-%dT%H:%M:%SZ"
GIT_SHORT_COMMIT:
sh: git rev-parse --short HEAD
GIT_VERSION:
sh: echo "$(date -u +"%Y%m%d.%H%M%S")-$(git rev-parse --short HEAD)"
GIT_COMMIT:
sh: git rev-parse HEAD
cmds:
- echo "Starting queryAPI with version={{.GIT_VERSION}} buildTime={{.BUILD_TIME}} commit={{.GIT_COMMIT}}"
- |
go run -ldflags "\
-X queryorchestration/internal/serviceconfig/build.version={{.GIT_VERSION}} \
-X queryorchestration/internal/serviceconfig/build.buildTime={{.BUILD_TIME}} \
-X queryorchestration/internal/serviceconfig/build.gitCommit={{.GIT_COMMIT}}" \
cmd/queryAPI/main.go