From f7cf64158041d3647b489c3d63a52914d265b24f Mon Sep 17 00:00:00 2001 From: asnewman Date: Wed, 8 Dec 2021 20:15:21 -0800 Subject: [PATCH] Add new_command_on_retry --- .github/workflows/ci_cd.yml | 9 +++++++++ README.md | 15 +++++++++++++++ action.yml | 3 +++ src/index.ts | 9 ++++++--- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 7a2274f..7dfd143 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -60,6 +60,15 @@ jobs: actual: ${{ steps.sad_path_wait_sec.outputs.exit_error }} comparison: contains + - name: new-command-on-retry + id: new-command-on-retry + uses: ./ + with: + timeout_minutes: 1 + max_attempts: 3 + command: node -e "process.exit(1)" + new_command_on_retry: node -e "console.log('this is the new command on retry')" + - name: on-retry-cmd id: on-retry-cmd uses: ./ diff --git a/README.md b/README.md index 27d96fb..8d47970 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,10 @@ Retries an Action step on failure or timeout. This is currently intended to repl **Optional** Command to run before a retry (such as a cleanup script). Any error thrown from retry command is caught and surfaced as a warning. +### `new_command_on_retry` + +**Optional** Command to run if the first attempt fails. This command will be called on all subsequent attempts. + ### `continue_on_error` **Optional** Exit successfully even if an error occurs. Same as native continue-on-error behavior, but for use in composite actions. Defaults to `false` @@ -179,6 +183,17 @@ with: on_retry_command: npm run cleanup-flaky-script-output ``` +### Run different command after first failure + +```yaml +uses: nick-invision/retry@v2 +with: + timeout_seconds: 15 + max_attempts: 3 + command: npx jest + new_command_on_retry: npx jest --onlyFailures +``` + ### Run multi-line, multi-command script ```yaml diff --git a/action.yml b/action.yml index ada5748..44de21a 100644 --- a/action.yml +++ b/action.yml @@ -36,6 +36,9 @@ inputs: continue_on_error: description: Exits successfully even if an error occurs. Same as native continue-on-error behavior, but for use in composite actions. Default is false default: false + new_command_on_retry: + description: Command to run if the first attempt fails. This command will be called on all subsequent attempts. + required: false outputs: total_attempts: description: The final number of attempts made diff --git a/src/index.ts b/src/index.ts index 947ad0d..0fa1420 100644 --- a/src/index.ts +++ b/src/index.ts @@ -17,6 +17,7 @@ const RETRY_ON = getInput('retry_on') || 'any'; const WARNING_ON_RETRY = getInput('warning_on_retry').toLowerCase() === 'true'; const ON_RETRY_COMMAND = getInput('on_retry_command'); const CONTINUE_ON_ERROR = getInputBoolean('continue_on_error'); +const NEW_COMMAND_ON_RETRY = getInput('new_command_on_retry'); const OS = process.platform; const OUTPUT_TOTAL_ATTEMPTS_KEY = 'total_attempts'; @@ -122,7 +123,7 @@ async function runRetryCmd(): Promise { } } -async function runCmd() { +async function runCmd(attempt: number) { const end_time = Date.now() + getTimeout(); const executable = getExecutable(); @@ -130,7 +131,9 @@ async function runCmd() { done = false; debug(`Running command ${COMMAND} on ${OS} using shell ${executable}`) - var child = exec(COMMAND, { 'shell': executable }); + var child = attempt > 1 && NEW_COMMAND_ON_RETRY + ? exec(NEW_COMMAND_ON_RETRY, { 'shell': executable }) + : exec(COMMAND, { 'shell': executable }); child.stdout?.on('data', (data) => { process.stdout.write(data); @@ -175,7 +178,7 @@ async function runAction() { try { // just keep overwriting attempts output setOutput(OUTPUT_TOTAL_ATTEMPTS_KEY, attempt); - await runCmd(); + await runCmd(attempt); info(`Command completed after ${attempt} attempt(s).`); break; } catch (error) {