Skip to content

serve version from backend instead of frontend env var#998

Merged
mergify[bot] merged 3 commits intomainfrom
kdreyer/version-from-backend-970
Mar 24, 2026
Merged

serve version from backend instead of frontend env var#998
mergify[bot] merged 3 commits intomainfrom
kdreyer/version-from-backend-970

Conversation

@ktdreyer
Copy link
Copy Markdown
Contributor

@ktdreyer ktdreyer commented Mar 24, 2026

Summary

  • Add GET /api/version backend endpoint that returns the version embedded at compile time via Go ldflags
  • Frontend version route now proxies to the backend instead of reading the VTEAM_VERSION env var
  • Remove VTEAM_VERSION from frontend deployment manifest, env.ts, and all oc set env workflow steps
  • Pass --build-arg AMBIENT_VERSION=... in CI workflows and the Makefile so the version is baked into the backend image

Context

The UI showed a stale "v0.0.7" on ArgoCD-managed clusters because VTEAM_VERSION was hardcoded in the frontend deployment manifest. The GH Actions workflows hid this by imperatively running oc set env after deploy, but ArgoCD reverts imperative changes on every sync cycle.

The backend now owns the version as an immutable property of its binary — correct regardless of whether the cluster is managed by ArgoCD, GH Actions, or manual kubectl apply.

Test plan

  • Backend GET /api/version returns {"version": "..."} with the compile-time value
  • Frontend UI displays the backend-reported version
  • No remaining VTEAM_VERSION references in the codebase (grep -r VTEAM_VERSION returns nothing)
  • Local dev (kind) shows a short git SHA (e.g. f305fcc-dirty)
  • CI stage deploy shows the full git SHA as the version
  • CI release deploy shows the release tag (e.g. v0.1.3)

Fixes #970

The frontend VTEAM_VERSION env var was hardcoded in the deployment
manifest and required imperative "oc set env" patching after deploy.
ArgoCD reverts imperative changes on every sync, so the UI always
showed the stale default ("v0.0.7") on declaratively-managed clusters.

Embed the version in the backend binary at compile time via Go
ldflags and expose it through a new "GET /api/version" endpoint.
The frontend version route now proxies to the backend instead of
reading a local env var, making the version correct regardless of
deployment tool.

The backend becomes the single source of version truth for all
consumers (UI, CLI, API clients). Local builds get a short git SHA
from "git describe --tags --always --dirty", CI stage deploys get
the full commit SHA, and release deploys get the semver tag.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 24, 2026

Walkthrough

Backend now embeds a compile-time version (AMBIENT_VERSION via ldflags) and exposes GET /api/version. Frontend /api/version proxies to the backend. Manifests and CI/workflows stop imperatively setting VTEAM_VERSION; Makefile/local builds pass AMBIENT_VERSION build-arg instead.

Changes

Cohort / File(s) Summary
Backend Version Handler
components/backend/handlers/version.go, components/backend/handlers/version_test.go
Add package-level version state, SetVersion() and GetVersion() handler; add tests verifying default and overridden versions.
Backend Integration & Build
components/backend/main.go, components/backend/routes.go, components/backend/Dockerfile
Call handlers.SetVersion(GitVersion) in main(), register GET /api/version, and add ARG AMBIENT_VERSION / pass -X main.GitVersion=${AMBIENT_VERSION} to go build.
Makefile (local builds)
Makefile
Removed local-sync-version target; backend build targets now pass --build-arg AMBIENT_VERSION=$(shell git describe --tags --always --dirty) when building backend images.
Frontend API & Env
components/frontend/src/app/api/version/route.ts, components/frontend/src/lib/env.ts
Frontend /api/version now fetches the backend /version and proxies its JSON; removed VTEAM_VERSION from frontend env types and public env exposure.
Kubernetes Manifests
components/manifests/base/core/frontend-deployment.yaml
Removed VTEAM_VERSION environment variable from the frontend Deployment container.
CI/CD Workflows
.github/workflows/components-build-deploy.yml, .github/workflows/prod-release-deploy.yaml
Docker build steps now pass build-args: AMBIENT_VERSION=... (commit SHA or release tag) to backend builds; removed oc set env ... VTEAM_VERSION=... updates.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant CI as CI / Developer
participant Docker as Docker Build
participant BackendImage as Backend Image (AMBIENT_VERSION)
participant Cluster as Cluster / Deployment
participant FrontendAPI as Frontend /api/version
participant BackendSvc as Backend /api/version
CI->>Docker: build backend with AMBIENT_VERSION (sha/tag)
Docker->>BackendImage: embed AMBIENT_VERSION into binary (ldflags)
CI->>Cluster: deploy BackendImage
User->>FrontendAPI: GET /api/version
FrontendAPI->>BackendSvc: GET /api/version (backend service)
BackendSvc-->>FrontendAPI: 200 {"version": "..."}
FrontendAPI-->>User: 200 {"version": "..."}

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'serve version from backend instead of frontend env var' accurately summarizes the main objective of the changeset—shifting version responsibility from a frontend environment variable to a backend endpoint.
Linked Issues check ✅ Passed The changeset implements all core requirements from issue #970: backend version endpoint with compile-time embedding via ldflags, frontend proxy to backend, removal of VTEAM_VERSION from manifests/env, CI/Makefile build-arg injection, and backend tests.
Out of Scope Changes check ✅ Passed All changes are scoped to the stated objectives: backend version handling, frontend proxying, build argument injection, and environment variable removal. No extraneous refactoring or unrelated modifications present.
Description check ✅ Passed The pull request description clearly describes the changeset: adding a backend version endpoint, removing VTEAM_VERSION from frontend, and propagating version through build args in CI and Makefile.

