import * as fs from 'node:fs/promises'; import * as os from 'os'; import * as path from 'path'; import * as semver from 'semver'; import * as core from '@actions/core'; import * as tc from '@actions/tool-cache'; import { restoreCache } from './cache-restore'; import { getVersionObject } from './lib/get-version'; const IS_WINDOWS = process.platform === 'win32'; async function run() { try { core.exportVariable('FORCE_COLOR', process.env.FORCE_COLOR ?? '1'); const nodeArchToReleaseArch: Record = { x64: 'amd64', arm: 'arm64', }; const nodePlatformToReleasePlatform: Record = { darwin: 'darwin', freebsd: 'freebsd', linux: 'linux', openbsd: 'openbsd', win32: 'windows', }; const runnerPlatform = os.platform(); const pkgName = 'earth'; const releasePlatform = nodePlatformToReleasePlatform[runnerPlatform]; if (!releasePlatform) { throw new Error( `Unsupported operating system - ${pkgName} is only released for ${Object.keys( nodePlatformToReleasePlatform, ).join(', ')}`, ); } const osArch = os.arch(); const releaseArch = nodeArchToReleaseArch[osArch] || osArch; const range = core.getInput('version'); const isValidSemVer = semver.valid(range) != null; let tag_name: string; if (isValidSemVer) { core.info(`Using provided strict version ${range}`); if (range[0] === 'v') { tag_name = range; } else { tag_name = `v${range}`; } } else { // only grab the version from the api if the version provided by the user // doesn't appear to be a valid semver const prerelease = core.getInput('prerelease').toUpperCase() === 'TRUE'; core.info( `Configured range: ${range}; allow prerelease: ${String(prerelease)}`, ); const version = await getVersionObject(range, prerelease); tag_name = version.tag_name; } const destination = path.join(os.homedir(), `.${pkgName}`); core.info(`Install destination is ${destination}`); const installationDir = path.join(destination, 'bin'); const installationPath = path.join( installationDir, `${pkgName}${IS_WINDOWS ? '.exe' : ''}`, ); core.info(`Matched version: ${tag_name}`); // first see if earthbuild is in the toolcache (installed locally) const toolcacheDir = tc.find( pkgName, semver.clean(tag_name) || tag_name.substring(1), os.arch(), ); if (toolcacheDir) { core.addPath(toolcacheDir); core.info(`using earthbuild from toolcache (${toolcacheDir})`); return; } // then try to restore earthbuild from the github action cache core.addPath(installationDir); const restored = await restoreCache( installationPath, semver.clean(tag_name) || tag_name.substring(1), ); if (restored) { await fs.chmod(installationPath, 0o755); return; } // finally, dowload EarthBuild release binary await fs.rm(installationDir, { recursive: true, force: true }); core.info(`Successfully deleted pre-existing ${installationDir}`); const buildURL = `https://github.com/EarthBuild/earthbuild/releases/download/${ tag_name }/${pkgName}-${releasePlatform}-${releaseArch}${IS_WINDOWS ? '.exe' : ''}`; core.info(`downloading ${buildURL}`); const downloaded = await tc.downloadTool(buildURL, installationPath); core.debug(`successfully downloaded ${buildURL} to ${downloaded}`); await fs.chmod(installationPath, 0o755); await tc.cacheDir( path.join(destination, 'bin'), pkgName, semver.clean(tag_name) || tag_name.substring(1), os.arch(), ); } catch (error: unknown) { if (error instanceof Error) { core.setFailed(error.message); } else { core.setFailed(String(error)); } } } void run();