2021-09-14 17:23:12 +08:00
|
|
|
import { find, downloadTool, cacheDir } from "@actions/tool-cache"
|
2021-09-14 21:47:16 +08:00
|
|
|
import { addPath, group, startGroup, endGroup, info } from "@actions/core"
|
2021-09-14 17:23:38 +08:00
|
|
|
import { join } from "path"
|
2021-09-14 17:23:12 +08:00
|
|
|
import { existsSync } from "fs"
|
|
|
|
import * as hasha from "hasha"
|
2021-09-14 19:38:58 +08:00
|
|
|
import { tmpdir } from "os"
|
2021-09-14 17:23:12 +08:00
|
|
|
|
2021-09-14 17:26:33 +08:00
|
|
|
/** A type that describes a package */
|
2021-09-14 17:23:12 +08:00
|
|
|
export type PackageInfo = {
|
2021-09-14 17:27:55 +08:00
|
|
|
/** Url to download the package */
|
2021-09-14 17:23:12 +08:00
|
|
|
url: string
|
2021-09-14 17:26:33 +08:00
|
|
|
/** The top folder name once it is extracted. It can be `""` if there is no top folder */
|
2021-09-14 17:23:38 +08:00
|
|
|
extractedFolderName: string
|
2021-09-14 17:26:33 +08:00
|
|
|
/** The relative directory in which the binary is located. It can be `""` if the exe is in the top folder */
|
|
|
|
binRelativeDir: string
|
2021-09-14 17:27:55 +08:00
|
|
|
/** The function to extract the downloaded archive. It can be `undefined`, if the binary itself is downloaded directly. */
|
|
|
|
extractFunction?: {
|
2021-09-14 23:00:30 +08:00
|
|
|
(file: string, dest: string): Promise<string> | Promise<void>
|
2021-09-14 17:23:12 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-14 22:13:39 +08:00
|
|
|
export type InstallationInfo = {
|
|
|
|
/** The top install dir */
|
|
|
|
installDir: string
|
|
|
|
binDir: string
|
|
|
|
}
|
|
|
|
|
2021-09-14 21:47:16 +08:00
|
|
|
/**
|
|
|
|
* A function that:
|
|
|
|
*
|
|
|
|
* - Downlodas and extracts a package
|
|
|
|
* - Adds the bin path of the package to PATH
|
|
|
|
* - Caches the dowloaded directory into tool cache for usage from other sessions
|
|
|
|
*
|
|
|
|
* @returns The installation directory
|
|
|
|
*/
|
2021-09-14 21:50:26 +08:00
|
|
|
export async function setupPackage(
|
2021-09-14 17:23:12 +08:00
|
|
|
name: string,
|
|
|
|
version: string,
|
2021-09-14 21:47:16 +08:00
|
|
|
getPackageInfo: (version: string, platform: NodeJS.Platform) => PackageInfo | Promise<PackageInfo>,
|
2021-09-14 20:02:34 +08:00
|
|
|
setupCppDir: string
|
2021-09-14 22:13:39 +08:00
|
|
|
): Promise<InstallationInfo> {
|
2021-09-14 19:38:58 +08:00
|
|
|
process.env.RUNNER_TEMP = process.env.RUNNER_TEMP ?? tmpdir()
|
|
|
|
|
2021-09-14 22:13:39 +08:00
|
|
|
const { url, binRelativeDir, extractedFolderName, extractFunction } = await getPackageInfo(version, process.platform)
|
|
|
|
|
2021-09-14 17:23:12 +08:00
|
|
|
// Restore from cache (if found).
|
|
|
|
const dir = find(name, version)
|
|
|
|
if (dir) {
|
2021-09-14 21:47:16 +08:00
|
|
|
info(`${name} ${version} was found in the cache.`)
|
2021-09-14 17:23:12 +08:00
|
|
|
addPath(dir)
|
|
|
|
|
2021-09-14 22:13:39 +08:00
|
|
|
const installDir = join(dir, extractedFolderName)
|
|
|
|
return { installDir, binDir: join(installDir, binRelativeDir) }
|
|
|
|
}
|
2021-09-14 17:23:12 +08:00
|
|
|
|
|
|
|
// Get an unique output directory name from the URL.
|
|
|
|
const key: string = await hasha.async(url)
|
2021-09-14 22:13:39 +08:00
|
|
|
const rootDir = join(setupCppDir, key)
|
2021-09-14 17:23:12 +08:00
|
|
|
|
2021-09-14 21:47:16 +08:00
|
|
|
// download ane extract the package into the installation directory.
|
2021-09-14 22:13:39 +08:00
|
|
|
if (!existsSync(rootDir)) {
|
2021-09-14 21:47:16 +08:00
|
|
|
await group(`Download and extract ${name} ${version}`, async () => {
|
2021-09-14 17:23:12 +08:00
|
|
|
const downloaded = await downloadTool(url)
|
2021-09-14 22:13:39 +08:00
|
|
|
await extractFunction?.(downloaded, rootDir)
|
2021-09-14 17:23:12 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-09-14 22:13:39 +08:00
|
|
|
const installDir = join(rootDir, extractedFolderName)
|
|
|
|
const binDir = join(installDir, binRelativeDir)
|
|
|
|
|
2021-09-14 21:47:16 +08:00
|
|
|
// Adding the bin dir to the path
|
2021-09-14 17:23:12 +08:00
|
|
|
try {
|
2021-09-14 21:47:16 +08:00
|
|
|
/** The directory which the tool is installed to */
|
|
|
|
startGroup(`Add ${binDir} to PATH`)
|
2021-09-14 17:23:12 +08:00
|
|
|
addPath(binDir)
|
|
|
|
} finally {
|
|
|
|
endGroup()
|
|
|
|
}
|
|
|
|
|
2021-09-14 21:02:57 +08:00
|
|
|
// check if inside Github Actions. If so, cache the installation
|
|
|
|
if (typeof process.env.RUNNER_TOOL_CACHE === "string") {
|
2021-09-14 22:13:39 +08:00
|
|
|
await cacheDir(rootDir, name, version)
|
2021-09-14 21:02:57 +08:00
|
|
|
}
|
2021-09-14 17:23:12 +08:00
|
|
|
|
2021-09-14 22:13:39 +08:00
|
|
|
return { installDir, binDir }
|
2021-09-14 17:23:12 +08:00
|
|
|
}
|
2021-09-14 22:04:39 +08:00
|
|
|
/** Add bin extension to a binary. This will be `.exe` on Windows. */
|
|
|
|
export function addBinExtension(name: string) {
|
|
|
|
if (process.platform === "win32") {
|
|
|
|
return `${name}.exe`
|
|
|
|
}
|
|
|
|
return name
|
|
|
|
}
|