From 7dffd70c0ea2570d9d98ca056105f42aca0a8ac9 Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Wed, 8 Apr 2026 21:02:19 -0500 Subject: [PATCH] build: publish multi-arch (amd64 + arm64) container images Adds linux/arm64 to the published image so Apple Silicon developers can run the operator locally without QEMU. - Dockerfile: pin builder to BUILDPLATFORM and cross-compile to TARGETARCH so arm64 builds run natively on amd64 runners (and vice versa) instead of under emulation. - Dockerfile: stamp version metadata into the binary via -ldflags using the VERSION/GIT_COMMIT/GIT_TREE_STATE/BUILD_DATE build args the shared publish workflow already provides. - cmd/main.go: log the stamped build metadata on startup. - publish.yaml: bump the shared publish-docker workflow to v1.13.1 and request linux/amd64,linux/arm64. Verified locally with docker buildx: cold multi-arch build is ~47s, warm rebuild is ~7s, both architectures cross-compile natively. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/publish.yaml | 3 ++- Dockerfile | 14 ++++++++++++-- cmd/main.go | 13 +++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 335b929..6ea37be 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -11,9 +11,10 @@ jobs: id-token: write contents: read packages: write - uses: datum-cloud/actions/.github/workflows/publish-docker.yaml@v1.5.1 + uses: datum-cloud/actions/.github/workflows/publish-docker.yaml@v1.13.1 with: image-name: workload-operator + platforms: linux/amd64,linux/arm64 secrets: inherit publish-kustomize-bundles: diff --git a/Dockerfile b/Dockerfile index 491b7fe..e5f577d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,11 @@ # Build the manager binary -FROM golang:1.24 AS builder +FROM --platform=$BUILDPLATFORM golang:1.24 AS builder ARG TARGETOS ARG TARGETARCH +ARG VERSION=dev +ARG GIT_COMMIT=unknown +ARG GIT_TREE_STATE=unknown +ARG BUILD_DATE=unknown WORKDIR /workspace # Copy the Go Modules manifests @@ -26,7 +30,13 @@ ENV GOCACHE=/root/.cache/go-build ENV GOTMPDIR=/root/.cache/go-build RUN --mount=type=cache,target=/go/pkg/mod/ \ --mount=type=cache,target="/root/.cache/go-build" \ - CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go + CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build \ + -ldflags "-s -w \ + -X main.version=${VERSION} \ + -X main.gitCommit=${GIT_COMMIT} \ + -X main.gitTreeState=${GIT_TREE_STATE} \ + -X main.buildDate=${BUILD_DATE}" \ + -o manager cmd/main.go # Use distroless as minimal base image to package the manager binary # Refer to https://github.com/GoogleContainerTools/distroless for more details diff --git a/cmd/main.go b/cmd/main.go index 2deba5d..9517e70 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -44,6 +44,12 @@ var ( scheme = runtime.NewScheme() setupLog = ctrl.Log.WithName("setup") codecs = serializer.NewCodecFactory(scheme, serializer.EnableStrict) + + // Build metadata, set via -ldflags at build time. See Dockerfile. + version = "dev" + gitCommit = "unknown" + gitTreeState = "unknown" + buildDate = "unknown" ) func init() { @@ -81,6 +87,13 @@ func main() { ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) + setupLog.Info("starting workload-operator", + "version", version, + "gitCommit", gitCommit, + "gitTreeState", gitTreeState, + "buildDate", buildDate, + ) + var serverConfig config.WorkloadOperator var configData []byte if len(serverConfigFile) > 0 {