✏️ 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 kdreyer/version-from-backend-970

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/frontend/src/app/api/version/route.ts`:
- Around line 9-14: Remove the unnecessary 'Content-Type' header from the GET
fetch call to BACKEND_URL in route.ts: locate the fetch invocation that builds
the request (the code creating "response = await fetch(`${BACKEND_URL}/version`,
{ method: 'GET', headers: { 'Content-Type': 'application/json' } })") and delete
the headers block (or at least the 'Content-Type' entry), leaving a plain GET
request without a body.
- Around line 8-26: Add a timeout to the fetch by using an AbortController:
create an AbortController before calling fetch(`${BACKEND_URL}/version`, { ... ,
signal: controller.signal }), start a timer (e.g., setTimeout) to call
controller.abort() after your desired timeout, and clear the timer after fetch
completes; update the catch block to detect an abort (error.name ===
'AbortError') and return a 504 Response.json({ error: 'Request timed out' }, {
status: 504 }) while keeping other errors returning 500, and ensure you clear
the timeout in all code paths to avoid leaks.

In `@Makefile`:
- Around line 174-175: The makefile is inconsistent: some backend build targets
(local-reload-backend and _build-and-load) do not pass the VERSION build-arg
like build-backend does, causing non-uniform image labels; update the Docker
build invocations in the local-reload-backend target and in the _build-and-load
target to include the same --build-arg VERSION=$(shell git describe --tags
--always --dirty) (and keep the -t $(BACKEND_IMAGE) naming) so images built for
local-up and local-reload-backend embed the correct git SHA/version just like
build-backend does.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1c7a8d8b-d7f9-4b91-919f-483151faf9d0

📥 Commits

Reviewing files that changed from the base of the PR and between 6b21778 and 1429848.

📒 Files selected for processing (11)
  • .github/workflows/components-build-deploy.yml
  • .github/workflows/prod-release-deploy.yaml
  • Makefile
  • components/backend/Dockerfile
  • components/backend/handlers/version.go
  • components/backend/handlers/version_test.go
  • components/backend/main.go
  • components/backend/routes.go
  • components/frontend/src/app/api/version/route.ts
  • components/frontend/src/lib/env.ts
  • components/manifests/base/core/frontend-deployment.yaml
💤 Files with no reviewable changes (2)
  • components/manifests/base/core/frontend-deployment.yaml
  • components/frontend/src/lib/env.ts

The ubi9/go-toolset base image sets "ENV VERSION=1.24.6", which
shadows the Dockerfile ARG of the same name. The backend binary
was getting the Go toolchain version instead of the git ref.

Use the "AMBIENT_" prefix to avoid collisions with base image
environment variables.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ktdreyer ktdreyer force-pushed the kdreyer/version-from-backend-970 branch from cd0ac36 to 4801f91 Compare March 24, 2026 13:12
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
Makefile (1)

174-175: ⚠️ Potential issue | 🟠 Major

Version embedding is still inconsistent across local backend build paths.

Line 174 correctly injects AMBIENT_VERSION, but Line 406 and Line 957 still build backend without that arg. As a result, local-reload-backend and local-up (_build-and-load) continue embedding the default "dev" version instead of git-derived metadata.

Proposed fix
 local-reload-backend: check-local-context ## Rebuild and reload backend only
 	`@echo` "$(COLOR_BLUE)▶$(COLOR_RESET) Rebuilding backend..."
-	`@cd` components/backend && $(CONTAINER_ENGINE) build -t $(BACKEND_IMAGE) . >/dev/null 2>&1
+	`@cd` components/backend && $(CONTAINER_ENGINE) build \
+		--build-arg AMBIENT_VERSION=$(shell git describe --tags --always --dirty) \
+		-t $(BACKEND_IMAGE) . >/dev/null 2>&1
 	@$(CONTAINER_ENGINE) tag $(BACKEND_IMAGE) localhost/$(BACKEND_IMAGE) 2>/dev/null || true
 _build-and-load: ## Internal: Build and load images
 	`@echo` "  Building backend ($(PLATFORM))..."
-	@$(CONTAINER_ENGINE) build $(PLATFORM_FLAG) -t $(BACKEND_IMAGE) components/backend $(QUIET_REDIRECT)
+	@$(CONTAINER_ENGINE) build $(PLATFORM_FLAG) \
+		--build-arg AMBIENT_VERSION=$(shell git describe --tags --always --dirty) \
+		-t $(BACKEND_IMAGE) components/backend $(QUIET_REDIRECT)
 	`@echo` "  Building frontend ($(PLATFORM))..."

Also applies to: 406-407, 955-958

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Makefile` around lines 174 - 175, The Makefile embeds AMBIENT_VERSION only
for one build target causing local-reload-backend and local-up (via
_build-and-load) to still build the backend with the default "dev"; update the
build commands for targets local-reload-backend, local-up (and the
_build-and-load helper) to pass --build-arg AMBIENT_VERSION=$(shell git describe
--tags --always --dirty) and keep -t $(BACKEND_IMAGE) so the git-derived
AMBIENT_VERSION is injected consistently; ensure you update every backend docker
build invocation (including those referenced around the local-reload-backend and
_build-and-load rules) to use the same AMBIENT_VERSION build-arg.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@Makefile`:
- Around line 174-175: The Makefile embeds AMBIENT_VERSION only for one build
target causing local-reload-backend and local-up (via _build-and-load) to still
build the backend with the default "dev"; update the build commands for targets
local-reload-backend, local-up (and the _build-and-load helper) to pass
--build-arg AMBIENT_VERSION=$(shell git describe --tags --always --dirty) and
keep -t $(BACKEND_IMAGE) so the git-derived AMBIENT_VERSION is injected
consistently; ensure you update every backend docker build invocation (including
those referenced around the local-reload-backend and _build-and-load rules) to
use the same AMBIENT_VERSION build-arg.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3ebb8879-2a13-4dc4-b31b-d5aab9caa7a6

📥 Commits

Reviewing files that changed from the base of the PR and between 1429848 and 4801f91.

📒 Files selected for processing (4)
  • .github/workflows/components-build-deploy.yml
  • .github/workflows/prod-release-deploy.yaml
  • Makefile
  • components/backend/Dockerfile

The "local-reload-backend" and "_build-and-load" targets were
building the backend image without the version build arg, so
those paths would always show "dev" in the UI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Gkrumbach07
Copy link
Copy Markdown
Contributor

@Mergifyio queue

@mergify
Copy link
Copy Markdown

mergify bot commented Mar 24, 2026

Merge Queue Status

This pull request spent 17 seconds in the queue, including 1 second running CI.

Required conditions to merge

@mergify mergify bot added the queued label Mar 24, 2026
mergify bot added a commit that referenced this pull request Mar 24, 2026
@mergify mergify bot merged commit 7b6f4eb into main Mar 24, 2026
42 checks passed
@mergify mergify bot deleted the kdreyer/version-from-backend-970 branch March 24, 2026 17:34
@mergify mergify bot removed the queued label Mar 24, 2026
@ambient-code ambient-code bot removed this from the Review Queue milestone Mar 26, 2026
jeremyeder pushed a commit to jeremyeder/platform that referenced this pull request Mar 26, 2026
)

## Summary

- Add `GET /api/version` backend endpoint that returns the version
embedded at compile time via Go `ldflags`
- Frontend version route now proxies to the backend instead of reading
the `VTEAM_VERSION` env var
- Remove `VTEAM_VERSION` from frontend deployment manifest, `env.ts`,
and all `oc set env` workflow steps
- Pass `--build-arg AMBIENT_VERSION=...` in CI workflows and the
Makefile so the version is baked into the backend image

## Context

The UI showed a stale "v0.0.7" on ArgoCD-managed clusters because
`VTEAM_VERSION` was hardcoded in the frontend deployment manifest. The
GH Actions workflows hid this by imperatively running `oc set env` after
deploy, but ArgoCD reverts imperative changes on every sync cycle.

The backend now owns the version as an immutable property of its binary
— correct regardless of whether the cluster is managed by ArgoCD, GH
Actions, or manual `kubectl apply`.

## Test plan

- [ ] Backend `GET /api/version` returns `{"version": "..."}` with the
compile-time value
- [ ] Frontend UI displays the backend-reported version
- [ ] No remaining `VTEAM_VERSION` references in the codebase (`grep -r
VTEAM_VERSION` returns nothing)
- [ ] Local dev (`kind`) shows a short git SHA (e.g. `f305fcc-dirty`)
- [ ] CI stage deploy shows the full git SHA as the version
- [ ] CI release deploy shows the release tag (e.g. `v0.1.3`)

Fixes ambient-code#970

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

version is incorrect when deploying with ArgoCD

2 participants