import * as artifactHost from '@actions/artifact'; import { ArtifactClient, DownloadResponse, UploadResponse } from '@actions/artifact'; import * as core from '@actions/core'; import * as exec from '@actions/exec'; import { ExecOptions } from '@actions/exec'; import * as github from '@actions/github'; import { readdirSync } from 'fs'; const shell = async (commandLine: string, args?: Array, options?: ExecOptions): Promise => { const code: number = await exec.exec(commandLine, args, options); if (code !== 0) throw new Error(`Stage: A ${commandLine} command errored with code ${code}`); }; (async () => { const output = () => { console.log('Stage: Setting output', { 'finished': input.finished, 'package': input.package, 'use-registry': input.useRegistry, 'image-tag': input.imageTag }); core.setOutput('finished', input.finished); core.setOutput('package', input.package); core.setOutput('use-registry', input.useRegistry); core.setOutput('image-tag', input.imageTag); }; const artifact: ArtifactClient = artifactHost.create(); const input = { finished: core.getInput('finished') === 'true', progressName: core.getInput('progress-name'), package: core.getInput('package', { required: true }), useRegistry: core.getInput('use-registry') === 'true', registryToken: core.getInput('registry-token'), imageTag: core.getInput('image-tag'), arch: core.getInput('arch'), }; console.log('Stage: Got input', input); if (input.finished) return output(); // Taken from https://github.com/easimon/maximize-build-space/blob/master/action.yml await core.group('Stage: Free space on GitHub Runner...', async () => { await shell('sudo rm -rf /usr/share/dotnet'); await shell('sudo rm -rf /usr/local/lib/android'); await shell('sudo rm -rf /opt/ghc'); }); if (input.useRegistry) { await core.group('Stage: Logging into docker registry...', () => shell('docker', ['login', 'ghcr.io', '-u', github.context.actor, '-p', input.registryToken])); await core.group('Stage: Pulling image from registry...', () => shell('docker', ['pull', input.imageTag])); } else { await core.group('Stage: Downloading image artifact...', () => artifact.downloadArtifact('image')); await core.group('Stage: Loading image from file...', () => shell('docker load --input image')); await core.group('Stage: Removing image file...', () => shell('rm image')); } await core.group('Stage: Creating input, output and progress directory...', () => shell('mkdir input output progress')); if (input.progressName !== '') { await core.group('Stage: Downloading progress artifact...', () => artifact.downloadArtifact(input.progressName)); await core.group('Stage: Moving progress archive into input directory...', () => shell('mv progress.tar.zst input')); } const mount = (directory: string): Array => ['--mount', `type=bind,source=${process.cwd()}/${directory},target=/mnt/${directory}`]; await core.group('Stage: Running docker container...', () => shell('docker', ['run', '-e', 'TIMEOUT=300', '-e', `BUILD_ARCH=${input.arch}`, ...mount('input'), ...mount('output'), ...mount('progress'), input.imageTag])); if (readdirSync('output').length !== 0) { console.log('Stage: Successfully built package'); input.finished = true; } await core.group('Stage: Uploading progress...', () => artifact.uploadArtifact(`${github.context.job}-${input.arch}`, readdirSync('progress').map(node => `progress/${node}`), 'progress')); if (input.finished) await core.group('Stage: Uploading package...', () => artifact.uploadArtifact(input.package, readdirSync('output').map(node => `output/${node}`), 'output')); output(); })().catch(core.setFailed);