From e36e46761a88f18c0601fd02e2e7da0f7a15cfa6 Mon Sep 17 00:00:00 2001 From: CrazyMax <1951866+crazy-max@users.noreply.github.com> Date: Mon, 16 Feb 2026 15:46:43 +0100 Subject: [PATCH] add registry-login input for optional registry auth before build Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> --- .github/workflows/.test-bake.yml | 22 ++++++++++++++++++++++ .github/workflows/.test-build.yml | 21 +++++++++++++++++++++ .github/workflows/bake.yml | 28 ++++++++++++++++++++++++++-- .github/workflows/build.yml | 28 ++++++++++++++++++++++++++-- README.md | 18 ++++++++++-------- test/dhi.Dockerfile | 9 +++++++++ test/docker-bake.hcl | 5 +++++ 7 files changed, 119 insertions(+), 12 deletions(-) create mode 100644 test/dhi.Dockerfile diff --git a/.github/workflows/.test-bake.yml b/.github/workflows/.test-bake.yml index 382851b..571cadc 100644 --- a/.github/workflows/.test-bake.yml +++ b/.github/workflows/.test-bake.yml @@ -561,3 +561,25 @@ jobs: sbom: true sign: ${{ github.event_name != 'pull_request' }} target: go-cross-with-contexts + + bake-local-login: + uses: ./.github/workflows/bake.yml + if: ${{ github.event_name != 'pull_request' }} + permissions: + contents: read + id-token: write + with: + artifact-name: bake-login-output + artifact-upload: true + context: test + output: local + registry-login: true + sbom: true + sign: true + target: dhi + secrets: + registry-auths: | + - registry: dhi.io + username: ${{ vars.DOCKERPUBLICBOT_USERNAME }} + password: ${{ secrets.DOCKERPUBLICBOT_READ_PAT }} + scope: 'dhi.io@pull' diff --git a/.github/workflows/.test-build.yml b/.github/workflows/.test-build.yml index aaaebe7..26dfa3d 100644 --- a/.github/workflows/.test-build.yml +++ b/.github/workflows/.test-build.yml @@ -578,3 +578,24 @@ jobs: - registry: registry-1-stage.docker.io username: ${{ vars.DOCKERHUB_STAGE_USERNAME }} password: ${{ secrets.DOCKERHUB_STAGE_TOKEN }} + + build-local-login: + uses: ./.github/workflows/build.yml + if: ${{ github.event_name != 'pull_request' }} + permissions: + contents: read + id-token: write + with: + artifact-name: build-login-output + artifact-upload: true + file: test/dhi.Dockerfile + output: local + registry-login: true + sbom: true + sign: true + secrets: + registry-auths: | + - registry: dhi.io + username: ${{ vars.DOCKERPUBLICBOT_USERNAME }} + password: ${{ secrets.DOCKERPUBLICBOT_READ_PAT }} + scope: 'dhi.io@pull' diff --git a/.github/workflows/bake.yml b/.github/workflows/bake.yml index 773c428..8c0df76 100644 --- a/.github/workflows/bake.yml +++ b/.github/workflows/bake.yml @@ -60,6 +60,11 @@ on: description: "Push image to the registry (for image output)" required: false default: false + registry-login: + type: string + description: "Login to registry before build to allow pulling private images (one of auto, true or false). The auto mode enables login only when output is image and push is true" + required: false + default: auto sbom: type: boolean description: "Generate SBOM attestation for the build" @@ -120,7 +125,7 @@ on: required: false secrets: registry-auths: - description: "Raw authentication to registries, defined as YAML objects (for image output)" + description: "Raw authentication to registries, defined as YAML objects" required: false github-token: description: "GitHub Token used to authenticate against the repository for Git context" @@ -162,6 +167,7 @@ jobs: includes: ${{ steps.set.outputs.includes }} sign: ${{ steps.set.outputs.sign }} ghaCacheSign: ${{ steps.set.outputs.ghaCacheSign }} + registryLogin: ${{ steps.set.outputs.registryLogin }} steps: - name: Install @docker/actions-toolkit @@ -240,6 +246,8 @@ jobs: INPUT_FILES: ${{ inputs.files }} INPUT_OUTPUT: ${{ inputs.output }} INPUT_PUSH: ${{ inputs.push }} + INPUT_REGISTRY-LOGIN: ${{ inputs.registry-login }} + INPUT_REGISTRY-AUTHS-SET: ${{ secrets.registry-auths != '' }} INPUT_SBOM: ${{ inputs.sbom }} INPUT_SET: ${{ inputs.set }} INPUT_SIGN: ${{ inputs.sign }} @@ -265,6 +273,8 @@ jobs: const inpFiles = Util.getInputList('files'); const inpOutput = core.getInput('output'); const inpPush = core.getBooleanInput('push'); + const inpRegistryLogin = core.getInput('registry-login'); + const inpRegistryAuthsSet = core.getBooleanInput('registry-auths-set'); const inpSbom = core.getBooleanInput('sbom'); const inpSet = Util.getInputList('set', {ignoreComma: true, quote: false}); const inpSign = core.getInput('sign'); @@ -296,6 +306,16 @@ jobs: return; } + if (!['auto', 'true', 'false'].includes(inpRegistryLogin)) { + core.setFailed(`Invalid registry-login input: ${inpRegistryLogin}`); + return; + } + const registryLogin = inpRegistryLogin === 'auto' ? inpOutput === 'image' && inpPush : inpRegistryLogin === 'true'; + if (registryLogin && !inpRegistryAuthsSet) { + core.setFailed(`registry-login is enabled but registry-auths secret is not set`); + return; + } + const bakeSource = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}.git#${process.env.GITHUB_REF}:${inpContext}`; await core.group(`Set bake source`, async () => { core.info(bakeSource); @@ -421,6 +441,10 @@ jobs: core.info(`ghaCacheSign: ${ghaCacheSign}`); core.setOutput('ghaCacheSign', ghaCacheSign); }); + await core.group(`Set registryLogin output`, async () => { + core.info(`registryLogin: ${registryLogin}`); + core.setOutput('registryLogin', registryLogin); + }); build: runs-on: ${{ matrix.runner }} @@ -738,7 +762,7 @@ jobs: }); - name: Login to registry - if: ${{ inputs.push && inputs.output == 'image' }} + if: ${{ needs.prepare.outputs.registryLogin == 'true' }} uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: registry-auth: ${{ secrets.registry-auths }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c09ab32..b08cf65 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,6 +76,11 @@ on: description: "Push image to the registry (for image output)" required: false default: false + registry-login: + type: string + description: "Login to registry before build to allow pulling private images (one of auto, true or false). The auto mode enables login only when output is image and push is true" + required: false + default: auto sbom: type: boolean description: "Generate SBOM attestation for the build" @@ -123,7 +128,7 @@ on: required: false secrets: registry-auths: - description: "Raw authentication to registries, defined as YAML objects (for image output)" + description: "Raw authentication to registries, defined as YAML objects" required: false github-token: description: "GitHub Token used to authenticate against the repository for Git context" @@ -166,6 +171,7 @@ jobs: sign: ${{ steps.set.outputs.sign }} privateRepo: ${{ steps.set.outputs.privateRepo }} ghaCacheSign: ${{ steps.set.outputs.ghaCacheSign }} + registryLogin: ${{ steps.set.outputs.registryLogin }} steps: - name: Install @docker/actions-toolkit @@ -242,6 +248,8 @@ jobs: INPUT_OUTPUT: ${{ inputs.output }} INPUT_PLATFORMS: ${{ inputs.platforms }} INPUT_PUSH: ${{ inputs.push }} + INPUT_REGISTRY-LOGIN: ${{ inputs.registry-login }} + INPUT_REGISTRY-AUTHS-SET: ${{ secrets.registry-auths != '' }} INPUT_SIGN: ${{ inputs.sign }} with: script: | @@ -257,6 +265,8 @@ jobs: const inpPlatforms = Util.getInputList('platforms'); const inpOutput = core.getInput('output'); const inpPush = core.getBooleanInput('push'); + const inpRegistryLogin = core.getInput('registry-login'); + const inpRegistryAuthsSet = core.getBooleanInput('registry-auths-set'); const inpSign = core.getInput('sign'); let runner = inpRunner; @@ -284,6 +294,16 @@ jobs: return; } + if (!['auto', 'true', 'false'].includes(inpRegistryLogin)) { + core.setFailed(`Invalid registry-login input: ${inpRegistryLogin}`); + return; + } + const registryLogin = inpRegistryLogin === 'auto' ? inpOutput === 'image' && inpPush : inpRegistryLogin === 'true'; + if (registryLogin && !inpRegistryAuthsSet) { + core.setFailed(`registry-login is enabled but registry-auths secret is not set`); + return; + } + if (inpDistribute && inpPlatforms.length > inpMatrixSizeLimit) { core.setFailed(`Platforms to build exceed matrix size limit of ${inpMatrixSizeLimit}`); return; @@ -323,6 +343,10 @@ jobs: core.info(`ghaCacheSign: ${ghaCacheSign}`); core.setOutput('ghaCacheSign', ghaCacheSign); }); + await core.group(`Set registryLogin output`, async () => { + core.info(`registryLogin: ${registryLogin}`); + core.setOutput('registryLogin', registryLogin); + }); build: runs-on: ${{ matrix.runner }} @@ -595,7 +619,7 @@ jobs: } - name: Login to registry - if: ${{ inputs.push && inputs.output == 'image' }} + if: ${{ needs.prepare.outputs.registryLogin == 'true' }} uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 with: registry-auth: ${{ secrets.registry-auths }} diff --git a/README.md b/README.md index 9abbc21..de6c7f8 100644 --- a/README.md +++ b/README.md @@ -234,6 +234,7 @@ on: | `output` | String | | Build output destination (one of [`image`](https://docs.docker.com/build/exporters/image-registry/) or [`local`](https://docs.docker.com/build/exporters/local-tar/)). Unlike the `build-push-action`, it only accepts `image` or `local`. The reusable workflow takes care of setting the `outputs` attribute | | `platforms` | List/CSV | | List of [target platforms](https://docs.docker.com/engine/reference/commandline/buildx_build/#platform) to build | | `push` | Bool | `false` | [Push](https://docs.docker.com/engine/reference/commandline/buildx_build/#push) image to the registry (for `image` output) | +| `registry-login` | String | `auto` | Login to registry before build to allow pulling private images (one of `auto`, `true` or `false`). The `auto` mode enables login only when output is image and push is true | | `sbom` | Bool | `false` | Generate [SBOM](https://docs.docker.com/build/attestations/sbom/) attestation for the build | | `shm-size` | String | | Size of [`/dev/shm`](https://docs.docker.com/engine/reference/commandline/buildx_build/#shm-size) (e.g., `2g`) | | `sign` | String | `auto` | Sign attestation manifest for `image` output or artifacts for `local` output, can be one of `auto`, `true` or `false`. The `auto` mode will enable signing if `push` is enabled for pushing the `image` or if `artifact-upload` is enabled for uploading the `local` build output as GitHub Artifact | @@ -247,10 +248,10 @@ on: #### Secrets -| Name | Default | Description | -|------------------|-----------------------|--------------------------------------------------------------------------------| -| `registry-auths` | | Raw authentication to registries, defined as YAML objects (for `image` output) | -| `github-token` | `${{ github.token }}` | GitHub Token used to authenticate against the repository for Git context | +| Name | Default | Description | +|------------------|-----------------------|----------------------------------------------------------------------------------------------------------------| +| `registry-auths` | | Raw authentication to registries, defined as YAML objects (used for push/signing and optional pre-build login) | +| `github-token` | `${{ github.token }}` | GitHub Token used to authenticate against the repository for Git context | ### Bake reusable workflow @@ -338,6 +339,7 @@ on: | `files` | List | `{context}/docker-bake.hcl` | List of bake definition files | | `output` | String | | Build output destination (one of [`image`](https://docs.docker.com/build/exporters/image-registry/) or [`local`](https://docs.docker.com/build/exporters/local-tar/)). | | `push` | Bool | `false` | Push image to the registry (for `image` output) | +| `registry-login` | String | `auto` | Login to registry before build to allow pulling private images (one of `auto`, `true` or `false`). The `auto` mode enables login only when output is image and push is true | | `sbom` | Bool | `false` | Generate [SBOM](https://docs.docker.com/build/attestations/sbom/) attestation for the build | | `set` | List | | List of [target values to override](https://docs.docker.com/engine/reference/commandline/buildx_bake/#set) (e.g., `targetpattern.key=value`) | | `sign` | String | `auto` | Sign attestation manifest for `image` output or artifacts for `local` output, can be one of `auto`, `true` or `false`. The `auto` mode will enable signing if `push` is enabled for pushing the `image` or if `artifact-upload` is enabled for uploading the `local` build output as GitHub Artifact | @@ -353,7 +355,7 @@ on: #### Secrets -| Name | Default | Description | -|------------------|-----------------------|--------------------------------------------------------------------------------| -| `registry-auths` | | Raw authentication to registries, defined as YAML objects (for `image` output) | -| `github-token` | `${{ github.token }}` | GitHub Token used to authenticate against the repository for Git context | +| Name | Default | Description | +|------------------|-----------------------|----------------------------------------------------------------------------------------------------------------| +| `registry-auths` | | Raw authentication to registries, defined as YAML objects (used for push/signing and optional pre-build login) | +| `github-token` | `${{ github.token }}` | GitHub Token used to authenticate against the repository for Git context | diff --git a/test/dhi.Dockerfile b/test/dhi.Dockerfile new file mode 100644 index 0000000..dc651c1 --- /dev/null +++ b/test/dhi.Dockerfile @@ -0,0 +1,9 @@ +# syntax=docker/dockerfile:1 + +FROM dhi.io/alpine-base:3.23 AS base +ARG TARGETPLATFORM +RUN echo "Hello, World! This is ${TARGETPLATFORM}" > /tmp/hello.txt +ARG BUILDKIT_SBOM_SCAN_STAGE=true + +FROM scratch +COPY --from=base /tmp/hello.txt / diff --git a/test/docker-bake.hcl b/test/docker-bake.hcl index fbea740..b00cec7 100644 --- a/test/docker-bake.hcl +++ b/test/docker-bake.hcl @@ -67,3 +67,8 @@ target "generated-hello2" { dockerfile = "hello.Dockerfile" output = ["type=cacheonly"] } + +target "dhi" { + inherits = ["docker-metadata-action"] + dockerfile = "dhi.Dockerfile" +}