This commit is contained in:
CrazyMax 2026-04-01 13:42:21 +00:00 committed by GitHub
commit 82c21eb975
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 285 additions and 59 deletions

View file

@ -101,6 +101,57 @@ jobs:
exit 1
fi
git-context-query:
runs-on: ubuntu-latest
env:
BUILDX_SEND_GIT_QUERY_AS_INPUT: true
services:
registry:
image: registry:2.8.3@sha256:a3d8aaa63ed8681a604f1dea0aa03f100d5895b6a58ace528858a7b332415373
ports:
- 5000:5000
steps:
-
name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: action
-
name: Set up QEMU
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
-
name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
with:
version: v0.29.0
driver-opts: |
network=host
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
-
name: Build and push
id: docker_build
uses: ./action
with:
file: ./test/Dockerfile
builder: ${{ steps.buildx.outputs.name }}
platforms: linux/amd64,linux/arm64
push: true
tags: |
localhost:5000/name/app:latest
localhost:5000/name/app:1.0.0
-
name: Inspect
run: |
docker buildx imagetools inspect localhost:5000/name/app:1.0.0 --format '{{json .}}'
-
name: Check digest
run: |
if [ -z "${{ steps.docker_build.outputs.digest }}" ]; then
echo "::error::Digest should not be empty"
exit 1
fi
git-context-secret:
runs-on: ubuntu-latest
services:
@ -394,6 +445,29 @@ jobs:
MYSECRET=foo
INVALID_SECRET=
secret-files:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
with:
version: ${{ inputs.buildx-version || env.BUILDX_VERSION }}
driver-opts: |
image=${{ inputs.buildkit-image || env.BUILDKIT_IMAGE }}
-
name: Build
uses: ./
with:
context: .
file: ./test/secret.Dockerfile
secret-files: |
MYSECRET=./test/secret.txt
INVALID_SECRET=
secret-envs:
runs-on: ubuntu-latest
steps:

View file

