Skip to content

Commit fcb5a0c

Browse files
committed
bake: pass variables explicitly to buildx
Disable ambient Bake variable lookup so runner environment values cannot implicitly override the definition. Use BakeVars to forward CI, GITHUB_, RUNNER_ and DOCKER_METADATA_OUTPUT_ values, preserving caller precedence. Pass variables explicitly to definition validation and bake-action. Serialize the action input as JSON to preserve multiline metadata values. Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
1 parent 62eefc8 commit fcb5a0c

5 files changed

Lines changed: 115 additions & 44 deletions

File tree

‎.github/workflows/.test-bake.yml‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -599,13 +599,20 @@ jobs:
599599
contents: read
600600
id-token: write
601601
with:
602-
setup-qemu: true
603-
artifact-upload: false
604602
context: test
605-
output: local
606-
target: go
603+
output: image
604+
push: false
605+
target: vars
607606
vars: |
608607
XX_VERSION=1.9.0
608+
DOCKER_METADATA_OUTPUT_VERSION=caller-version
609+
meta-images: example/app
610+
meta-tags: |
611+
type=raw,value=vars-one
612+
type=raw,value=vars-two
613+
meta-labels: |
614+
org.example.vars.one=one
615+
org.example.vars.two=two
609616
610617
bake-auth-scope:
611618
uses: ./.github/workflows/bake.yml

‎.github/workflows/bake.yml‎

