From e51051ad0baf1cdf23788f7f0980f675806b580e Mon Sep 17 00:00:00 2001 From: CrazyMax <1951866+crazy-max@users.noreply.github.com> Date: Thu, 2 May 2024 13:49:01 +0200 Subject: [PATCH] export build record and upload artifact Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> --- src/main.ts | 56 ++++++++++++++++++++++++++++++++++++++++++++- src/state-helper.ts | 5 ++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/main.ts b/src/main.ts index 55fb6b2..4aed14f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,11 +4,14 @@ import * as stateHelper from './state-helper'; 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 {ConfigFile} from '@docker/actions-toolkit/lib/types/docker/docker'; @@ -17,6 +20,7 @@ import * as context from './context'; actionsToolkit.run( // main async () => { + const startedTime = new Date(); const inputs: context.Inputs = await context.getInputs(); core.debug(`inputs: ${JSON.stringify(inputs)}`); @@ -87,11 +91,12 @@ actionsToolkit.run( core.debug(`buildCmd.command: ${buildCmd.command}`); core.debug(`buildCmd.args: ${JSON.stringify(buildCmd.args)}`); + let err: Error | undefined; await Exec.getExecOutput(buildCmd.command, buildCmd.args, { ignoreReturnCode: true }).then(res => { if (res.stderr.length > 0 && res.exitCode != 0) { - throw new Error(`buildx failed with: ${res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error'}`); + err = Error(`buildx failed with: ${res.stderr.match(/(.*)\s*$/)?.[0]?.trim() ?? 'unknown error'}`); } }); @@ -118,9 +123,39 @@ actionsToolkit.run( core.setOutput('metadata', metadatadt); }); } + await core.group(`Reference`, async () => { + const ref = await buildRef(toolkit, startedTime, inputs.builder); + if (ref) { + core.info(ref); + stateHelper.setBuildRef(ref); + } else { + core.warning('No build ref found'); + } + }); + if (err) { + throw err; + } }, // post async () => { + if (stateHelper.buildRef.length > 0) { + await core.group(`Exporting build record`, async () => { + try { + const buildxHistory = new BuildxHistory(); + const exportRes = await buildxHistory.export({ + refs: [stateHelper.buildRef] + }); + core.info(`Build record 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}); @@ -128,3 +163,22 @@ actionsToolkit.run( } } ); + +async function buildRef(toolkit: Toolkit, since: Date, builder?: string): Promise { + // get ref from metadata file + const ref = toolkit.buildxBuild.resolveRef(); + if (ref) { + return ref; + } + // 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 refs = Buildx.refs({ + dir: Buildx.refsDir, + builderName: builder, + since: since + }); + return Object.keys(refs).length > 0 ? Object.keys(refs)[0] : ''; +} diff --git a/src/state-helper.ts b/src/state-helper.ts index 01c11be..e5f5e8f 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 buildRef = process.env['STATE_buildRef'] || ''; export function setTmpDir(tmpDir: string) { core.saveState('tmpDir', tmpDir); } + +export function setBuildRef(buildRef: string) { + core.saveState('buildRef', buildRef); +}