serve version from backend instead of frontend env var#998
serve version from backend instead of frontend env var#998mergify[bot] merged 3 commits intomainfrom
Conversation
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>
WalkthroughBackend 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
Sequence Diagram(s)mermaid Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (11)
.github/workflows/components-build-deploy.yml.github/workflows/prod-release-deploy.yamlMakefilecomponents/backend/Dockerfilecomponents/backend/handlers/version.gocomponents/backend/handlers/version_test.gocomponents/backend/main.gocomponents/backend/routes.gocomponents/frontend/src/app/api/version/route.tscomponents/frontend/src/lib/env.tscomponents/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>
cd0ac36 to
4801f91
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
Makefile (1)
174-175:⚠️ Potential issue | 🟠 MajorVersion 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-backendandlocal-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
📒 Files selected for processing (4)
.github/workflows/components-build-deploy.yml.github/workflows/prod-release-deploy.yamlMakefilecomponents/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>
|
@Mergifyio queue |
Merge Queue Status
This pull request spent 17 seconds in the queue, including 1 second running CI. Required conditions to merge
|
) ## 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>
Summary
GET /api/versionbackend endpoint that returns the version embedded at compile time via GoldflagsVTEAM_VERSIONenv varVTEAM_VERSIONfrom frontend deployment manifest,env.ts, and alloc set envworkflow steps--build-arg AMBIENT_VERSION=...in CI workflows and the Makefile so the version is baked into the backend imageContext
The UI showed a stale "v0.0.7" on ArgoCD-managed clusters because
VTEAM_VERSIONwas hardcoded in the frontend deployment manifest. The GH Actions workflows hid this by imperatively runningoc set envafter 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
GET /api/versionreturns{"version": "..."}with the compile-time valueVTEAM_VERSIONreferences in the codebase (grep -r VTEAM_VERSIONreturns nothing)kind) shows a short git SHA (e.g.f305fcc-dirty)v0.1.3)Fixes #970