feat: add timeout for installation of the tools

This commit is contained in:
Amin Yahyaabadi 2023-08-21 20:11:21 -07:00
parent 99a4fe7118
commit d93dc2b536
14 changed files with 107 additions and 67 deletions

View File

@ -84,6 +84,10 @@ inputs:
powershell:
description: "The powershell version to install."
required: false
timeout:
description: "The timeout for installation of one tool (in minutes)."
default: "10"
required: false
runs:
using: "node16"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -112,6 +112,7 @@
"npm-check-updates": "^16.10.17",
"npm-run-all2": "^6.0.6",
"numerous": "1.0.3",
"p-timeout": "^6.1.2",
"parcel": "2.9.3",
"path-exists": "^5.0.0",
"patha": "^0.4.1",

View File

@ -134,6 +134,9 @@ importers:
numerous:
specifier: 1.0.3
version: 1.0.3
p-timeout:
specifier: ^6.1.2
version: 6.1.2
parcel:
specifier: 2.9.3
version: 2.9.3
@ -8780,6 +8783,11 @@ packages:
aggregate-error: 3.1.0
dev: true
/p-timeout@6.1.2:
resolution: {integrity: sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==}
engines: {node: '>=14.16'}
dev: true
/p-try@2.2.0:
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
engines: {node: '>=6'}

View File

@ -1,6 +1,5 @@
import { syncVersions, getVersion } from "../versions/versions"
import { parseArgs } from "../cli-options"
import { Inputs } from "../tool"
import { parseArgs, Inputs } from "../cli-options"
import { getCompilerInfo } from "../compilers"
jest.setTimeout(300000)

View File

