Skip to content

feat(api): public /version endpoint exposes git SHA + build time - #901

Merged
cristim merged 1 commit into
feat/multicloud-web-frontendfrom
feat/version-endpoint
Jun 1, 2026
Merged

cristim merged 1 commit into
feat/multicloud-web-frontendfrom
feat/version-endpoint

Conversation

@cristim

@cristim cristim commented Jun 1, 2026 •

Copy link
Copy Markdown
Member

Summary

Adds a public GET /version endpoint that returns the deployed build's version, git commit SHA, and build timestamp, so deploy-lag (an environment still serving a stale build) can be diagnosed by curling the URL and comparing the SHA to the branch HEAD.

Closes #900.

Changes

  • cmd/server/main.go: new GitSHA ldflag var; exports VERSION, BUILD_TIME, and GIT_SHA to the environment (the api package reads them from env to avoid an import cycle); startup log now includes the SHA.
  • internal/api/handler_version.go: getVersion handler + VersionResponse{version, git_sha, build_time}, read from env with dev/unknown fallbacks. Carries no account IDs, ARNs, or secrets, so it is safe to expose unauthenticated (not an info leak like sec(api): GET /api/info (unauthenticated) leaks Secrets Manager ARN including AWS account ID and region #437/sec(api): move APIKeySecretURL + DeploymentAWSAccountID out of unauthenticated /api/info (re-scope of #527) #633).
  • internal/api/router.go + middleware.go: register GET /version as AuthPublic and add it to the public allowlist.
  • internal/server/http.go: register /version on the container HTTP mux (a root path, like /health) so it reaches the API router instead of the SPA catch-all when STATIC_DIR is set. Deliberately skips ensureDB so the deployed commit stays readable even when the database is down, which is exactly when confirming the build matters.
  • Dockerfile / Makefile: thread the short SHA into the build. The terraform build module already passes --build-arg GIT_COMMIT and --build-arg BUILD_DATE; the Dockerfile now declares those ARGs and stamps main.GitSHA / main.BuildTime from them (falling back to unknown / date -u so a bare docker build . still works). make build stamps GIT_SHA from git rev-parse --short HEAD.

How the git SHA is injected

Via build-arg, not in-build git. The container build context excludes .git reliability, and terraform already computes the short SHA (local.git_commit) and passes it as --build-arg GIT_COMMIT. We consume that existing arg. Local make build derives it from git rev-parse.

Testing

  • go build ./... clean.
  • go test ./internal/api/... ./internal/server/... — 1692 pass.
  • New unit tests: defaults (dev/unknown), env-stamped values, and router dispatch as a public no-auth route.
  • Verified ldflags stamp: built the binary with -X main.GitSHA=<sha> and confirmed the SHA is embedded.

Verify a deployed environment

curl -s https://<env-host>/version
# {"version":"1b99460","git_sha":"1b99460","build_time":"2026-06-01T00:00:00Z"}

Summary by CodeRabbit

  • New Features
    • Added a new public /version endpoint that returns build metadata including version, git SHA, and build time
    • Build metadata is captured during compilation and served via the API endpoint
    • Endpoint remains accessible even when the database is unavailable

Adds GitSHA ldflag + a public GET /version returning version, git_sha,
and build_time so a running environment's deployed commit can be
verified against the branch HEAD (diagnoses deploy-lag). Wires the
short SHA through the Docker/Make build.
@cristim cristim added triaged Item has been triaged priority/p2 Backlog-worthy severity/low Minor harm urgency/this-sprint Within the current sprint impact/internal Team-internal only effort/s Hours type/feat New capability labels Jun 1, 2026
@coderabbitai

coderabbitai Bot commented Jun 1, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b397e82d-e04a-4d66-be25-5ab00cff6e6a

📥 Commits

Reviewing files that changed from the base of the PR and between 1b99460 and d1f6965.

📒 Files selected for processing (8)
  • Dockerfile
  • Makefile
  • cmd/server/main.go
  • internal/api/handler_version.go
  • internal/api/handler_version_test.go
  • internal/api/middleware.go
  • internal/api/router.go
  • internal/server/http.go

📝 Walkthrough

Walkthrough

This PR adds a public GET /version endpoint that exposes build metadata (version, git commit SHA, build timestamp) for deployment verification. Changes flow from build-time stamping through Dockerfile/Makefile, server-side metadata declaration, API handler implementation, and HTTP routing registration.

Changes

Public /version Endpoint for Deploy Verification

Layer / File(s) Summary
Build metadata compilation and stamping
Dockerfile, Makefile, cmd/server/main.go
Dockerfile parameterizes VERSION, GIT_COMMIT, and BUILD_DATE as build arguments and computes BUILD_TIME from BUILD_DATE. Makefile introduces GIT_SHA variable with git fallback and extends LDFLAGS to inject main.GitSHA. cmd/server/main.go declares exported GitSHA variable and updates startup to initialize BUILD_TIME and GIT_SHA environment variables alongside VERSION.
API handler and version response
internal/api/handler_version.go, internal/api/handler_version_test.go
Defines VersionResponse struct with version, git_sha, and build_time JSON fields. Implements Handler.getVersion to read from environment variables with fallback sentinel defaults ("dev" for version, "unknown" for git SHA and build time). Includes envOrDefault helper and three tests covering default values, populated environment variables, and router dispatch.
Router, middleware, and HTTP endpoint registration
internal/api/router.go, internal/api/middleware.go, internal/server/http.go
router.go adds AuthPublic route for GET /version with getVersionHandler delegate. middleware.go marks /version in public endpoint allowlist. http.go registers root /version endpoint with handleVersion HTTP handler that applies 5s timeout, dispatches through API without database initialization, and converts Lambda response back to HTTP.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A version endpoint hops into view,
Git SHA and timestamp in JSON so true,
No database needed, just swift and divine,
Deploy-lag diagnosis on endpoint /version—rabbits align!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main feature: adding a public /version endpoint that exposes git SHA and build time metadata.
Linked Issues check ✅ Passed All coding requirements from #900 are met: GitSHA is stamped via ldflags, public GET /version endpoint returns {version, git_sha, build_time}, registered in API router and middleware allowlist, and configured at root path independent of DB.
Out of Scope Changes check ✅ Passed All changes are within scope of #900: build metadata propagation (Dockerfile, Makefile), endpoint implementation (handler_version.go), router registration, middleware updates, HTTP server setup, and related tests.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/version-endpoint

Comment @coderabbitai help to get the list of available commands and usage tips.

@cristim

cristim commented Jun 1, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cristim
cristim merged commit 74148ec into feat/multicloud-web-frontend Jun 1, 2026
5 checks passed
@cristim
cristim deleted the feat/version-endpoint branch June 1, 2026 16:04
cristim added a commit that referenced this pull request Jun 2, 2026
…h fallback (#916)

isStaticPath() only excluded /api/* and /health, so /version was falling through
to the SPA file server on the Lambda Function URL path, returning index.html
instead of the JSON build-metadata response added by PR #901. The HTTP/Cloud Run
path was unaffected because mux.HandleFunc("/version", ...) is registered before
the SPA catch-all in CreateHTTPServer.

Add /version to the isStaticPath allowlist (same pattern as /health) so
handleLambdaHTTPEvent routes it to app.API.HandleRequest, which already handles
it correctly via the ExactPath:/version AuthPublic router entry.

Also add test cases for /version and //version (double-slash normalised) to
TestIsStaticPath.
cristim added a commit that referenced this pull request Sep 27, 2026
Adds GitSHA ldflag + a public GET /version returning version, git_sha,
and build_time so a running environment's deployed commit can be
verified against the branch HEAD (diagnoses deploy-lag). Wires the
short SHA through the Docker/Make build.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/s Hours impact/internal Team-internal only priority/p2 Backlog-worthy severity/low Minor harm triaged Item has been triaged type/feat New capability urgency/this-sprint Within the current sprint

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant