bake: additional opts when parsing definition
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
@@ -29,17 +29,20 @@ beforeEach(() => {
|
|||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
maybe('parseDefinitions', () => {
|
maybe('getDefinition', () => {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
test.each([
|
test.each([
|
||||||
[
|
[
|
||||||
['https://github.com/docker/buildx.git#v0.10.4'],
|
'https://github.com/docker/buildx.git#v0.10.4',
|
||||||
['binaries-cross'],
|
['binaries-cross'],
|
||||||
path.join(fixturesDir, 'bake-buildx-0.10.4-binaries-cross.json')
|
path.join(fixturesDir, 'bake-buildx-0.10.4-binaries-cross.json')
|
||||||
]
|
],
|
||||||
])('given %p', async (sources: string[], targets: string[], out: string) => {
|
])('given %p', async (source: string, targets: string[], out: string) => {
|
||||||
const bake = new Bake();
|
const bake = new Bake();
|
||||||
const expectedDef = <BakeDefinition>JSON.parse(fs.readFileSync(out, {encoding: 'utf-8'}).trim())
|
const expectedDef = <BakeDefinition>JSON.parse(fs.readFileSync(out, {encoding: 'utf-8'}).trim())
|
||||||
expect(await bake.parseDefinitions(sources, targets)).toEqual(expectedDef);
|
expect(await bake.getDefinition({
|
||||||
|
source: source,
|
||||||
|
targets: targets
|
||||||
|
})).toEqual(expectedDef);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ import * as fs from 'fs';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
import {Bake} from '../../src/buildx/bake';
|
import {Bake} from '../../src/buildx/bake';
|
||||||
|
|
||||||
|
import {ExecOptions} from '@actions/exec';
|
||||||
import {BakeDefinition} from '../../src/types/bake';
|
import {BakeDefinition} from '../../src/types/bake';
|
||||||
|
|
||||||
const fixturesDir = path.join(__dirname, '..', 'fixtures');
|
const fixturesDir = path.join(__dirname, '..', 'fixtures');
|
||||||
@@ -27,31 +29,38 @@ beforeEach(() => {
|
|||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('parseDefinitions', () => {
|
describe('getDefinition', () => {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
test.each([
|
test.each([
|
||||||
[
|
[
|
||||||
[path.join(fixturesDir, 'bake-01.hcl')],
|
[path.join(fixturesDir, 'bake-01.hcl')],
|
||||||
['validate'],
|
['validate'],
|
||||||
[],
|
[],
|
||||||
|
{silent: true},
|
||||||
path.join(fixturesDir, 'bake-01-validate.json')
|
path.join(fixturesDir, 'bake-01-validate.json')
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
[path.join(fixturesDir, 'bake-02.hcl')],
|
[path.join(fixturesDir, 'bake-02.hcl')],
|
||||||
['build'],
|
['build'],
|
||||||
[],
|
[],
|
||||||
|
undefined,
|
||||||
path.join(fixturesDir, 'bake-02-build.json')
|
path.join(fixturesDir, 'bake-02-build.json')
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
[path.join(fixturesDir, 'bake-01.hcl')],
|
[path.join(fixturesDir, 'bake-01.hcl')],
|
||||||
['image'],
|
['image'],
|
||||||
['*.output=type=docker', '*.platform=linux/amd64'],
|
['*.output=type=docker', '*.platform=linux/amd64'],
|
||||||
|
undefined,
|
||||||
path.join(fixturesDir, 'bake-01-overrides.json')
|
path.join(fixturesDir, 'bake-01-overrides.json')
|
||||||
]
|
]
|
||||||
])('given %p', async (sources: string[], targets: string[], overrides: string[], out: string) => {
|
])('given %p', async (files: string[], targets: string[], overrides: string[], execOptions: ExecOptions | undefined, out: string) => {
|
||||||
const bake = new Bake();
|
const bake = new Bake();
|
||||||
const expectedDef = <BakeDefinition>JSON.parse(fs.readFileSync(out, {encoding: 'utf-8'}).trim())
|
const expectedDef = <BakeDefinition>JSON.parse(fs.readFileSync(out, {encoding: 'utf-8'}).trim())
|
||||||
expect(await bake.parseDefinitions(sources, targets, overrides)).toEqual(expectedDef);
|
expect(await bake.getDefinition({
|
||||||
|
files: files,
|
||||||
|
targets: targets,
|
||||||
|
overrides: overrides
|
||||||
|
}, execOptions)).toEqual(expectedDef);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -19,12 +19,25 @@ import {Exec} from '../exec';
|
|||||||
import {Inputs} from './inputs';
|
import {Inputs} from './inputs';
|
||||||
import {Util} from '../util';
|
import {Util} from '../util';
|
||||||
|
|
||||||
|
import {ExecOptions} from '@actions/exec';
|
||||||
import {BakeDefinition} from '../types/bake';
|
import {BakeDefinition} from '../types/bake';
|
||||||
|
|
||||||
export interface BakeOpts {
|
export interface BakeOpts {
|
||||||
buildx?: Buildx;
|
buildx?: Buildx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface BakeCmdOpts {
|
||||||
|
files?: Array<string>;
|
||||||
|
load?: boolean;
|
||||||
|
noCache?: boolean;
|
||||||
|
overrides?: Array<string>;
|
||||||
|
provenance?: string;
|
||||||
|
push?: boolean;
|
||||||
|
sbom?: string;
|
||||||
|
source?: string;
|
||||||
|
targets?: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
export class Bake {
|
export class Bake {
|
||||||
private readonly buildx: Buildx;
|
private readonly buildx: Buildx;
|
||||||
|
|
||||||
@@ -32,13 +45,17 @@ export class Bake {
|
|||||||
this.buildx = opts?.buildx || new Buildx();
|
this.buildx = opts?.buildx || new Buildx();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async parseDefinitions(sources: Array<string>, targets?: Array<string>, overrides?: Array<string>, load?: boolean, push?: boolean, workdir?: string): Promise<BakeDefinition> {
|
public async getDefinition(cmdOpts: BakeCmdOpts, execOptions?: ExecOptions): Promise<BakeDefinition> {
|
||||||
|
execOptions = execOptions || {ignoreReturnCode: true};
|
||||||
|
execOptions.ignoreReturnCode = true;
|
||||||
|
|
||||||
const args = ['bake'];
|
const args = ['bake'];
|
||||||
|
|
||||||
let remoteDef;
|
let remoteDef: string | undefined;
|
||||||
const files: Array<string> = [];
|
const files: Array<string> = [];
|
||||||
|
const sources = [...(cmdOpts.files || []), cmdOpts.source];
|
||||||
if (sources) {
|
if (sources) {
|
||||||
for (const source of sources.map(v => v.trim())) {
|
for (const source of sources.map(v => (v ? v.trim() : ''))) {
|
||||||
if (source.length == 0) {
|
if (source.length == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -47,7 +64,7 @@ export class Bake {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (remoteDef) {
|
if (remoteDef) {
|
||||||
throw new Error(`Only one remote bake definition is allowed`);
|
throw new Error(`Only one remote bake definition can be defined`);
|
||||||
}
|
}
|
||||||
remoteDef = source;
|
remoteDef = source;
|
||||||
}
|
}
|
||||||
@@ -58,31 +75,40 @@ export class Bake {
|
|||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
args.push('--file', file);
|
args.push('--file', file);
|
||||||
}
|
}
|
||||||
if (overrides) {
|
if (cmdOpts.overrides) {
|
||||||
for (const override of overrides) {
|
for (const override of cmdOpts.overrides) {
|
||||||
args.push('--set', override);
|
args.push('--set', override);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (load) {
|
if (cmdOpts.load) {
|
||||||
args.push('--load');
|
args.push('--load');
|
||||||
}
|
}
|
||||||
if (push) {
|
if (cmdOpts.noCache) {
|
||||||
|
args.push('--no-cache');
|
||||||
|
}
|
||||||
|
if (cmdOpts.provenance) {
|
||||||
|
args.push('--provenance', cmdOpts.provenance);
|
||||||
|
}
|
||||||
|
if (cmdOpts.push) {
|
||||||
args.push('--push');
|
args.push('--push');
|
||||||
}
|
}
|
||||||
|
if (cmdOpts.sbom) {
|
||||||
|
args.push('--sbom', cmdOpts.sbom);
|
||||||
|
}
|
||||||
|
|
||||||
const printCmd = await this.buildx.getCommand([...args, '--print', ...(targets || [])]);
|
const printCmd = await this.buildx.getCommand([...args, '--print', ...(cmdOpts.targets || [])]);
|
||||||
return await Exec.getExecOutput(printCmd.command, printCmd.args, {
|
return await Exec.getExecOutput(printCmd.command, printCmd.args, execOptions).then(res => {
|
||||||
cwd: workdir,
|
|
||||||
ignoreReturnCode: true,
|
|
||||||
silent: true
|
|
||||||
}).then(res => {
|
|
||||||
if (res.stderr.length > 0 && res.exitCode != 0) {
|
if (res.stderr.length > 0 && res.exitCode != 0) {
|
||||||
throw new Error(`cannot parse bake definitions: ${res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error'}`);
|
throw new Error(`cannot parse bake definitions: ${res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error'}`);
|
||||||
}
|
}
|
||||||
return <BakeDefinition>JSON.parse(res.stdout.trim());
|
return Bake.parseDefinition(res.stdout.trim());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static parseDefinition(dt: string): BakeDefinition {
|
||||||
|
return <BakeDefinition>JSON.parse(dt);
|
||||||
|
}
|
||||||
|
|
||||||
public static hasLocalExporter(def: BakeDefinition): boolean {
|
public static hasLocalExporter(def: BakeDefinition): boolean {
|
||||||
return Inputs.hasExporterType('local', Bake.exporters(def));
|
return Inputs.hasExporterType('local', Bake.exporters(def));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user