import * as core from "@actions/core"; import * as exec from "@actions/exec"; import { CommandResult } from "./types"; interface Buildah { buildUsingDocker(image: string, context: string, dockerFiles: string[], buildArgs: string[]): Promise; from(baseImage: string): Promise; copy(container: string, contentToCopy: string[]): Promise; config(container: string, setting: {}): Promise; commit(container: string, newImageName: string, flags?: string[]): Promise; } export interface BuildahConfigSettings { entrypoint?: string[]; envs?: string[]; port?: string; workingdir?: string; } export class BuildahCli implements Buildah { private executable: string; constructor(executable: string) { this.executable = executable; } async buildUsingDocker(image: string, context: string, dockerFiles: string[], buildArgs: string[]): Promise { const args: string[] = ['bud']; dockerFiles.forEach(file => { args.push('-f'); args.push(file); }); buildArgs.forEach((buildArg) => { args.push('--build-arg'); args.push(buildArg); }) args.push('-t'); args.push(image); args.push(context); return await this.execute(args); } async from(baseImage: string): Promise { return await this.execute(['from', baseImage]); } async copy(container: string, contentToCopy: string[], path?: string): Promise { core.debug('copy'); core.debug(container); let result: CommandResult; for (const content of contentToCopy) { const args: string[] = ["copy", container, content]; if (path) { args.push(path); } result = await this.execute(args); if (result.succeeded === false) { return result; } } return result; } async config(container: string, settings: BuildahConfigSettings): Promise { core.debug('config'); core.debug(container); const args: string[] = ['config']; if (settings.entrypoint) { args.push('--entrypoint'); args.push(this.convertArrayToStringArg(settings.entrypoint)); } if (settings.port) { args.push('--port'); args.push(settings.port); } if (settings.envs) { settings.envs.forEach((env) => { args.push('--env'); args.push(env); }); } args.push(container); return await this.execute(args); } async commit(container: string, newImageName: string, flags: string[] = []): Promise { core.debug('commit'); core.debug(container); core.debug(newImageName); const args: string[] = ["commit", ...flags, container, newImageName]; return await this.execute(args); } private convertArrayToStringArg(args: string[]): string { let arrayAsString = '['; args.forEach(arg => { arrayAsString += `"${arg}",`; }); return `${arrayAsString.slice(0, -1)}]`; } private async execute(args: string[]): Promise { if (!this.executable) { return Promise.reject(new Error('Unable to call buildah executable')); } let output = ''; let error = ''; const options: exec.ExecOptions = {}; options.listeners = { stdout: (data: Buffer): void => { output += data.toString(); }, stderr: (data: Buffer): void => { error += data.toString(); } }; const exitCode = await exec.exec(this.executable, args, options); if (exitCode === 1) { return Promise.resolve({ succeeded: false, error }); } return Promise.resolve({ succeeded: true, output }); } }