@ -12,8 +12,6 @@ import {Toolkit} from '@docker/actions-toolkit/lib/toolkit.js';
import {BuilderInfo} from '@docker/actions-toolkit/lib/types/buildx/builder.js';
import * as context from '../src/context.js';
const tmpDir = fs.mkdtempSync(path.join(process.env.TEMP || os.tmpdir(), 'context-'));
const tmpName = path.join(tmpDir, '.tmpname-vi');
const fixturesDir = path.join(__dirname, 'fixtures');
@ -52,6 +50,53 @@ vi.spyOn(Builder.prototype, 'inspect').mockImplementation(async (): Promise<Buil
};
});
describe('getInputs', () => {
const originalEnv = process.env;
beforeEach(() => {
process.env = Object.keys(process.env).reduce((object, key) => {
if (!key.startsWith('INPUT_')) {
object[key] = process.env[key];
}
return object;
}, {});
});
afterEach(() => {
process.env = originalEnv;
});
function setRequiredBooleanInputs(): void {
setInput('load', 'false');
setInput('no-cache', 'false');
setInput('push', 'false');
setInput('pull', 'false');
}
test('uses Build git context when context input is empty', async () => {
const gitContext = 'https://github.com/docker/build-push-action.git?ref=refs/heads/master';
const gitContextSpy = vi.spyOn(Build.prototype, 'gitContext').mockResolvedValue(gitContext);
setRequiredBooleanInputs();
const context = await loadContextModule();
const inputs = await context.getInputs();
expect(inputs.context).toBe(gitContext);
expect(gitContextSpy).toHaveBeenCalledTimes(1);
gitContextSpy.mockRestore();
});
test('renders defaultContext templates from Build git context', async () => {
const gitContext = 'https://github.com/docker/build-push-action.git#refs/heads/master';
const gitContextSpy = vi.spyOn(Build.prototype, 'gitContext').mockResolvedValue(gitContext);
setRequiredBooleanInputs();
setInput('context', '{{defaultContext}}:subdir');
const context = await loadContextModule();
const inputs = await context.getInputs();
expect(inputs.context).toBe(`${gitContext}:subdir`);
expect(gitContextSpy).toHaveBeenCalledTimes(1);
gitContextSpy.mockRestore();
});
});
describe('getArgs', () => {
const originalEnv = process.env;
beforeEach(() => {
@ -344,7 +389,7 @@ ccc`],
'build',
'--file', './test/Dockerfile',
'--iidfile', imageIDFilePath,
'--secret', `id=MY_SECRET,src=${tmpName}`,
'--secret', `id=MY_SECRET,src=${path.join(fixturesDir, 'secret.txt')}`,
'--builder', 'builder-git-context-2',
'--network', 'host',
'--push',
@ -888,6 +933,46 @@ ANOTHER_SECRET=ANOTHER_SECRET_ENV`]
['GITHUB_SERVER_URL', 'https://github.cds.internal.unity3d.com'],
])
],
[
37,
'0.29.0',
new Map<string, string>([
['load', 'false'],
['no-cache', 'false'],
['push', 'false'],
['pull', 'false'],
]),
[
'build',
'--iidfile', imageIDFilePath,
'--attest', `type=provenance,mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789/attempts/1`,
'--metadata-file', metadataJson,
'https://github.com/docker/build-push-action.git?ref=refs/heads/master'
],
new Map<string, string>([
['BUILDX_SEND_GIT_QUERY_AS_INPUT', 'true']
])
],
[
38,
'0.28.0',
new Map<string, string>([
['load', 'false'],
['no-cache', 'false'],
['push', 'false'],
['pull', 'false'],
]),
[
'build',
'--iidfile', imageIDFilePath,
'--attest', `type=provenance,mode=min,inline-only=true,builder-id=https://github.com/docker/build-push-action/actions/runs/123456789/attempts/1`,
'--metadata-file', metadataJson,
'https://github.com/docker/build-push-action.git#refs/heads/master'
],
new Map<string, string>([
['BUILDX_SEND_GIT_QUERY_AS_INPUT', 'true']
])
],
])(
'[%d] given %o with %o as inputs, returns %o',
async (num: number, buildxVersion: string, inputs: Map<string, string>, expected: Array<string>, envs: Map<string, string> | undefined) => {
@ -903,6 +988,7 @@ ANOTHER_SECRET=ANOTHER_SECRET_ENV`]
vi.spyOn(Buildx.prototype, 'version').mockImplementation(async (): Promise<string> => {
return buildxVersion;
});
const context = await loadContextModule();
const inp = await context.getInputs();
const res = await context.getArgs(inp, toolkit);
expect(res).toEqual(expected);
@ -918,3 +1004,8 @@ function getInputName(name: string): string {
function setInput(name: string, value: string): void {
process.env[getInputName(name)] = value;
}
async function loadContextModule(): Promise<typeof import('../src/context.js')> {
vi.resetModules();
return await import('../src/context.js');
}

45
dist/index.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

View file

@ -24,7 +24,7 @@
"packageManager": "yarn@4.9.2",
"dependencies": {
"@actions/core": "^3.0.0",
"@docker/actions-toolkit": "0.79.0",
"@docker/actions-toolkit": "0.86.0",
"handlebars": "^4.7.9"
},
"devDependencies": {

View file

@ -2,11 +2,17 @@ import * as core from '@actions/core';
import * as handlebars from 'handlebars';
import {Build} from '@docker/actions-toolkit/lib/buildx/build.js';
import {Context} from '@docker/actions-toolkit/lib/context.js';
import {GitHub} from '@docker/actions-toolkit/lib/github/github.js';
import {Toolkit} from '@docker/actions-toolkit/lib/toolkit.js';
import {Util} from '@docker/actions-toolkit/lib/util.js';
let defaultContextPromise: Promise<string> | undefined;
async function getDefaultContext(): Promise<string> {
defaultContextPromise ??= new Build().gitContext();
return await defaultContextPromise;
}
export interface Inputs {
'add-hosts': string[];
allow: string[];
@ -44,6 +50,7 @@ export interface Inputs {
}
export async function getInputs(): Promise<Inputs> {
const defaultContext = await getDefaultContext();
return {
'add-hosts': Util.getInputList('add-hosts'),
allow: Util.getInputList('allow'),
@ -56,7 +63,7 @@ export async function getInputs(): Promise<Inputs> {
'cache-to': Util.getInputList('cache-to', {ignoreComma: true}),
call: core.getInput('call'),
'cgroup-parent': core.getInput('cgroup-parent'),
context: core.getInput('context') || Context.gitContext(),
context: handlebars.compile(core.getInput('context'))({defaultContext}) || defaultContext,
file: core.getInput('file'),
labels: Util.getInputList('labels', {ignoreComma: true}),
load: core.getBooleanInput('load'),
@ -82,18 +89,17 @@ export async function getInputs(): Promise<Inputs> {
}
export async function getArgs(inputs: Inputs, toolkit: Toolkit): Promise<Array<string>> {
const context = handlebars.compile(inputs.context)({
defaultContext: Context.gitContext()
});
// prettier-ignore
return [
...await getBuildArgs(inputs, context, toolkit),
...await getBuildArgs(inputs, inputs.context, toolkit),
...await getCommonArgs(inputs, toolkit),
context
inputs.context
];
}
async function getBuildArgs(inputs: Inputs, context: string, toolkit: Toolkit): Promise<Array<string>> {
const defaultContext = await getDefaultContext();
const args: Array<string> = ['build'];
await Util.asyncForEach(inputs['add-hosts'], async addHost => {
args.push('--add-host', addHost);
@ -116,7 +122,7 @@ async function getBuildArgs(inputs: Inputs, context: string, toolkit: Toolkit):
args.push(
'--build-context',
handlebars.compile(buildContext)({
defaultContext: Context.gitContext()
defaultContext: defaultContext
})
);
});
@ -182,7 +188,7 @@ async function getBuildArgs(inputs: Inputs, context: string, toolkit: Toolkit):
core.warning(err.message);
}
});
if (inputs['github-token'] && !Build.hasGitAuthTokenSecret(inputs.secrets) && context.startsWith(Context.gitContext())) {
if (inputs['github-token'] && !Build.hasGitAuthTokenSecret(inputs.secrets) && context.startsWith(defaultContext)) {
args.push('--secret', Build.resolveSecretString(`GIT_AUTH_TOKEN.${new URL(GitHub.serverURL).host.trimEnd()}=${inputs['github-token']}`));
}
if (inputs['shm-size']) {

1
test/secret.txt Normal file
View file

@ -0,0 +1 @@
foo

View file

@ -12,9 +12,9 @@ __metadata:
languageName: node
linkType: hard
"@actions/artifact@npm:^6.2.0":
version: 6.2.0
resolution: "@actions/artifact@npm:6.2.0"
"@actions/artifact@npm:^6.2.1":
version: 6.2.1
resolution: "@actions/artifact@npm:6.2.1"
dependencies:
"@actions/core": "npm:^3.0.0"
"@actions/github": "npm:^9.0.0"
@ -30,7 +30,7 @@ __metadata:
archiver: "npm:^7.0.1"
jwt-decode: "npm:^4.0.0"
unzip-stream: "npm:^0.3.1"
checksum: 10/fa931b1222c0e08bca85d3cb18c2cd5ae912cce3f09ab3acd4ec3486e864337d65177089a14aef124d9696b9dd5309b273a9251e230172c79c2444af2c43443e
checksum: 10/1fad9b079ee2ab07f964b93bf7b4fc594d115199219baed74ac3bf2a8675e0b7ea57252eccbcdaaaa8fc8375742d23585cbd054f3b2d029c091817e0f257ce93
languageName: node
linkType: hard
@ -367,11 +367,11 @@ __metadata:
languageName: node
linkType: hard
"@docker/actions-toolkit@npm:0.79.0":
version: 0.79.0
resolution: "@docker/actions-toolkit@npm:0.79.0"
"@docker/actions-toolkit@npm:0.86.0":
version: 0.86.0
resolution: "@docker/actions-toolkit@npm:0.86.0"
dependencies:
"@actions/artifact": "npm:^6.2.0"
"@actions/artifact": "npm:^6.2.1"
"@actions/cache": "npm:^6.0.0"
"@actions/core": "npm:^3.0.0"
"@actions/exec": "npm:^3.0.0"
@ -380,11 +380,11 @@ __metadata:
"@actions/io": "npm:^3.0.2"
"@actions/tool-cache": "npm:^4.0.0"
"@sigstore/bundle": "npm:^4.0.0"
"@sigstore/sign": "npm:^4.1.0"
"@sigstore/tuf": "npm:^4.0.1"
"@sigstore/sign": "npm:^4.1.1"
"@sigstore/tuf": "npm:^4.0.2"
"@sigstore/verify": "npm:^3.1.0"
async-retry: "npm:^1.3.3"
csv-parse: "npm:^6.1.0"
csv-parse: "npm:^6.2.1"
gunzip-maybe: "npm:^1.4.2"
handlebars: "npm:^4.7.8"
he: "npm:^1.2.0"
@ -393,7 +393,7 @@ __metadata:
semver: "npm:^7.7.4"
tar-stream: "npm:^3.1.7"
tmp: "npm:^0.2.5"
checksum: 10/d64849ba49b2b59e2e93237a70be03fd7c43b1f7f01bac3f7557616ba5f59be785cb12a273bbb6a71c1e0d959f1bc6c673111b587c57bd2d6da105dcc500921a
checksum: 10/89d65c4a48de7474d7356520b452a1f9ff1931e6bcb2b810a2e14b4b6efcdc1fb7d0d22771e94289b58ee57040a77792306a13dc898b2aa7e083124bee102f18
languageName: node
linkType: hard
@ -676,6 +676,13 @@ __metadata:
languageName: node
linkType: hard
"@gar/promise-retry@npm:^1.0.2":
version: 1.0.3
resolution: "@gar/promise-retry@npm:1.0.3"
checksum: 10/0d13ea3bb1025755e055648f6e290d2a7e0c87affaf552218f09f66b3fcd9ea9d5c9cc5fe2aa6e285e1530437768e40f9448fe9a86f4f3417b216dcf488d3d1a
languageName: node
linkType: hard
"@humanfs/core@npm:^0.19.1":
version: 0.19.1
resolution: "@humanfs/core@npm:0.19.1"
@ -796,6 +803,13 @@ __metadata:
languageName: node
linkType: hard
"@npmcli/redact@npm:^4.0.0":
version: 4.0.0
resolution: "@npmcli/redact@npm:4.0.0"
checksum: 10/5d52df2b5267f4369c97a2b2f7c427e3d7aa4b6a83e7a1b522e196f6e9d50024c620bd0cb2052067c74d1aaa0c330d9bc04e1d335bfb46180e705bb33423e74c
languageName: node
linkType: hard
"@octokit/auth-token@npm:^6.0.0":
version: 6.0.0
resolution: "@octokit/auth-token@npm:6.0.0"
@ -1194,6 +1208,13 @@ __metadata:
languageName: node
linkType: hard
"@sigstore/core@npm:^3.2.0":
version: 3.2.0
resolution: "@sigstore/core@npm:3.2.0"
checksum: 10/2425d20297d57a5f5a62f0e6c2f4280818015ea00b3defebdac63f13c7d01db988602c316c16e374ba091c3649dd9a22ae8c9ba3ac165f736b0503164c5da5f5
languageName: node
linkType: hard
"@sigstore/protobuf-specs@npm:^0.5.0":
version: 0.5.0
resolution: "@sigstore/protobuf-specs@npm:0.5.0"
@ -1201,27 +1222,27 @@ __metadata:
languageName: node
linkType: hard
"@sigstore/sign@npm:^4.1.0":
version: 4.1.0
resolution: "@sigstore/sign@npm:4.1.0"
"@sigstore/sign@npm:^4.1.1":
version: 4.1.1
resolution: "@sigstore/sign@npm:4.1.1"
dependencies:
"@gar/promise-retry": "npm:^1.0.2"
"@sigstore/bundle": "npm:^4.0.0"
"@sigstore/core": "npm:^3.1.0"
"@sigstore/core": "npm:^3.2.0"
"@sigstore/protobuf-specs": "npm:^0.5.0"
make-fetch-happen: "npm:^15.0.3"
make-fetch-happen: "npm:^15.0.4"
proc-log: "npm:^6.1.0"
promise-retry: "npm:^2.0.1"
checksum: 10/e5441d4cacf0f203f329e96bb7a3ca77682cfdf90d6448ad368344056fd8d55c01742e2b636545d55364490a87988f767f2b23168b2d9cc52ef3d8fe9e9496aa
checksum: 10/c9424813ed83ae26111dd3a190dbfd776901cfc245ebb9aa68e133a7ffcbf8fc053f01d999a451e44805a291921ba4d2dfe80e3fd41b20cd5becd26aae5f5e7c
languageName: node
linkType: hard
"@sigstore/tuf@npm:^4.0.1":
version: 4.0.1
resolution: "@sigstore/tuf@npm:4.0.1"
"@sigstore/tuf@npm:^4.0.2":
version: 4.0.2
resolution: "@sigstore/tuf@npm:4.0.2"
dependencies:
"@sigstore/protobuf-specs": "npm:^0.5.0"
tuf-js: "npm:^4.1.0"
checksum: 10/1a9725aa95eba55badf24442fe8a71c6d68f8b7d17a6b2a5e4b5590117f0181881b3485cfa57ea375b7c3a38421dbffdfcbe86e6623d903e17e3a8359837e268
checksum: 10/14882b8e71be4185ec417744b97a47392a50da00aafd4207a46bb74b40aa019ebf22d928052fd2d31a8da0da1efe7ebebac5a70898b31a74239a1ada997be754
languageName: node
linkType: hard
@ -2039,10 +2060,10 @@ __metadata:
languageName: node
linkType: hard
"csv-parse@npm:^6.1.0":
version: 6.1.0
resolution: "csv-parse@npm:6.1.0"
checksum: 10/607d92611435fdfb7631242644a2582bfb218fad8c6c6d6416db31647c2e63a3110f16c9837de6baaa3edf318212765cfc6e72d672d99690fd7f565d6c93d6f4
"csv-parse@npm:^6.2.1":
version: 6.2.1
resolution: "csv-parse@npm:6.2.1"
checksum: 10/7fbde1225c6df6aaea01a202934e1f15ce16ed55e544ead0d066b0c4dc9ae1a2fc881b412889cbf115cd74cbf14ea17388b394e8a31e05cb412dd7dc6114bebd
languageName: node
linkType: hard
@ -2094,7 +2115,7 @@ __metadata:
resolution: "docker-build-push@workspace:."
dependencies:
"@actions/core": "npm:^3.0.0"
"@docker/actions-toolkit": "npm:0.79.0"
"@docker/actions-toolkit": "npm:0.86.0"
"@eslint/js": "npm:^9.39.3"
"@types/node": "npm:^24.11.0"
"@typescript-eslint/eslint-plugin": "npm:^8.56.1"
@ -3217,7 +3238,7 @@ __metadata:
languageName: node
linkType: hard
"make-fetch-happen@npm:^15.0.1, make-fetch-happen@npm:^15.0.3":
"make-fetch-happen@npm:^15.0.1":
version: 15.0.4
resolution: "make-fetch-happen@npm:15.0.4"
dependencies:
@ -3236,6 +3257,26 @@ __metadata:
languageName: node
linkType: hard
"make-fetch-happen@npm:^15.0.4":
version: 15.0.5
resolution: "make-fetch-happen@npm:15.0.5"
dependencies:
"@gar/promise-retry": "npm:^1.0.0"
"@npmcli/agent": "npm:^4.0.0"
"@npmcli/redact": "npm:^4.0.0"
cacache: "npm:^20.0.1"
http-cache-semantics: "npm:^4.1.1"
minipass: "npm:^7.0.2"
minipass-fetch: "npm:^5.0.0"
minipass-flush: "npm:^1.0.5"
minipass-pipeline: "npm:^1.2.4"
negotiator: "npm:^1.0.0"
proc-log: "npm:^6.0.0"
ssri: "npm:^13.0.0"
checksum: 10/d2649effb06c00cb2b266057cb1c8c1e99cfc8d1378e7d9c26cc8f00be41bc63d59b77a5576ed28f8105acc57fb16220b64217f8d3a6a066a594c004aa163afa
languageName: node
linkType: hard
"minimatch@npm:^10.1.1, minimatch@npm:^10.2.2":
version: 10.2.4
resolution: "minimatch@npm:10.2.4"