Lines changed: 29 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ jobs:
347347
const { GitHub } = require('@docker/github-builder-runtime/lib/github/github');
348348
const { RunnerMapping } = require('@docker/github-builder-runtime/lib/github-builder/runner-mapping');
349349
const { BakeTargets } = require('@docker/github-builder-runtime/lib/github-builder/bake-targets');
350+
const { BakeVars } = require('@docker/github-builder-runtime/lib/github-builder/bake-vars');
350351
const { Util } = require('@docker/github-builder-runtime/lib/util');
351352
352353
const inpSbomImage = core.getInput('sbom-image');
@@ -359,7 +360,7 @@ jobs:
359360
const inpArtifactUpload = core.getBooleanInput('artifact-upload');
360361
const inpJobNamePrefix = core.getInput('job-name-prefix');
361362
const inpContext = core.getInput('context');
362-
const inpVars = Util.getInputList('vars');
363+
const inpVars = Util.getInputList('vars', {ignoreComma: true, quote: false});
363364
const inpFiles = Util.getInputList('files');
364365
const inpOutput = core.getInput('output');
365366
const inpPush = core.getBooleanInput('push');
@@ -409,21 +410,12 @@ jobs:
409410
}
410411
const registryLogin = inpRegistryLogin === 'auto' ? inpOutput === 'image' && inpPush : inpRegistryLogin === 'true';
411412
412-
const envs = Object.assign({},
413-
inpVars ? inpVars.reduce((acc, curr) => {
414-
const idx = curr.indexOf('=');
415-
if (idx !== -1) {
416-
acc[curr.substring(0, idx)] = curr.substring(idx + 1);
417-
}
418-
return acc;
419-
}, {}) : {},
420-
{
421-
BUILDKIT_MULTI_PLATFORM: '1',
422-
BUILDX_BAKE_GIT_AUTH_TOKEN: inpGitHubToken
423-
}
424-
);
425-
await core.group(`Set envs`, async () => {
426-
core.info(JSON.stringify(Object.keys(envs).sort(), null, 2));
413+
const bakeVars = BakeVars.resolve(inpVars);
414+
await core.group(`Set bake vars`, async () => {
415+
core.info(JSON.stringify(bakeVars.map(value => {
416+
const idx = value.indexOf('=');
417+
return idx === -1 ? '<invalid>' : value.substring(0, idx);
418+
}).sort(), null, 2));
427419
});
428420
429421
const metaImages = inpMetaImages.map(image => image.toLowerCase());
@@ -448,9 +440,14 @@ jobs:
448440
overrides: [...validationOverrides, '*.secrets='],
449441
sbom: inpSbom ? `generator=${inpSbomImage}` : 'false',
450442
source: bakeSource,
451-
targets: [inpTarget]
443+
targets: [inpTarget],
444+
vars: bakeVars,
445+
githubToken: inpGitHubToken
452446
}, {
453-
env: Object.keys(envs).length > 0 ? envs : undefined
447+
env: {
448+
BUILDKIT_MULTI_PLATFORM: '1',
449+
BUILDX_BAKE_DISABLE_VARS_ENV_LOOKUP: '1'
450+
}
454451
});
455452
if (!def) {
456453
throw new Error('Bake definition not set');
@@ -857,6 +854,7 @@ jobs:
857854
const os = require('os');
858855
const { Build } = require('@docker/github-builder-runtime/lib/buildx/build');
859856
const { BuildSecrets } = require('@docker/github-builder-runtime/lib/github-builder/build-secrets');
857+
const { BakeVars } = require('@docker/github-builder-runtime/lib/github-builder/bake-vars');
860858
const { GitHub } = require('@docker/github-builder-runtime/lib/github/github');
861859
const { Util } = require('@docker/github-builder-runtime/lib/util');
862860
@@ -879,7 +877,7 @@ jobs:
879877
const inpSbom = core.getBooleanInput('sbom');
880878
const inpSet = Util.getInputList('set', {ignoreComma: true, quote: false});
881879
const inpTarget = core.getInput('target');
882-
const inpVars = Util.getInputList('vars');
880+
const inpVars = Util.getInputList('vars', {ignoreComma: true, quote: false});
883881
const inpBuildkitProxyNetwork = core.getBooleanInput('buildkit-proxy-network');
884882
885883
const inpMetaImages = core.getMultilineInput('meta-images');
@@ -924,27 +922,15 @@ jobs:
924922
}
925923
core.setOutput('secret-dir', buildSecrets.directory);
926924
927-
const envs = Object.assign({},
928-
inpVars ? inpVars.reduce((acc, curr) => {
929-
const idx = curr.indexOf('=');
930-
if (idx !== -1) {
931-
acc[curr.substring(0, idx)] = curr.substring(idx + 1);
932-
}
933-
return acc;
934-
}, {}) : {},
935-
{
936-
BUILDKIT_MULTI_PLATFORM: '1'
937-
}
938-
);
939-
940-
// Git authentication is supplied directly to the Bake action.
941-
delete envs.BUILDX_BAKE_GIT_AUTH_TOKEN;
942-
943-
await core.group(`Set envs`, async () => {
944-
core.info(JSON.stringify(Object.keys(envs).sort(), null, 2));
945-
core.setOutput('envs', JSON.stringify(envs));
925+
const bakeVars = BakeVars.resolve(inpVars);
926+
await core.group(`Set bake vars`, async () => {
927+
core.info(JSON.stringify(bakeVars.map(value => {
928+
const idx = value.indexOf('=');
929+
return idx === -1 ? '<invalid>' : value.substring(0, idx);
930+
}).sort(), null, 2));
931+
core.setOutput('vars', JSON.stringify(bakeVars));
946932
});
947-
933+
948934
let bakeFiles = inpFiles;
949935
await core.group(`Set bake files`, async () => {
950936
if (bakeFiles.length === 0) {
@@ -1019,8 +1005,11 @@ jobs:
10191005
targets: ${{ steps.prepare.outputs.target }}
10201006
sbom: ${{ steps.prepare.outputs.sbom }}
10211007
set: ${{ steps.prepare.outputs.overrides }}
1008+
vars: ${{ steps.prepare.outputs.vars }}
10221009
github-token: ${{ secrets.github-token || github.token }}
1023-
env: ${{ fromJson(steps.prepare.outputs.envs || '{}') }}
1010+
env:
1011+
BUILDKIT_MULTI_PLATFORM: '1'
1012+
BUILDX_BAKE_DISABLE_VARS_ENV_LOOKUP: '1'
10241013
-
10251014
name: Remove build secrets
10261015
if: ${{ always() && steps.prepare.outputs.secret-dir != '' }}

‎README.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,14 @@ jobs:
377377
| `meta-flavor` | List | | [Flavor](https://github.com/docker/metadata-action?tab=readme-ov-file#flavor-input) defines a global behavior for `meta-tags` |
378378
| `buildkit-proxy-network` | Bool | `false` | Enable BuildKit proxy network mode for default Dockerfile `RUN` networking. See [BuildKit proxy network](#buildkit-proxy-network). |
379379

380+
> [!NOTE]
381+
> The `vars` input is passed to Buildx as explicit Bake variables. Ambient
382+
> environment lookup for Bake variables is disabled. The `CI` environment variable
383+
> and variables with `GITHUB_`, `RUNNER_`, or `DOCKER_METADATA_OUTPUT_` prefixes
384+
> are forwarded as explicit vars for workflows that declare them in their Bake
385+
> definition. Multiline metadata values are preserved. Caller-provided vars take
386+
> precedence over these forwarded values.
387+
380388
### Secrets
381389

382390
| Name | Default | Description |

‎test/docker-bake.hcl‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,34 @@ variable "XX_VERSION" {
1515
default = null
1616
}
1717

18+
variable "BUILDX_VERSION" {
19+
default = "not-leaked"
20+
}
21+
22+
variable "CI" {
23+
default = ""
24+
}
25+
26+
variable "GITHUB_SHA" {
27+
default = ""
28+
}
29+
30+
variable "RUNNER_OS" {
31+
default = ""
32+
}
33+
34+
variable "DOCKER_METADATA_OUTPUT_VERSION" {
35+
default = ""
36+
}
37+
38+
variable "DOCKER_METADATA_OUTPUT_TAGS" {
39+
default = ""
40+
}
41+
42+
variable "DOCKER_METADATA_OUTPUT_LABELS" {
43+
default = ""
44+
}
45+
1846
target "go" {
1947
inherits = ["docker-metadata-action"]
2048
args = {
@@ -23,6 +51,20 @@ target "go" {
2351
dockerfile = "go.Dockerfile"
2452
}
2553

54+
target "vars" {
55+
args = {
56+
BUILDX_VERSION = BUILDX_VERSION
57+
CI = CI
58+
GITHUB_SHA = GITHUB_SHA
59+
RUNNER_OS = RUNNER_OS
60+
XX_VERSION = XX_VERSION
61+
DOCKER_METADATA_OUTPUT_VERSION = DOCKER_METADATA_OUTPUT_VERSION
62+
DOCKER_METADATA_OUTPUT_TAGS = DOCKER_METADATA_OUTPUT_TAGS
63+
DOCKER_METADATA_OUTPUT_LABELS = DOCKER_METADATA_OUTPUT_LABELS
64+
}
65+
dockerfile = "vars.Dockerfile"
66+
}
67+
2668
target "go-cross" {
2769
inherits = ["go"]
2870
platforms = ["linux/amd64", "linux/arm64"]

‎test/vars.Dockerfile‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# syntax=docker/dockerfile:1
2+
3+
FROM alpine
4+
ARG BUILDX_VERSION
5+
ARG CI
6+
ARG GITHUB_SHA
7+
ARG RUNNER_OS
8+
ARG XX_VERSION
9+
ARG DOCKER_METADATA_OUTPUT_VERSION
10+
ARG DOCKER_METADATA_OUTPUT_TAGS
11+
ARG DOCKER_METADATA_OUTPUT_LABELS
12+
RUN test "$BUILDX_VERSION" = "not-leaked"
13+
RUN test "$CI" = "true"
14+
RUN test -n "$GITHUB_SHA"
15+
RUN test -n "$RUNNER_OS"
16+
RUN test "$XX_VERSION" = "1.9.0"
17+
RUN test "$DOCKER_METADATA_OUTPUT_VERSION" = "caller-version"
18+
RUN printf '%s\n' "$DOCKER_METADATA_OUTPUT_TAGS" | grep -Fx 'example/app:vars-one' \
19+
&& printf '%s\n' "$DOCKER_METADATA_OUTPUT_TAGS" | grep -Fx 'example/app:vars-two'
20+
RUN printf '%s\n' "$DOCKER_METADATA_OUTPUT_LABELS" | grep -Fx 'org.example.vars.one=one' \
21+
&& printf '%s\n' "$DOCKER_METADATA_OUTPUT_LABELS" | grep -Fx 'org.example.vars.two=two'
22+
RUN mkdir -p /out && printf 'ok\n' > /out/vars.txt
23+
24+
FROM scratch
25+
COPY --from=0 /out /

0 commit comments

Comments
 (0)