From 62955c998de9286342112a7e7a3971200f6bdf5e Mon Sep 17 00:00:00 2001 From: Mathias Date: Fri, 28 Aug 2026 13:31:59 +0200 Subject: [PATCH] fix(ci): authenticate go mod download against the private cad module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Build & Import (run #68) failed: mathias/cad is PRIVATE (unlike mcp-chassis, the only other internal module a cad-* Dockerfile has fetched so far, which is public) — 'go mod download' inside the Docker build had no credential and died on 'terminal prompts disabled'. Fix mirrors this repo's own existing GIT_ASKPASS pattern (cd.yml's oathcandidate step, for the private swedsl dependency): a BuildKit secret mount feeds a GIT_ASKPASS helper for the one RUN that needs it. The token is never written to a persisted layer — the askpass script and its reference to /run/secrets/gitea_token are created and removed within the same RUN instruction. cd.yml writes the token to a file only for build-image.sh's subprocess and passes it via BUILD_SECRETS (the script's existing mechanism — 'the caller writes the secret to PATH itself'). Verified by running build-image.sh's actual buildctl invocation locally against the real koala buildkitd (same daemon CI uses) with a real token — 'go mod download' completes in 1.9s, full build succeeds. Reproduced the CI failure log before writing this fix, per house discipline. Co-Authored-By: Claude Sonnet 5 --- .gitea/workflows/cd.yml | 20 +++++++++++++++++++- Dockerfile | 18 +++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/cd.yml b/.gitea/workflows/cd.yml index 366d5b3..1b8f4af 100644 --- a/.gitea/workflows/cd.yml +++ b/.gitea/workflows/cd.yml @@ -146,11 +146,29 @@ jobs: # byte-identical copy of mathias/infra's ci-templates/build-image.sh. # Do not edit it here -- edit the canonical file, run `task ci:sync`, # and infra's drift gate names any repo still carrying an old copy. + # + # cad-atlas#11: the build now fetches git.d-ma.be/mathias/cad, a + # PRIVATE module (unlike mcp-chassis, the only other internal module + # any cad-* repo's Dockerfile has fetched so far, which is public) -- + # `go mod download` inside the Dockerfile needs to authenticate. The + # token is written to a file ONLY for the build-image.sh subprocess and + # passed as a BuildKit secret (build-image.sh's existing BUILD_SECRETS + # mechanism: "the caller writes the secret to PATH itself... a secret + # VALUE must never be passed here"), never as a build-arg or env var + # that would land in the image or this log. env: SHA_TAG: ${{ steps.meta.outputs.sha-tag }} GIT_SHA: ${{ github.sha }} BUILD_ARGS: VERSION=${{ steps.meta.outputs.version }} - run: bash .gitea/build-image.sh + DMABE_GITEA_API_TOKEN: ${{ secrets.DMABE_GITEA_API_TOKEN }} + run: | + set -euo pipefail + TOKEN_FILE=$(mktemp) + printf '%s' "$DMABE_GITEA_API_TOKEN" > "$TOKEN_FILE" + chmod 600 "$TOKEN_FILE" + export BUILD_SECRETS="id=gitea_token,src=${TOKEN_FILE}" + bash .gitea/build-image.sh + shred -u "$TOKEN_FILE" deploy: name: Deploy via GitOps diff --git a/Dockerfile b/Dockerfile index 525d9e6..f208d98 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,6 +6,18 @@ WORKDIR /src # proxy.golang.org. Gitea returns http:// in its go-import meta tag, so # rewrite to https and bypass the module proxy + sumdb (mirrors mathias/cad's # own Dockerfile — same trick, same reason). +# +# UNLIKE mcp-chassis (public, what cad's own Dockerfile fetches this way), +# mathias/cad is a PRIVATE repo, so the plain insteadOf rewrite above is not +# enough — `go mod download` needs to authenticate. Use a GIT_ASKPASS helper +# reading a BuildKit secret mount (mirrors the GIT_ASKPASS pattern this +# repo's own cd.yml already uses for the oathcandidate module's private +# swedsl dependency): the token is never written to a persisted layer — the +# askpass script and its reference to /run/secrets/gitea_token are created +# and removed within the same RUN instruction, and the secret mount itself +# is never part of any layer diff. Caller passes it via +# `BUILD_SECRETS="id=gitea_token,src="` (build-image.sh's existing +# mechanism) — see cd.yml. RUN apk add --no-cache git && \ git config --global url."https://git.d-ma.be/".insteadOf "http://git.d-ma.be/" ENV GOPRIVATE=git.d-ma.be @@ -13,7 +25,11 @@ ENV GOPROXY=direct ENV GOSUMDB=off RUN go install github.com/a-h/templ/cmd/templ@latest COPY go.mod go.sum ./ -RUN go mod download +RUN --mount=type=secret,id=gitea_token \ + printf '#!/bin/sh\ncase "$1" in *sername*) echo oauth2 ;; *) cat /run/secrets/gitea_token ;; esac\n' > /tmp/askpass.sh && \ + chmod 700 /tmp/askpass.sh && \ + GIT_ASKPASS=/tmp/askpass.sh GIT_TERMINAL_PROMPT=0 go mod download && \ + rm -f /tmp/askpass.sh COPY . . ARG VERSION=dev RUN templ generate && CGO_ENABLED=0 go build -trimpath \