From c16a76aec208e45f2d0c5ece134c520acca27999 Mon Sep 17 00:00:00 2001 From: samuelho-dev Date: Tue, 9 Jun 2026 13:40:16 -0700 Subject: [PATCH] feat(docker-build): add secret-build-args for secret-valued build args MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitHub strips secret values from job outputs, so a caller that resolves environment-scoped secrets in one job and hands them to this reusable workflow's build-args input via `needs.x.outputs.*` gets EMPTY build-args — silently baking undefined into the image (e.g. NEXT_PUBLIC_* inlined as undefined by next build, crashing the app at runtime env validation). Add a `secret-build-args` secret input, merged with the plain build-args inside the build job (where secrets resolve). Read from an env var so values aren't echoed; step outputs keep real values within a job (only cross-job outputs are stripped). build-args bake into image layers, so this is for public-anyway values (NEXT_PUBLIC_*), documented in the input description. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/docker-build-push.yml | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-build-push.yml b/.github/workflows/docker-build-push.yml index a5fe557..9e213ae 100644 --- a/.github/workflows/docker-build-push.yml +++ b/.github/workflows/docker-build-push.yml @@ -79,6 +79,16 @@ on: registry-password: description: 'Registry password/token' required: false + secret-build-args: + description: >- + Build args whose VALUES are secrets (KEY=VALUE, one per line), merged + with `build-args`. Pass these here, NOT via a caller job `output` — + GitHub strips secret values from job outputs, so an output handoff + silently yields empty build-args. Secrets resolve inside this job's + steps, so they reach the build correctly. NOTE: build-args bake into + image layers (visible via `docker history`) — use only for values that + are public anyway (e.g. NEXT_PUBLIC_*), never for true secrets. + required: false outputs: digest: description: 'Image digest (sha256:...)' @@ -146,12 +156,22 @@ jobs: - name: Parse build arguments id: build-args - if: inputs.build-args != '' shell: bash + # Merge plain `build-args` with `secret-build-args`. The secret values + # are read from an env var (not interpolated into the script body) so + # they aren't echoed; GitHub masks them in logs, and step outputs keep + # their real values WITHIN this job (only cross-job outputs get stripped, + # which is the bug this input exists to avoid). docker/build-push-action + # de-dupes by key, so a key in both wins from whichever appears last — + # secret args are appended last so they take precedence. + env: + PLAIN_BUILD_ARGS: ${{ inputs.build-args }} + SECRET_BUILD_ARGS: ${{ secrets.secret-build-args }} run: | { echo "args<> "$GITHUB_OUTPUT"