From e9c9fe79d42d29c740e59af0d6fee312c8d2b6d8 Mon Sep 17 00:00:00 2001 From: Jeremy Collins Date: Thu, 27 Aug 2026 20:33:38 -0400 Subject: [PATCH] Check that the build version reaches the binary - Read the linker flags back out of each binary the Makefile builds. - Refuse an image build that takes a VERSION arg without declaring it. - Run the built container and the released binary to confirm the version. --- .github/workflows/pr.yml | 24 ++++++++++++++++++++++++ .github/workflows/release.yml | 11 +++++++++++ Makefile | 14 +++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index d521451..d6abed2 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -49,6 +49,18 @@ jobs: make VERSION=version-probe test "$(./build/dims version)" = "version-probe" + # A build arg only reaches make when the Dockerfile declares it. Both + # image builds once took VERSION without declaring it, so every released + # artifact carried the commit hash instead of the tag. + - name: Check every image build declares VERSION + run: | + for file in Dockerfile Dockerfile.lambda Dockerfile.binaries; do + grep -qE '^ARG VERSION' "$file" || { + echo "$file takes a VERSION build arg but never declares it" + exit 1 + } + done + - name: Scan for vulnerabilities run: | go install golang.org/x/vuln/cmd/govulncheck@latest @@ -86,8 +98,20 @@ jobs: with: context: . push: false + load: true + tags: go-dims:pr + build-args: VERSION=pr-${{ github.event.pull_request.number }} platforms: ${{ matrix.platform }} + - name: Check the version reaches the container + run: | + expected="pr-${{ github.event.pull_request.number }}" + actual="$(docker run --rm go-dims:pr version)" + test "$actual" = "$expected" || { + echo "want $expected, got $actual" + exit 1 + } + - name: Build Lambda Function uses: docker/build-push-action@v5 id: lambda diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0c8ef3b..50cc084 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -98,6 +98,17 @@ jobs: platforms: ${{ matrix.platform }} outputs: type=local,dest=build + # The runner matches the target architecture, so the released binary + # answers for itself. + - name: Check the version reaches the binary + run: | + unzip -o -q build/dims-linux-${{ matrix.targetarch }}.zip -d /tmp/dims-release + actual="$(/tmp/dims-release/dims version)" + test "$actual" = "${{ env.TRACKING_TAG }}" || { + echo "want ${{ env.TRACKING_TAG }}, got $actual" + exit 1 + } + - name: Upload Standalone Binary uses: actions/upload-artifact@v4 with: diff --git a/Makefile b/Makefile index ee799ca..90e6a2a 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION ?= $(shell git rev-parse --short=8 HEAD) +VERSION ?= $(shell git rev-parse --short=8 HEAD 2>/dev/null || echo unknown) BUILD_DIR := build BOOTSTRAP := $(BUILD_DIR)/bootstrap REGISTRY := ghcr.io/beetlebugorg/go-dims @@ -9,17 +9,28 @@ LAMBDA_BINARY := $(BUILD_DIR)/bootstrap LD_FLAGS = "-X 'github.com/beetlebugorg/go-dims/internal/core.Version=${VERSION}'" STATIC_LDFLAGS = "-X 'github.com/beetlebugorg/go-dims/internal/core.Version=${VERSION}' -linkmode 'external' -extldflags '-fno-PIC -static -Wl,-z,stack-size=8388608 -lpng -lz -ltiff -lwebp -lwebpmux -lwebpdemux -ljpeg -lbz2 -lexpat -llcms2 -lgomp -lsharpyuv'" +# verify-version reads the linker flags back out of a built binary and fails +# when VERSION did not reach it. Dockerfile.lambda and Dockerfile.binaries once +# took a VERSION build arg they never declared, so every released artifact +# carried the commit hash instead of the release tag and nothing reported it. +# The lambda binary cannot be run to ask for its version, so this reads the +# recorded build settings instead. +verify-version = @go version -m $(1) | grep -qF "core.Version=$(VERSION)" \ + || { echo "VERSION=$(VERSION) did not reach $(1)"; exit 1; } + # -- Build targets # Builds the shared library version of dims all: go generate ./... go build -o $(BINARY) -ldflags $(LD_FLAGS) ./cmd/dims + $(call verify-version,$(BINARY)) # Builds a static binary version of dims static: go generate ./... go build -o $(BINARY) -ldflags $(STATIC_LDFLAGS) ./cmd/dims + $(call verify-version,$(BINARY)) binary-amd64: docker buildx build \ @@ -40,6 +51,7 @@ binary-arm64: lambda: go generate ./... go build -o $(LAMBDA_BINARY) -tags "lambda.norpc lambda" -ldflags $(STATIC_LDFLAGS) ./cmd/dims + $(call verify-version,$(LAMBDA_BINARY)) cd $(BUILD_DIR) && zip lambda.zip bootstrap lambda-amd64: