diff --git a/src/main.ts b/src/main.ts index 530bc11..f1b3ae5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,11 +3,14 @@ import * as path from 'path'; import * as core from '@actions/core'; import * as actionsToolkit from '@docker/actions-toolkit'; +import {Buildx} from '@docker/actions-toolkit/lib/buildx/buildx'; +import {History as BuildxHistory} from '@docker/actions-toolkit/lib/buildx/history'; import {Context} from '@docker/actions-toolkit/lib/context'; import {Docker} from '@docker/actions-toolkit/lib/docker/docker'; import {Exec} from '@docker/actions-toolkit/lib/exec'; import {GitHub} from '@docker/actions-toolkit/lib/github'; import {Toolkit} from '@docker/actions-toolkit/lib/toolkit'; +import {Util} from '@docker/actions-toolkit/lib/util'; import {BakeDefinition} from '@docker/actions-toolkit/lib/types/buildx/bake'; import {ConfigFile} from '@docker/actions-toolkit/lib/types/docker/docker'; @@ -18,7 +21,11 @@ import * as stateHelper from './state-helper'; actionsToolkit.run( // main async () => { + const startedTime = new Date(); + const inputs: context.Inputs = await context.getInputs(); + core.debug(`inputs: ${JSON.stringify(inputs)}`); + const toolkit = new Toolkit(); const gitAuthToken = process.env.BUILDX_BAKE_GIT_AUTH_TOKEN ?? inputs['github-token']; @@ -119,13 +126,14 @@ actionsToolkit.run( }); }); + let err: Error | undefined; await Exec.getExecOutput(buildCmd.command, buildCmd.args, { cwd: inputs.workdir, env: buildEnv, ignoreReturnCode: true }).then(res => { if (res.stderr.length > 0 && res.exitCode != 0) { - throw new Error(`buildx bake failed with: ${res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error'}`); + err = Error(`buildx bake failed with: ${res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error'}`); } }); @@ -137,9 +145,41 @@ actionsToolkit.run( core.setOutput('metadata', metadatadt); }); } + await core.group(`Build references`, async () => { + const refs = await buildRefs(toolkit, startedTime, inputs.builder); + if (refs) { + for (const ref of refs) { + core.info(ref); + } + stateHelper.setBuildRefs(refs); + } else { + core.warning('No build refs found'); + } + }); + if (err) { + throw err; + } }, // post async () => { + if (stateHelper.buildRefs.length > 0) { + await core.group(`Generating build summary`, async () => { + try { + const buildxHistory = new BuildxHistory(); + const exportRes = await buildxHistory.export({ + refs: stateHelper.buildRefs + }); + core.info(`Build records exported to ${exportRes.dockerbuildFilename} (${Util.formatFileSize(exportRes.dockerbuildSize)})`); + await GitHub.uploadArtifact({ + filename: exportRes.dockerbuildFilename, + mimeType: 'application/gzip', + retentionDays: 90 + }); + } catch (e) { + core.warning(e.message); + } + }); + } if (stateHelper.tmpDir.length > 0) { await core.group(`Removing temp folder ${stateHelper.tmpDir}`, async () => { fs.rmSync(stateHelper.tmpDir, {recursive: true}); @@ -147,3 +187,28 @@ actionsToolkit.run( } } ); + +async function buildRefs(toolkit: Toolkit, since: Date, builder?: string): Promise> { + // get refs from metadata file + const metaRefs = toolkit.buildxBake.resolveRefs(); + if (metaRefs) { + return metaRefs; + } + // otherwise, look for the very first build ref since the build has started + if (!builder) { + const currentBuilder = await toolkit.builder.inspect(); + builder = currentBuilder.name; + } + const res = Buildx.refs({ + dir: Buildx.refsDir, + builderName: builder, + since: since + }); + const refs: Array = []; + for (const ref in res) { + if (Object.prototype.hasOwnProperty.call(res, ref)) { + refs.push(ref); + } + } + return refs; +} diff --git a/src/state-helper.ts b/src/state-helper.ts index 01c11be..cbc6d25 100644 --- a/src/state-helper.ts +++ b/src/state-helper.ts @@ -1,7 +1,12 @@ import * as core from '@actions/core'; export const tmpDir = process.env['STATE_tmpDir'] || ''; +export const buildRefs = process.env['STATE_buildRefs'] ? process.env['STATE_buildRefs'].split(',') : []; export function setTmpDir(tmpDir: string) { core.saveState('tmpDir', tmpDir); } + +export function setBuildRefs(buildRefs: Array) { + core.saveState('buildRefs', buildRefs.join(',')); +}