From 5d2be7ef560d1429e2bfa8ebc5d99b70400ce865 Mon Sep 17 00:00:00 2001 From: Manas Srivastava Date: Tue, 12 May 2026 16:19:31 +0530 Subject: [PATCH] obs: Dockerfile ldflags + smoke-buildinfo target for commit_sha (track 1/8) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Dockerfile: ARG GIT_SHA / BUILD_TIME / VERSION, passed into `go build -ldflags -X instant.dev/common/buildinfo.X=...` so the resulting api binary stamps its own commit on every log line and /healthz response. - Makefile: docker-build target updated to `cd ..` first (since the Dockerfile assumes repo-root as build context per CLAUDE.md) and forwards --build-arg from `make` vars defaulting to `git rev-parse --short HEAD`. - New cmd/smoke-buildinfo helper + `make smoke-buildinfo` target builds with override values and asserts they appear at runtime — CI regression gate for the ldflag path. Companion changes: - common adds buildinfo package (InstaNode-dev/common#2) - worker adds matching Dockerfile/Makefile (InstaNode-dev/worker#7) - provisioner adds matching Dockerfile/Makefile (InstaNode-dev/provisioner#5) Co-Authored-By: Claude Opus 4.7 (1M context) --- Dockerfile | 9 ++++++++- Makefile | 36 ++++++++++++++++++++++++++++++++++-- cmd/smoke-buildinfo/main.go | 17 +++++++++++++++++ 3 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 cmd/smoke-buildinfo/main.go diff --git a/Dockerfile b/Dockerfile index 7b28e007..7b839970 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,14 @@ COPY common/ /common/ COPY api/go.mod api/go.sum ./ RUN go mod download COPY api/ . -RUN CGO_ENABLED=0 GOOS=linux go build -o /instant . +# Build-time metadata injected via -ldflags into instant.dev/common/buildinfo. +# Defaults keep the build runnable without --build-arg; CI passes real values. +ARG GIT_SHA=dev +ARG BUILD_TIME=unknown +ARG VERSION=dev +RUN CGO_ENABLED=0 GOOS=linux go build \ + -ldflags "-X instant.dev/common/buildinfo.GitSHA=${GIT_SHA} -X instant.dev/common/buildinfo.BuildTime=${BUILD_TIME} -X instant.dev/common/buildinfo.Version=${VERSION}" \ + -o /instant . FROM alpine:3.20 RUN apk add --no-cache ca-certificates tzdata docker-cli diff --git a/Makefile b/Makefile index 833ceebf..d7439e16 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,17 @@ .PHONY: run build build-cli test test-unit test-db-up test-db-down test-db-reset \ docker-up docker-down docker-logs \ migrate migrate-platform migrate-customers \ - docker-build \ + docker-build smoke-buildinfo \ k8s-deploy k8s-delete k8s-status k8s-regen-migrations \ gen-secrets install-cli +# Build-time metadata injected into instant.dev/common/buildinfo via -ldflags. +# Override on the make line if needed. GIT_SHA falls back to "dev" when not +# in a git checkout (e.g. CI tarball builds). +GIT_SHA ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo dev) +BUILD_TIME ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ) +VERSION ?= dev + # Local test database — Postgres 16 in Docker on localhost:5432. Matches # testhelpers.defaultTestDBURL so tests run without setting any env vars # beyond TEST_DATABASE_URL (which `make test-unit` sets for you). @@ -116,8 +123,33 @@ migrate-customers: # ── Local Kubernetes (Rancher Desktop / k3s) ───────────────────────────────── +# NOTE: per CLAUDE.md the canonical build is from the repo root: +# docker build -f api/Dockerfile -t instant-api:local \ +# --build-arg GIT_SHA=$(git rev-parse --short HEAD) \ +# --build-arg BUILD_TIME=$(date -u +%Y-%m-%dT%H:%M:%SZ) \ +# --build-arg VERSION=$VERSION .. +# This target mirrors that — `cd ..` first so the build context is the repo root. docker-build: - docker build -t instant-api:local . + cd .. && docker build -f api/Dockerfile -t instant-api:local \ + --build-arg GIT_SHA=$(GIT_SHA) \ + --build-arg BUILD_TIME=$(BUILD_TIME) \ + --build-arg VERSION=$(VERSION) \ + . + +# Verifies the -ldflags injection actually wires through to the buildinfo +# package. Builds a tiny throwaway binary, then runs it; expects to see the +# override value (`smoke-sha`) in stdout. CI can run this on every PR to +# catch a regression where someone breaks the ldflag path. +smoke-buildinfo: + @tmpdir=$$(mktemp -d) && \ + go build -ldflags "-X instant.dev/common/buildinfo.GitSHA=smoke-sha -X instant.dev/common/buildinfo.BuildTime=smoke-time -X instant.dev/common/buildinfo.Version=smoke-ver" \ + -o $$tmpdir/smoke ./cmd/smoke-buildinfo && \ + out=$$($$tmpdir/smoke) && \ + echo "$$out" | grep -q "GitSHA=smoke-sha" || (echo "FAIL: $$out" && exit 1) && \ + echo "$$out" | grep -q "BuildTime=smoke-time" || (echo "FAIL: $$out" && exit 1) && \ + echo "$$out" | grep -q "Version=smoke-ver" || (echo "FAIL: $$out" && exit 1) && \ + echo "smoke-buildinfo: OK ($$out)" && \ + rm -rf $$tmpdir # Regen the SQL ConfigMap from the actual migration file (run after schema changes) k8s-regen-migrations: diff --git a/cmd/smoke-buildinfo/main.go b/cmd/smoke-buildinfo/main.go new file mode 100644 index 00000000..d0d85133 --- /dev/null +++ b/cmd/smoke-buildinfo/main.go @@ -0,0 +1,17 @@ +// Command smoke-buildinfo prints the linked-in buildinfo values to stdout. +// +// Used by `make smoke-buildinfo` to verify the -ldflags -X path actually +// flows through to instant.dev/common/buildinfo at link time. The CI +// signal is "did the override land?" — not how the values are formatted. +package main + +import ( + "fmt" + + "instant.dev/common/buildinfo" +) + +func main() { + fmt.Printf("GitSHA=%s BuildTime=%s Version=%s\n", + buildinfo.GitSHA, buildinfo.BuildTime, buildinfo.Version) +}