From 341bae465ffe2a483fb955b05e82425a422a7fd4 Mon Sep 17 00:00:00 2001 From: CrazyMax <1951866+crazy-max@users.noreply.github.com> Date: Tue, 26 Mar 2024 09:46:22 +0100 Subject: [PATCH 1/2] bake: additional opts when parsing definition Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> --- __tests__/buildx/bake.test.itg.ts | 13 ++++--- __tests__/buildx/bake.test.ts | 15 +++++++-- src/buildx/bake.ts | 56 ++++++++++++++++++++++--------- 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/__tests__/buildx/bake.test.itg.ts b/__tests__/buildx/bake.test.itg.ts index 78a0863c..b3ce79a4 100644 --- a/__tests__/buildx/bake.test.itg.ts +++ b/__tests__/buildx/bake.test.itg.ts @@ -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 = 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); }); }); diff --git a/__tests__/buildx/bake.test.ts b/__tests__/buildx/bake.test.ts index 5fd6cebf..c4214126 100644 --- a/__tests__/buildx/bake.test.ts +++ b/__tests__/buildx/bake.test.ts @@ -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'); @@ -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 = 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); }); }); diff --git a/src/buildx/bake.ts b/src/buildx/bake.ts index 4c47dae8..93f158f1 100644 --- a/src/buildx/bake.ts +++ b/src/buildx/bake.ts @@ -19,12 +19,25 @@ 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; + load?: boolean; + noCache?: boolean; + overrides?: Array; + provenance?: string; + push?: boolean; + sbom?: string; + source?: string; + targets?: Array; +} + export class Bake { private readonly buildx: Buildx; @@ -32,13 +45,17 @@ export class Bake { this.buildx = opts?.buildx || new Buildx(); } - public async parseDefinitions(sources: Array, targets?: Array, overrides?: Array, load?: boolean, push?: boolean, workdir?: string): Promise { + public async getDefinition(cmdOpts: BakeCmdOpts, execOptions?: ExecOptions): Promise { + execOptions = execOptions || {ignoreReturnCode: true}; + execOptions.ignoreReturnCode = true; + const args = ['bake']; - let remoteDef; + let remoteDef: string | undefined; const files: Array = []; + 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; } @@ -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; } @@ -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 JSON.parse(res.stdout.trim()); + return Bake.parseDefinition(res.stdout.trim()); }); } + public static parseDefinition(dt: string): BakeDefinition { + return JSON.parse(dt); + } + public static hasLocalExporter(def: BakeDefinition): boolean { return Inputs.hasExporterType('local', Bake.exporters(def)); } From 416c2914dfcf3b9e03384a105ef7843df671e40e Mon Sep 17 00:00:00 2001 From: CrazyMax <1951866+crazy-max@users.noreply.github.com> Date: Tue, 26 Mar 2024 10:06:31 +0100 Subject: [PATCH 2/2] bake: add shm-size and ulimits to target struct Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> --- src/types/bake.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/types/bake.ts b/src/types/bake.ts index 089efdef..e257dc5b 100644 --- a/src/types/bake.ts +++ b/src/types/bake.ts @@ -39,7 +39,9 @@ export interface Target { platforms?: Array; pull?: boolean; secret?: Array; + 'shm-size'?: string; ssh?: Array; tags?: Array; target?: string; + ulimits?: Array; }