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 \