From 961aa0fa3ea2d625b41e4af8533511561a089998 Mon Sep 17 00:00:00 2001 From: Anders Fischer-Nielsen Date: Mon, 11 Apr 2022 09:47:29 +0200 Subject: [PATCH 1/7] feat: retry only on specific exit code --- action.yml | 3 +++ dist/index.js | 4 +++- src/index.ts | 6 +++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/action.yml b/action.yml index 44de21a..7528bc4 100644 --- a/action.yml +++ b/action.yml @@ -39,6 +39,9 @@ inputs: new_command_on_retry: description: Command to run if the first attempt fails. This command will be called on all subsequent attempts. required: false + retry_on_exit_code: + description: Specific exit code to retry on. This will only retry for the given error code and fail immediately other error codes. + required: false outputs: total_attempts: description: The final number of attempts made diff --git a/dist/index.js b/dist/index.js index ae13ef3..7f6d393 100644 --- a/dist/index.js +++ b/dist/index.js @@ -289,6 +289,7 @@ var WARNING_ON_RETRY = core_1.getInput('warning_on_retry').toLowerCase() === 'tr var ON_RETRY_COMMAND = core_1.getInput('on_retry_command'); var CONTINUE_ON_ERROR = getInputBoolean('continue_on_error'); var NEW_COMMAND_ON_RETRY = core_1.getInput('new_command_on_retry'); +var RETRY_ON_EXIT_CODE = getInputNumber('retry_on_exit_code', false); var OS = process.platform; var OUTPUT_TOTAL_ATTEMPTS_KEY = 'total_attempts'; var OUTPUT_EXIT_CODE_KEY = 'exit_code'; @@ -499,7 +500,8 @@ function runAction() { // error: timeout throw error_2; case 7: - if (!(exit > 0 && RETRY_ON === 'timeout')) return [3 /*break*/, 8]; + if (!(((RETRY_ON_EXIT_CODE && RETRY_ON_EXIT_CODE !== exit) || exit > 0) && + RETRY_ON === 'timeout')) return [3 /*break*/, 8]; // error: error throw error_2; case 8: return [4 /*yield*/, runRetryCmd()]; diff --git a/src/index.ts b/src/index.ts index 0fa1420..0364f1d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,6 +18,7 @@ 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 RETRY_ON_EXIT_CODE = getInputNumber('retry_on_exit_code', false); const OS = process.platform; const OUTPUT_TOTAL_ATTEMPTS_KEY = 'total_attempts'; @@ -187,7 +188,10 @@ async function runAction() { } else if (!done && RETRY_ON === 'error') { // error: timeout throw error; - } else if (exit > 0 && RETRY_ON === 'timeout') { + } else if ( + ((RETRY_ON_EXIT_CODE && RETRY_ON_EXIT_CODE !== exit) || exit > 0) && + RETRY_ON === 'timeout' + ) { // error: error throw error; } else { From 4e441eac6137d4758380346eb78099aaa5536c6f Mon Sep 17 00:00:00 2001 From: Anders Fischer-Nielsen Date: Mon, 11 Apr 2022 09:50:22 +0200 Subject: [PATCH 2/7] feat: retry only on specific exit code --- .github/workflows/ci_cd.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 7dfd143..f6b5e03 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -79,6 +79,26 @@ jobs: command: node -e "process.exit(1)" on_retry_command: node -e "console.log('this is a retry command')" + - name: retry_on_exit_code (with expected error code) + id: retry_on_exit_code + uses: ./ + continue-on-error: true + with: + timeout_minutes: 1 + retry_on_exit_code: 2 + max_attempts: 3 + command: node -e "process.exit(2)" + + - name: retry_on_exit_code (with unexpected error code) + id: retry_on_exit_code + uses: ./ + continue-on-error: true + with: + timeout_minutes: 1 + retry_on_exit_code: 2 + max_attempts: 3 + command: node -e "process.exit(1)" + - name: on-retry-cmd (on-retry fails) id: on-retry-cmd-fails uses: ./ From e19da5faf0c2d990f975b0add8748a6ca5391036 Mon Sep 17 00:00:00 2001 From: Anders Fischer-Nielsen Date: Tue, 19 Apr 2022 09:57:50 +0200 Subject: [PATCH 3/7] Run ci_cd on all push events --- .github/workflows/ci_cd.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index f6b5e03..04d1f05 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -1,8 +1,7 @@ name: CI/CD on: push: - branches: - - '**' + jobs: # runs on branch pushes only ci: From cf714f3adb9e8dc6428e966286535e77cf037516 Mon Sep 17 00:00:00 2001 From: Nick Fields Date: Tue, 19 Apr 2022 08:30:49 -0400 Subject: [PATCH 4/7] dedupe step IDs --- .github/workflows/ci_cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 04d1f05..acd9150 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -79,7 +79,7 @@ jobs: on_retry_command: node -e "console.log('this is a retry command')" - name: retry_on_exit_code (with expected error code) - id: retry_on_exit_code + id: retry_on_exit_code_expected uses: ./ continue-on-error: true with: @@ -89,7 +89,7 @@ jobs: command: node -e "process.exit(2)" - name: retry_on_exit_code (with unexpected error code) - id: retry_on_exit_code + id: retry_on_exit_code_unexpected uses: ./ continue-on-error: true with: From 679f4bb87af33a23def6cb41465450583967c062 Mon Sep 17 00:00:00 2001 From: Nick Fields Date: Tue, 19 Apr 2022 08:31:10 -0400 Subject: [PATCH 5/7] add assertions for retry_on_exit_code tests --- .github/workflows/ci_cd.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index acd9150..b886f5a 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -87,6 +87,14 @@ jobs: retry_on_exit_code: 2 max_attempts: 3 command: node -e "process.exit(2)" + - uses: nick-invision/assert-action@v1 + with: + expected: failure + actual: ${{ steps.retry_on_exit_code_expected.outcome }} + - uses: nick-invision/assert-action@v1 + with: + expected: 3 + actual: ${{ steps.retry_on_exit_code_expected.outputs.total_attempts }} - name: retry_on_exit_code (with unexpected error code) id: retry_on_exit_code_unexpected @@ -97,6 +105,14 @@ jobs: retry_on_exit_code: 2 max_attempts: 3 command: node -e "process.exit(1)" + - uses: nick-invision/assert-action@v1 + with: + expected: failure + actual: ${{ steps.retry_on_exit_code_unexpected.outcome }} + - uses: nick-invision/assert-action@v1 + with: + expected: 1 + actual: ${{ steps.retry_on_exit_code_unexpected.outputs.total_attempts }} - name: on-retry-cmd (on-retry fails) id: on-retry-cmd-fails From 102009eded99892dea80ed1e14dc1dd83a8b36a4 Mon Sep 17 00:00:00 2001 From: Nick Fields Date: Mon, 25 Apr 2022 21:43:44 -0400 Subject: [PATCH 6/7] minor: implemented suggested fix from @andersfischernielsen --- dist/index.js | 24 +++++++++++++----------- src/index.ts | 7 +++---- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/dist/index.js b/dist/index.js index 7f6d393..098970d 100644 --- a/dist/index.js +++ b/dist/index.js @@ -480,17 +480,17 @@ function runAction() { attempt = 1; _a.label = 2; case 2: - if (!(attempt <= MAX_ATTEMPTS)) return [3 /*break*/, 12]; + if (!(attempt <= MAX_ATTEMPTS)) return [3 /*break*/, 13]; _a.label = 3; case 3: - _a.trys.push([3, 5, , 11]); + _a.trys.push([3, 5, , 12]); // just keep overwriting attempts output core_1.setOutput(OUTPUT_TOTAL_ATTEMPTS_KEY, attempt); return [4 /*yield*/, runCmd(attempt)]; case 4: _a.sent(); core_1.info("Command completed after " + attempt + " attempt(s)."); - return [3 /*break*/, 12]; + return [3 /*break*/, 13]; case 5: error_2 = _a.sent(); if (!(attempt === MAX_ATTEMPTS)) return [3 /*break*/, 6]; @@ -500,12 +500,14 @@ function runAction() { // error: timeout throw error_2; case 7: - if (!(((RETRY_ON_EXIT_CODE && RETRY_ON_EXIT_CODE !== exit) || exit > 0) && - RETRY_ON === 'timeout')) return [3 /*break*/, 8]; + if (!(RETRY_ON_EXIT_CODE && RETRY_ON_EXIT_CODE !== exit)) return [3 /*break*/, 8]; + throw error_2; + case 8: + if (!(exit > 0 && RETRY_ON === 'timeout')) return [3 /*break*/, 9]; // error: error throw error_2; - case 8: return [4 /*yield*/, runRetryCmd()]; - case 9: + case 9: return [4 /*yield*/, runRetryCmd()]; + case 10: _a.sent(); if (WARNING_ON_RETRY) { core_1.warning("Attempt " + attempt + " failed. Reason: " + error_2.message); @@ -513,12 +515,12 @@ function runAction() { else { core_1.info("Attempt " + attempt + " failed. Reason: " + error_2.message); } - _a.label = 10; - case 10: return [3 /*break*/, 11]; - case 11: + _a.label = 11; + case 11: return [3 /*break*/, 12]; + case 12: attempt++; return [3 /*break*/, 2]; - case 12: return [2 /*return*/]; + case 13: return [2 /*return*/]; } }); }); diff --git a/src/index.ts b/src/index.ts index 0364f1d..b2fa2ff 100644 --- a/src/index.ts +++ b/src/index.ts @@ -188,10 +188,9 @@ async function runAction() { } else if (!done && RETRY_ON === 'error') { // error: timeout throw error; - } else if ( - ((RETRY_ON_EXIT_CODE && RETRY_ON_EXIT_CODE !== exit) || exit > 0) && - RETRY_ON === 'timeout' - ) { + } else if (RETRY_ON_EXIT_CODE && RETRY_ON_EXIT_CODE !== exit){ + throw error; + } else if (exit > 0 && RETRY_ON === 'timeout') { // error: error throw error; } else { From 217d6c1354d170af8bce6f21a138ee486367386e Mon Sep 17 00:00:00 2001 From: Nick Fields Date: Mon, 25 Apr 2022 21:59:48 -0400 Subject: [PATCH 7/7] docs: update readme to reflect new retry_on_exit_code input --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 25a03ab..5539f45 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Retries an Action step on failure or timeout. This is currently intended to replace the `run` step for moody commands. -**NOTE:** Ownership of this project was transferred to my personal account `nick-fields` from my work account `nick-invision`. Details [here](#Ownership) +**NOTE:** Ownership of this project was transferred to my personal account `nick-fields` from my work account `nick-invision`. Details [here](#Ownership) --- @@ -56,6 +56,10 @@ Retries an Action step on failure or timeout. This is currently intended to repl **Optional** Exit successfully even if an error occurs. Same as native continue-on-error behavior, but for use in composite actions. Defaults to `false` +### `retry_on_exit_code` + +**Optional** Specific exit code to retry on. This will only retry for the given error code and fail immediately other error codes. + ## Outputs ### `total_attempts` @@ -233,6 +237,6 @@ NodeJS is required for this action to run. This runs without issue on all GitHub ## **Ownership** -As of 2022/02/15 ownership of this project has been transferred to my personal account `nick-fields` from my work account `nick-invision` due to me leaving InVision. I am the author and have been the primary maintainer since day one and will continue to maintain this as needed. +As of 2022/02/15 ownership of this project has been transferred to my personal account `nick-fields` from my work account `nick-invision` due to me leaving InVision. I am the author and have been the primary maintainer since day one and will continue to maintain this as needed. Existing workflow references to `nick-invision/retry@` no longer work and must be updated to `nick-fields/retry@`.