@ -2,11 +2,17 @@ import { getInput } from "@actions/core"
import { info } from "ci-log"
import mri from "mri"
import { InstallationInfo } from "./utils/setup/setupBin"
import { Inputs, inputs } from "./tool"
import { setups, tools } from "./tool"
/** The possible inputs to the program */
export type Inputs = keyof typeof setups | "compiler" | "architecture" | "timeout"
/** an array of possible inputs */
export const inputs: Array<Inputs> = ["compiler", "architecture", "timeout", ...tools]
export function parseArgs(args: string[]): Opts {
return mri<Record<Inputs, string | undefined> & { help: boolean }>(args, {
string: inputs,
string: [...inputs, "timeout"],
default: Object.fromEntries(inputs.map((inp) => [inp, maybeGetInput(inp)])),
alias: { h: "help" },
boolean: "help",
@ -21,9 +27,9 @@ setup-cpp --compiler llvm --cmake true --ninja true --ccache true --vcpkg true
Install all the tools required for building and testing C++/C projects.
--architecture\t the cpu architecture to install the tools for. By default it uses the current CPU architecture.
--timeout\t the timeout for the installation of each tool in minutes. By default it is 10 minutes.
--compiler\t the <compiler> to install.
\t You can specify the version instead of specifying just the name e.g: --compiler 'llvm-13.0.0'
--$tool_name\t pass "true" or pass the <version> you would like to install for this tool. e.g. --conan true or --conan "1.42.1"
All the available tools:
@ -54,6 +60,7 @@ export function maybeGetInput(key: string) {
export type Opts = mri.Argv<
Record<Inputs, string | undefined> & {
help: boolean
timeout?: string
}
>

View File

@ -78,7 +78,16 @@ async function main(args: string[]): Promise<number> {
// running the setup function for this tool
time1 = Date.now()
// eslint-disable-next-line no-await-in-loop
hasLLVM = await installTool(tool, version, osVersion, arch, setupCppDir, successMessages, errorMessages)
hasLLVM = await installTool(
tool,
version,
osVersion,
arch,
setupCppDir,
successMessages,
errorMessages,
parseFloat(opts.timeout ?? "0.1"),
)
time2 = Date.now()
info(`took ${timeFormatter.format(time1, time2) || "0 seconds"}`)
}

View File

@ -30,46 +30,9 @@ import { InstallationInfo } from "./utils/setup/setupBin"
import { setupVcpkg } from "./vcpkg/vcpkg"
import { setupVCVarsall } from "./vcvarsall/vcvarsall"
import { getVersion } from "./versions/versions"
import pTimeout from "p-timeout"
export async function installTool(
tool: ToolName,
version: string,
osVersion: number[] | null,
arch: string,
setupCppDir: string,
successMessages: string[],
errorMessages: string[],
) {
startGroup(`Installing ${tool} ${version}`)
let hasLLVM = false
try {
let installationInfo: InstallationInfo | undefined | void
if (tool === "vcvarsall") {
// eslint-disable-next-line no-await-in-loop
await setupVCVarsall(getVersion(tool, version, osVersion), undefined, arch, undefined, undefined, false, false)
} else {
// get the setup function
const setupFunction = setups[tool]
hasLLVM = ["llvm", "clangformat", "clangtidy"].includes(tool)
// the tool installation directory (for the functions that ue it)
const setupDir = join(setupCppDir, hasLLVM ? "llvm" : tool)
// eslint-disable-next-line no-await-in-loop
installationInfo = await setupFunction(getVersion(tool, version, osVersion), setupDir, arch)
}
// preparing a report string
successMessages.push(getSuccessMessage(tool, installationInfo))
} catch (e) {
// push error message to the logger
error(e as string | Error)
errorMessages.push(`${tool} failed to install`)
}
endGroup()
return hasLLVM
} /** The setup functions */
/** The setup functions */
export const setups = {
nala: setupNala,
cmake: setupCmake,
@ -102,12 +65,62 @@ export const setups = {
}
export type ToolName = keyof typeof setups
/** The tools that can be installed */
export const tools = Object.keys(setups) as Array<ToolName>
/** The possible inputs to the program */
export type Inputs = keyof typeof setups | "compiler" | "architecture"
/** an array of possible inputs */
export async function installTool(
tool: ToolName,
version: string,
osVersion: number[] | null,
arch: string,
setupCppDir: string,
successMessages: string[],
errorMessages: string[],
timeout: number = 0.1,
) {
startGroup(`Installing ${tool} ${version}`)
let hasLLVM = false
try {
hasLLVM = await pTimeout(installToolImpl(tool, version, osVersion, arch, hasLLVM, setupCppDir, successMessages), {
milliseconds: timeout * 60 * 1000,
})
} catch (e) {
// push error message to the logger
error(e as string | Error)
errorMessages.push(`${tool} failed to install`)
}
endGroup()
return hasLLVM
}
export const inputs: Array<Inputs> = ["compiler", "architecture", ...tools]
async function installToolImpl(
tool: ToolName,
version: string,
osVersion: number[] | null,
arch: string,
hasLLVM: boolean,
setupCppDir: string,
successMessages: string[],
) {
let installationInfo: InstallationInfo | undefined | void
if (tool === "vcvarsall") {
// eslint-disable-next-line no-await-in-loop
await setupVCVarsall(getVersion(tool, version, osVersion), undefined, arch, undefined, undefined, false, false)
} else {
// get the setup function
const setupFunction = setups[tool]
// eslint-disable-next-line no-param-reassign
hasLLVM = ["llvm", "clangformat", "clangtidy"].includes(tool)
// the tool installation directory (for the functions that ue it)
const setupDir = join(setupCppDir, hasLLVM ? "llvm" : tool)
// eslint-disable-next-line no-await-in-loop
installationInfo = await setupFunction(getVersion(tool, version, osVersion), setupDir, arch)
}
// preparing a report string
successMessages.push(getSuccessMessage(tool, installationInfo))
return hasLLVM
}

View File

@ -1,5 +1,4 @@
import { Opts } from "../cli-options"
import { Inputs } from "../tool"
import { Opts, Inputs } from "../cli-options"
import { DefaultLinuxVersion, DefaultVersions } from "./default_versions"
/** Get the default version if passed true or undefined, otherwise return the version itself */