Skip to content

Commit

Permalink
bake: additional opts when parsing definition
Browse files Browse the repository at this point in the history
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
  • Loading branch information
crazy-max committed Mar 27, 2024
1 parent de2888a commit 4f6c1c7
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 23 deletions.
13 changes: 8 additions & 5 deletions __tests__/buildx/bake.test.itg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,20 @@ beforeEach(() => {
jest.clearAllMocks();
});

maybe('parseDefinitions', () => {
maybe('getDefinition', () => {
// prettier-ignore
test.each([
[
['https://github.com/docker/buildx.git#v0.10.4'],
'https://github.com/docker/buildx.git#v0.10.4',
['binaries-cross'],
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 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);
});
});
15 changes: 12 additions & 3 deletions __tests__/buildx/bake.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import * as fs from 'fs';
import * as path from 'path';

import {Bake} from '../../src/buildx/bake';

import {ExecOptions} from '@actions/exec';
import {BakeDefinition} from '../../src/types/bake';

const fixturesDir = path.join(__dirname, '..', 'fixtures');
Expand All @@ -27,31 +29,38 @@ beforeEach(() => {
jest.clearAllMocks();
});

describe('parseDefinitions', () => {
describe('getDefinition', () => {
// prettier-ignore
test.each([
[
[path.join(fixturesDir, 'bake-01.hcl')],
['validate'],
[],
{silent: true},
path.join(fixturesDir, 'bake-01-validate.json')
],
[
[path.join(fixturesDir, 'bake-02.hcl')],
['build'],
[],
undefined,
path.join(fixturesDir, 'bake-02-build.json')
],
[
[path.join(fixturesDir, 'bake-01.hcl')],
['image'],
['*.output=type=docker', '*.platform=linux/amd64'],
undefined,
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 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);
});
});

Expand Down
56 changes: 41 additions & 15 deletions src/buildx/bake.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,43 @@ import {Exec} from '../exec';
import {Inputs} from './inputs';
import {Util} from '../util';

import {ExecOptions} from '@actions/exec';
import {BakeDefinition} from '../types/bake';

export interface BakeOpts {
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 {
private readonly buildx: Buildx;

constructor(opts?: BakeOpts) {
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) {
execOptions = execOptions || {ignoreReturnCode: true};
execOptions.ignoreReturnCode = true;

const args = ['bake'];

let remoteDef;
let remoteDef: string | undefined;
const files: Array<string> = [];
const sources = [...(cmdOpts.files || []), cmdOpts.source];
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) {
continue;
}
Expand All @@ -47,7 +64,7 @@ export class Bake {
continue;
}
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;
}
Expand All @@ -58,31 +75,40 @@ export class Bake {
for (const file of files) {
args.push('--file', file);
}
if (overrides) {
for (const override of overrides) {
if (cmdOpts.overrides) {
for (const override of cmdOpts.overrides) {
args.push('--set', override);
}
}
if (load) {
if (cmdOpts.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');
}
if (cmdOpts.sbom) {
args.push('--sbom', cmdOpts.sbom);
}

const printCmd = await this.buildx.getCommand([...args, '--print', ...(targets || [])]);
return await Exec.getExecOutput(printCmd.command, printCmd.args, {
cwd: workdir,
ignoreReturnCode: true,
silent: true
}).then(res => {
const printCmd = await this.buildx.getCommand([...args, '--print', ...(cmdOpts.targets || [])]);
return await Exec.getExecOutput(printCmd.command, printCmd.args, execOptions).then(res => {
if (res.stderr.length > 0 && res.exitCode != 0) {
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 {
return Inputs.hasExporterType('local', Bake.exporters(def));
}
Expand Down

0 comments on commit 4f6c1c7

Please sign in to comment.