mirror of
https://github.com/docker/build-push-action.git
synced 2026-04-05 21:09:26 +00:00
refactor: use new gitContext for build context resolution
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
parent
6cc04c1209
commit
3b7fd34174
3 changed files with 159 additions and 11 deletions
51
.github/workflows/ci.yml
vendored
51
.github/workflows/ci.yml
vendored
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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(() => {
|
||||
|
|
@ -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');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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']) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue