mirror of
https://github.com/ryujinx-mirror/unstable-commands.git
synced 2025-02-17 04:49:23 +00:00
Move runUnstableCommand out of main.ts
This commit is contained in:
parent
ecd8f1da70
commit
355d827df4
93
src/main.ts
93
src/main.ts
@ -1,97 +1,6 @@
|
||||
import * as core from '@actions/core'
|
||||
import {spawnSync} from 'child_process'
|
||||
import {getInputs} from './inputs'
|
||||
import {Shell} from './shells'
|
||||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
import os from 'os'
|
||||
|
||||
interface UnstableResult {
|
||||
exitCode: number | null
|
||||
error?: Error
|
||||
}
|
||||
|
||||
export async function runUnstableCommand(
|
||||
commands: string[],
|
||||
shell: Shell,
|
||||
workingDirectory: string,
|
||||
timeoutMinutes: number,
|
||||
maxRetries: number,
|
||||
retryCodes: number[]
|
||||
): Promise<number | null> {
|
||||
const filepath = path.join(
|
||||
os.tmpdir(),
|
||||
`unstable-command${shell.scriptSuffix}`
|
||||
)
|
||||
|
||||
if (shell.args.filter(x => x.includes('{0}')).length === 0) {
|
||||
throw new Error("Shell does not contain the required argument: '{0}'")
|
||||
}
|
||||
|
||||
core.debug(`Writing commands to temporary file: ${filepath}`)
|
||||
await fs.writeFile(filepath, commands.join(os.EOL))
|
||||
core.debug('File was written successfully!')
|
||||
|
||||
const shellArgs: string[] = []
|
||||
for (const arg of shell.args) {
|
||||
if (arg.includes('{0}')) {
|
||||
shellArgs.push(arg.replace('{0}', filepath))
|
||||
continue
|
||||
}
|
||||
shellArgs.push(arg)
|
||||
}
|
||||
|
||||
let result: UnstableResult | null = null
|
||||
|
||||
for (let i = 1; i <= maxRetries; i++) {
|
||||
result = await core.group(
|
||||
`Attempt ${i}/${maxRetries}`,
|
||||
async (): Promise<UnstableResult> => {
|
||||
core.debug('Executing temporary script...')
|
||||
const process = spawnSync(shell.executable, shellArgs, {
|
||||
cwd: workingDirectory,
|
||||
killSignal: 'SIGKILL',
|
||||
timeout: timeoutMinutes * 60 * 1000,
|
||||
stdio: 'inherit'
|
||||
})
|
||||
core.debug('Child process exited.')
|
||||
|
||||
const unstableResult: UnstableResult = {
|
||||
exitCode: process.status
|
||||
}
|
||||
|
||||
if (process.error !== undefined) {
|
||||
unstableResult.error = process.error
|
||||
}
|
||||
|
||||
return unstableResult
|
||||
}
|
||||
)
|
||||
|
||||
if (result.exitCode === null || retryCodes.includes(result.exitCode)) {
|
||||
if (result.exitCode === null) {
|
||||
core.warning(`Process was killed due to a timeout.`)
|
||||
core.debug(`${result.error?.name}: ${result.error?.message}`)
|
||||
} else {
|
||||
core.warning(
|
||||
`Process exited with code '${result.exitCode}' which is part of the specified retry-codes.`
|
||||
)
|
||||
}
|
||||
} else {
|
||||
core.info(`Process exited with code '${result.exitCode}'.`)
|
||||
|
||||
return result.exitCode
|
||||
}
|
||||
}
|
||||
|
||||
core.error(`Aborting after ${maxRetries} attempts.`)
|
||||
core.setFailed(
|
||||
result?.error ??
|
||||
`Child process never returned with a good exit code. Giving up after ${maxRetries} attempts.`
|
||||
)
|
||||
|
||||
return null
|
||||
}
|
||||
import {runUnstableCommand} from './run'
|
||||
|
||||
async function run(): Promise<void> {
|
||||
try {
|
||||
|
93
src/run.ts
Normal file
93
src/run.ts
Normal file
@ -0,0 +1,93 @@
|
||||
import * as core from '@actions/core'
|
||||
import {spawnSync} from 'child_process'
|
||||
import {Shell} from './shells'
|
||||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
import os from 'os'
|
||||
|
||||
interface UnstableResult {
|
||||
exitCode: number | null
|
||||
error?: Error
|
||||
}
|
||||
|
||||
export async function runUnstableCommand(
|
||||
commands: string[],
|
||||
shell: Shell,
|
||||
workingDirectory: string,
|
||||
timeoutMinutes: number,
|
||||
maxRetries: number,
|
||||
retryCodes: number[]
|
||||
): Promise<number | null> {
|
||||
const filepath = path.join(
|
||||
os.tmpdir(),
|
||||
`unstable-command${shell.scriptSuffix}`
|
||||
)
|
||||
|
||||
if (shell.args.filter(x => x.includes('{0}')).length === 0) {
|
||||
throw new Error("Shell does not contain the required argument: '{0}'")
|
||||
}
|
||||
|
||||
core.debug(`Writing commands to temporary file: ${filepath}`)
|
||||
await fs.writeFile(filepath, commands.join(os.EOL))
|
||||
core.debug('File was written successfully!')
|
||||
|
||||
const shellArgs: string[] = []
|
||||
for (const arg of shell.args) {
|
||||
if (arg.includes('{0}')) {
|
||||
shellArgs.push(arg.replace('{0}', filepath))
|
||||
continue
|
||||
}
|
||||
shellArgs.push(arg)
|
||||
}
|
||||
|
||||
let result: UnstableResult | null = null
|
||||
|
||||
for (let i = 1; i <= maxRetries; i++) {
|
||||
result = await core.group(
|
||||
`Attempt ${i}/${maxRetries}`,
|
||||
async (): Promise<UnstableResult> => {
|
||||
core.debug('Executing temporary script...')
|
||||
const process = spawnSync(shell.executable, shellArgs, {
|
||||
cwd: workingDirectory,
|
||||
killSignal: 'SIGKILL',
|
||||
timeout: timeoutMinutes * 60 * 1000,
|
||||
stdio: 'inherit'
|
||||
})
|
||||
core.debug('Child process exited.')
|
||||
|
||||
const unstableResult: UnstableResult = {
|
||||
exitCode: process.status
|
||||
}
|
||||
|
||||
if (process.error !== undefined) {
|
||||
unstableResult.error = process.error
|
||||
}
|
||||
|
||||
return unstableResult
|
||||
}
|
||||
)
|
||||
|
||||
if (result.exitCode === null || retryCodes.includes(result.exitCode)) {
|
||||
if (result.exitCode === null) {
|
||||
core.warning(`Process was killed due to a timeout.`)
|
||||
core.debug(`${result.error?.name}: ${result.error?.message}`)
|
||||
} else {
|
||||
core.warning(
|
||||
`Process exited with code '${result.exitCode}' which is part of the specified retry-codes.`
|
||||
)
|
||||
}
|
||||
} else {
|
||||
core.info(`Process exited with code '${result.exitCode}'.`)
|
||||
|
||||
return result.exitCode
|
||||
}
|
||||
}
|
||||
|
||||
core.error(`Aborting after ${maxRetries} attempts.`)
|
||||
core.setFailed(
|
||||
result?.error ??
|
||||
`Child process never returned with a good exit code. Giving up after ${maxRetries} attempts.`
|
||||
)
|
||||
|
||||
return null
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import {expect, test} from '@jest/globals'
|
||||
import {runUnstableCommand} from '../src/main'
|
||||
import {runUnstableCommand} from '../src/run'
|
||||
import {getShell} from '../src/shells'
|
||||
|
||||
test('unstable command succeeds', async () => {
|
Loading…
x
Reference in New Issue
Block a user