diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml index 1d298f5..a762ff9 100644 --- a/.github/workflows/ci_cd.yml +++ b/.github/workflows/ci_cd.yml @@ -36,6 +36,100 @@ jobs: command: node ./.github/scripts/log-examples.js timeout_minutes: 1 + - name: Multi-line 2 commands non existent first command + id: multi_line_2_commands_non_existent_first_command + uses: ./ + continue-on-error: true + with: + shell: bash + timeout_seconds: 1 + max_attempts: 2 + command: | + i-do-not-exist && \ + echo "i-exist" + - uses: nick-invision/assert-action@v1 + with: + expected: 2 + actual: ${{ steps.multi_line_2_commands_non_existent_first_command.outputs.total_attempts }} + - uses: nick-invision/assert-action@v1 + with: + expected: 'Final attempt failed' + actual: ${{ steps.multi_line_2_commands_non_existent_first_command.outputs.exit_error }} + comparison: contains + - uses: nick-invision/assert-action@v1 + with: + # The 127 error code indicates “command not found”. + expected: '127' + actual: ${{ steps.multi_line_2_commands_non_existent_first_command.outputs.exit_code }} + comparison: contains + - uses: nick-invision/assert-action@v1 + with: + expected: 'i-exist' + actual: ${{ steps.multi_line_2_commands_non_existent_first_command.outputs.exit_error }} + comparison: notContains + + - name: Multi-line 2 commands happy path test + id: multi_line_2_commands_happy_path + uses: ./ + with: + shell: bash + timeout_seconds: 1 + max_attempts: 2 + command: | + echo "foo" && \ + echo "bar" + - uses: nick-invision/assert-action@v1 + with: + expected: 1 + actual: ${{ steps.multi_line_2_commands_happy_path.outputs.total_attempts }} + + - name: Conventional multi-line non existent first command + id: conventional_multi_line_non_existent_first_command + uses: ./ + continue-on-error: true + with: + shell: bash + timeout_seconds: 1 + max_attempts: 2 + command: | + i-do-not-exist + echo "i-exist" + - uses: nick-invision/assert-action@v1 + with: + expected: 2 + actual: ${{ steps.conventional_multi_line_non_existent_first_command.outputs.total_attempts }} + - uses: nick-invision/assert-action@v1 + with: + expected: 'Final attempt failed' + actual: ${{ steps.conventional_multi_line_non_existent_first_command.outputs.exit_error }} + comparison: contains + - uses: nick-invision/assert-action@v1 + with: + # The 127 error code indicates “command not found”. + expected: '127' + actual: ${{ steps.conventional_multi_line_non_existent_first_command.outputs.exit_code }} + comparison: contains + - uses: nick-invision/assert-action@v1 + with: + expected: 'i-exist' + actual: ${{ steps.conventional_multi_line_non_existent_first_command.outputs.exit_error }} + comparison: notContains + + - name: Conventional multi-line happy path test + id: conventional_multi_line_happy_path + uses: ./ + with: + shell: bash + timeout_seconds: 1 + max_attempts: 2 + command: | + echo "foo" + echo "bar" + - uses: nick-invision/assert-action@v1 + with: + expected: 1 + actual: ${{ steps.conventional_multi_line_happy_path.outputs.total_attempts }} + - name: sad-path (retry_wait_seconds) id: sad_path_wait_sec uses: ./ diff --git a/dist/index.js b/dist/index.js index 656e63e..d00d2d3 100644 --- a/dist/index.js +++ b/dist/index.js @@ -708,11 +708,14 @@ function getTimeout() { } function getExecutable() { if (!SHELL) { - return OS === 'win32' ? 'powershell' : 'bash'; + return OS === 'win32' ? 'powershell' : 'bash -e '; } var executable; switch (SHELL) { - case "bash": + case "bash": { + executable = "bash -e "; + break; + } case "python": case "pwsh": { executable = SHELL; @@ -2590,4 +2593,4 @@ function buildProcessTree (parentPid, tree, pidsToProcess, spawnChildProcessesLi /***/ }) -/******/ }); \ No newline at end of file +/******/ }); diff --git a/src/index.ts b/src/index.ts index b2fa2ff..2152f6a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -78,12 +78,16 @@ function getTimeout(): number { function getExecutable(): string { if (!SHELL) { - return OS === 'win32' ? 'powershell' : 'bash'; + return OS === 'win32' ? 'powershell' : 'bash -e'; } let executable: string; switch (SHELL) { - case "bash": + case "bash": { + // -e to not ignore errors, but exit with non-zero code. + executable = "bash -e"; + break; + } case "python": case "pwsh": { executable = SHELL; @@ -131,7 +135,7 @@ async function runCmd(attempt: number) { exit = 0; done = false; - debug(`Running command ${COMMAND} on ${OS} using shell ${executable}`) + debug(`Running command ${COMMAND} on ${OS} using shell "${executable}"`) var child = attempt > 1 && NEW_COMMAND_ON_RETRY ? exec(NEW_COMMAND_ON_RETRY, { 'shell': executable }) : exec(COMMAND, { 'shell': executable });