mirror of
https://github.com/nick-fields/retry.git
synced 2026-02-12 16:17:42 +00:00
Merge pull request #30 from isaacrlevin/master
feat: add SHELL input support
This commit is contained in:
53
.github/workflows/ci_cd.yml
vendored
53
.github/workflows/ci_cd.yml
vendored
@@ -197,6 +197,59 @@ jobs:
|
||||
expected: failure
|
||||
actual: ${{ steps.sad_path_timeout.outcome }}
|
||||
|
||||
- name: sad-path (wrong shell for OS)
|
||||
id: wrong_shell
|
||||
uses: ./
|
||||
continue-on-error: true
|
||||
with:
|
||||
timeout_minutes: 1
|
||||
max_attempts: 2
|
||||
shell: cmd
|
||||
command: "dir"
|
||||
- uses: nick-invision/assert-action@v1
|
||||
with:
|
||||
expected: 2
|
||||
actual: ${{ steps.wrong_shell.outputs.total_attempts }}
|
||||
- uses: nick-invision/assert-action@v1
|
||||
with:
|
||||
expected: failure
|
||||
actual: ${{ steps.wrong_shell.outcome }}
|
||||
|
||||
ci_windows:
|
||||
name: Run Windows Tests
|
||||
if: startsWith(github.ref, 'refs/heads')
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 12
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Powershell test
|
||||
uses: ./
|
||||
with:
|
||||
timeout_minutes: 1
|
||||
max_attempts: 2
|
||||
shell: powershell
|
||||
command: Get-ComputerInfo
|
||||
- name: CMD.exe test
|
||||
uses: ./
|
||||
with:
|
||||
timeout_minutes: 1
|
||||
max_attempts: 2
|
||||
shell: cmd
|
||||
command: echo %PATH%
|
||||
- name: Python test
|
||||
uses: ./
|
||||
with:
|
||||
timeout_minutes: 1
|
||||
max_attempts: 2
|
||||
shell: python
|
||||
command: print 1, 2, 3
|
||||
|
||||
# runs on push to master only
|
||||
cd:
|
||||
name: Publish Action
|
||||
|
||||
17
README.md
17
README.md
@@ -24,6 +24,12 @@ Retries an Action step on failure or timeout. This is currently intended to repl
|
||||
|
||||
**Optional** Number of seconds to wait before attempting the next retry. Defaults to `10`
|
||||
|
||||
### `shell`
|
||||
|
||||
**Optional** Shell to use to execute `command`. Defaults to `pwsh`. See [here](https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#using-a-specific-shell) for shell options
|
||||
required: false
|
||||
default: pwsh
|
||||
|
||||
### `polling_interval_seconds`
|
||||
|
||||
**Optional** Number of seconds to wait while polling for command result. Defaults to `1`
|
||||
@@ -52,6 +58,17 @@ The final error returned by the command
|
||||
|
||||
## Examples
|
||||
|
||||
### Shell
|
||||
|
||||
```yaml
|
||||
uses: nick-invision/retry@v2
|
||||
with:
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
shell: pwsh
|
||||
command: dir
|
||||
```
|
||||
|
||||
### Timeout in minutes
|
||||
|
||||
```yaml
|
||||
|
||||
@@ -18,6 +18,9 @@ inputs:
|
||||
description: Number of seconds to wait before attempting the next retry
|
||||
required: false
|
||||
default: 10
|
||||
shell:
|
||||
description: Shell to Use to retry (Default is pwsh)
|
||||
required: false
|
||||
polling_interval_seconds:
|
||||
description: Number of seconds to wait for each check that command has completed running
|
||||
required: false
|
||||
@@ -36,4 +39,4 @@ outputs:
|
||||
description: The final error returned by the command
|
||||
runs:
|
||||
using: 'node12'
|
||||
main: 'dist/index.js'
|
||||
main: 'dist/index.js'
|
||||
41
dist/index.js
vendored
41
dist/index.js
vendored
@@ -249,9 +249,11 @@ var TIMEOUT_SECONDS = getInputNumber('timeout_seconds', false);
|
||||
var MAX_ATTEMPTS = getInputNumber('max_attempts', true) || 3;
|
||||
var COMMAND = core_1.getInput('command', { required: true });
|
||||
var RETRY_WAIT_SECONDS = getInputNumber('retry_wait_seconds', false) || 10;
|
||||
var SHELL = core_1.getInput('shell');
|
||||
var POLLING_INTERVAL_SECONDS = getInputNumber('polling_interval_seconds', false) || 1;
|
||||
var RETRY_ON = core_1.getInput('retry_on') || 'any';
|
||||
var WARNING_ON_RETRY = core_1.getInput('warning_on_retry').toLowerCase() === 'true';
|
||||
var OS = process.platform;
|
||||
var OUTPUT_TOTAL_ATTEMPTS_KEY = 'total_attempts';
|
||||
var OUTPUT_EXIT_CODE_KEY = 'exit_code';
|
||||
var OUTPUT_EXIT_ERROR_KEY = 'exit_error';
|
||||
@@ -305,17 +307,52 @@ function getTimeout() {
|
||||
}
|
||||
throw new Error('Must specify either timeout_minutes or timeout_seconds inputs');
|
||||
}
|
||||
function getExecutable() {
|
||||
if (!SHELL) {
|
||||
return OS === 'win32' ? 'powershell' : 'bash';
|
||||
}
|
||||
var executable;
|
||||
switch (SHELL) {
|
||||
case "bash":
|
||||
case "python":
|
||||
case "pwsh": {
|
||||
executable = SHELL;
|
||||
break;
|
||||
}
|
||||
case "sh": {
|
||||
if (OS === 'win32') {
|
||||
throw new Error("Shell " + SHELL + " not allowed on OS " + OS);
|
||||
}
|
||||
executable = SHELL;
|
||||
break;
|
||||
}
|
||||
case "cmd":
|
||||
case "powershell": {
|
||||
if (OS !== 'win32') {
|
||||
throw new Error("Shell " + SHELL + " not allowed on OS " + OS);
|
||||
}
|
||||
executable = SHELL + ".exe";
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new Error("Shell " + SHELL + " required");
|
||||
}
|
||||
}
|
||||
return executable;
|
||||
}
|
||||
function runCmd() {
|
||||
var _a, _b;
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var end_time, child;
|
||||
var end_time, executable, child;
|
||||
return __generator(this, function (_c) {
|
||||
switch (_c.label) {
|
||||
case 0:
|
||||
end_time = Date.now() + getTimeout();
|
||||
executable = getExecutable();
|
||||
exit = 0;
|
||||
done = false;
|
||||
child = child_process_1.exec(COMMAND);
|
||||
core_1.debug("Running command " + COMMAND + " on " + OS + " using shell " + executable);
|
||||
child = child_process_1.exec(COMMAND, { 'shell': executable });
|
||||
(_a = child.stdout) === null || _a === void 0 ? void 0 : _a.on('data', function (data) {
|
||||
process.stdout.write(data);
|
||||
});
|
||||
|
||||
@@ -2,5 +2,6 @@ INPUT_TIMEOUT_MINUTES=1
|
||||
INPUT_MAX_ATTEMPTS=3
|
||||
INPUT_COMMAND="node -e 'process.exit(99)'"
|
||||
INPUT_RETRY_WAIT_SECONDS=10
|
||||
SHELL=pwsh
|
||||
INPUT_POLLING_INTERVAL_SECONDS=1
|
||||
INPUT_RETRY_ON=any
|
||||
|
||||
41
src/index.ts
41
src/index.ts
@@ -11,10 +11,12 @@ const TIMEOUT_SECONDS = getInputNumber('timeout_seconds', false);
|
||||
const MAX_ATTEMPTS = getInputNumber('max_attempts', true) || 3;
|
||||
const COMMAND = getInput('command', { required: true });
|
||||
const RETRY_WAIT_SECONDS = getInputNumber('retry_wait_seconds', false) || 10;
|
||||
const SHELL = getInput('shell');
|
||||
const POLLING_INTERVAL_SECONDS = getInputNumber('polling_interval_seconds', false) || 1;
|
||||
const RETRY_ON = getInput('retry_on') || 'any';
|
||||
const WARNING_ON_RETRY = getInput('warning_on_retry').toLowerCase() === 'true';
|
||||
|
||||
const OS = process.platform;
|
||||
const OUTPUT_TOTAL_ATTEMPTS_KEY = 'total_attempts';
|
||||
const OUTPUT_EXIT_CODE_KEY = 'exit_code';
|
||||
const OUTPUT_EXIT_ERROR_KEY = 'exit_error';
|
||||
@@ -61,13 +63,50 @@ function getTimeout(): number {
|
||||
throw new Error('Must specify either timeout_minutes or timeout_seconds inputs');
|
||||
}
|
||||
|
||||
function getExecutable(): string {
|
||||
if (!SHELL) {
|
||||
return OS === 'win32' ? 'powershell' : 'bash';
|
||||
}
|
||||
|
||||
let executable: string;
|
||||
switch (SHELL) {
|
||||
case "bash":
|
||||
case "python":
|
||||
case "pwsh": {
|
||||
executable = SHELL;
|
||||
break;
|
||||
}
|
||||
case "sh": {
|
||||
if (OS === 'win32') {
|
||||
throw new Error(`Shell ${SHELL} not allowed on OS ${OS}`);
|
||||
}
|
||||
executable = SHELL;
|
||||
break;
|
||||
}
|
||||
case "cmd":
|
||||
case "powershell": {
|
||||
if (OS !== 'win32') {
|
||||
throw new Error(`Shell ${SHELL} not allowed on OS ${OS}`);
|
||||
}
|
||||
executable = SHELL + ".exe";
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Shell ${SHELL} required`);
|
||||
}
|
||||
}
|
||||
return executable
|
||||
}
|
||||
|
||||
async function runCmd() {
|
||||
const end_time = Date.now() + getTimeout();
|
||||
const executable = getExecutable();
|
||||
|
||||
exit = 0;
|
||||
done = false;
|
||||
|
||||
var child = exec(COMMAND);
|
||||
debug(`Running command ${COMMAND} on ${OS} using shell ${executable}`)
|
||||
var child = exec(COMMAND, { 'shell': executable });
|
||||
|
||||
child.stdout?.on('data', (data) => {
|
||||
process.stdout.write(data);
|
||||
|
||||
Reference in New Issue
Block a user