Skip to content

Commit

Permalink
Fix bugs about the exit code (#262)
Browse files Browse the repository at this point in the history
-   **fix: Make `fail: false` effective even when `failIfEmpty: true`**

This commit also makes sure `outputs.exit_code` is “The exit code returned from Lychee”. `failIfEmpty` no longer changes it to `1`.

Relevant docs:
- [Setting exit codes for actions - GitHub Docs](https://docs.github.com/en/actions/sharing-automations/creating-actions/setting-exit-codes-for-actions)
- [exit - POSIX Programmer's Manual](https://manned.org/exit.1posix)

Relates to #86, #128, #145, #245, and #251.

-   **fix: Update `env.exit_code` to `outputs.exit_code`**

The previous expression always gives `false`.
Both `env.exit_code` and `env.lychee_exit_code` are `null`, probably since the docker→composite refactor #128. When GitHub evaluates the expression, it finds the types do not match, and coerces them to number, namely, `null` → `0`.

See [Evaluate expressions in workflows and actions - GitHub Docs](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/evaluate-expressions-in-workflows-and-actions#operators).

Relates to #253.



Co-authored-by: Sebastiaan Speck <[email protected]>
  • Loading branch information
YDX-2147483647 and sebastiaanspeck authored Nov 7, 2024
1 parent ae46991 commit 988c4c1
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 30 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/links.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ jobs:
- uses: actions/checkout@v4

- name: Link Checker
id: lychee
uses: ./ # Uses an action in the root directory
with:
args: --user-agent "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0" --verbose --exclude spinroot.com --no-progress './**/*.md' './**/*.html' './**/*.rst'
Expand All @@ -23,7 +24,7 @@ jobs:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}

- name: Create Issue From File
if: env.exit_code != 0
if: ${{ steps.lychee.outputs.exit_code }} != 0
uses: peter-evans/create-issue-from-file@v5
with:
title: Link Checker Report
Expand Down
56 changes: 56 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,28 @@ jobs:
echo "Output set in args and action input should have failed."
exit 1
- name: test fail - a lychee error should fail the pipeline
id: fail_test
uses: ./
with:
args: --verbose --no-progress foo.bar
debug: true
continue-on-error: true

# Explicitly check the exit code of the previous step
# as it's expected to fail
- name: Check fail
if: steps.fail_test.outcome != 'failure'
run: |
echo "Fail should have failed because the URL is invalid."
exit 1
- name: test disable fail - it's okay if lychee throws an error
uses: ./
with:
args: --no-progress foo.bar
fail: false

- name: test failIfEmpty - no links in input should fail the pipeline
id: fail_if_empty_test
uses: ./
Expand All @@ -147,6 +169,40 @@ jobs:
args: --no-progress fixtures/empty.md
failIfEmpty: false

- name: test disable failIfEmpty - a lychee error should still fail the pipeline
id: fail_but_not_failIfEmpty_test
uses: ./
with:
args: --verbose --no-progress foo.bar
failIfEmpty: false
debug: true
continue-on-error: true

# Explicitly check the exit code of the previous step
# as it's expected to fail
- name: Check fail when failIfEmpty is disabled
if: steps.fail_but_not_failIfEmpty_test.outcome != 'failure'
run: |
echo "Fail should have failed because the URL is invalid, even though failIfEmpty is disabled."
exit 1
- name: test disable fail - no links in input should still fail the pipeline
id: failIfEmpty_but_not_fail_test
uses: ./
with:
args: --verbose --no-progress fixtures/empty.md
fail: false
debug: true
continue-on-error: true

# Explicitly check the exit code of the previous step
# as it's expected to fail
- name: Check failIfEmpty when fail is disabled
if: steps.failIfEmpty_but_not_fail_test.outcome != 'failure'
run: |
echo "FailIfEmpty should have failed because no links were found, even though fail is disabled."
exit 1
- name: Install jq
run: sudo apt-get install jq

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
uses: lycheeverse/lychee-action@v2

- name: Create Issue From File
if: env.exit_code != 0
if: ${{ steps.lychee.outputs.exit_code }} != 0
uses: peter-evans/create-issue-from-file@v5
with:
title: Link Checker Report
Expand Down
15 changes: 1 addition & 14 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,20 +106,7 @@ runs:

- name: Run Lychee
id: run-lychee
run: |
# This step runs lychee and captures its exit code.
# We use 'set +e' to prevent the script from exiting immediately if lychee fails.
# This allows us to capture the exit code and pass it both to GitHub Actions (via GITHUB_OUTPUT)
# and to the shell (via the final 'exit $EXIT_CODE').
# This ensures that:
# 1. The step fails if lychee fails
# 2. The exit code is available as an output for subsequent steps
# 3. The exit code is properly propagated to the workflow
set +e
${{ github.action_path }}/entrypoint.sh
EXIT_CODE=$?
echo "exit_code=$EXIT_CODE" >> $GITHUB_OUTPUT
exit $EXIT_CODE
run: ${{ github.action_path }}/entrypoint.sh
env:
# https://github.com/actions/runner/issues/665
INPUT_TOKEN: ${{ inputs.TOKEN }}
Expand Down
37 changes: 23 additions & 14 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
#!/bin/bash -l
set -uo pipefail

# We use ‘set +e’ to prevent the script from exiting immediately if lychee fails.
# This ensures that:
# 1. Lychee exit code can be captured and passed to subsequent steps via `$GITHUB_OUTPUT`.
# 2. This step’s outcome (success/failure) can be controlled according to inputs
# by manually calling the ‘exit’ command.
set +e

# Enable optional debug output
if [ "${INPUT_DEBUG}" = true ]; then
echo "Debug output enabled"
Expand Down Expand Up @@ -29,19 +36,17 @@ fi

# Execute lychee
eval lychee ${FORMAT} --output ${LYCHEE_TMP} ${ARGS}
exit_code=$?
LYCHEE_EXIT_CODE=$?

# Overwrite the exit code in case no links were found
# and `failIfEmpty` is set to `true` (and it is by default)
# If no links were found and `failIfEmpty` is set to `true` (and it is by default),
# fail with an error later, but leave lychee exit code untouched.
should_fail_because_empty=false
if [ "${INPUT_FAILIFEMPTY}" = "true" ]; then
# Explicitly set INPUT_FAIL to true to ensure the script fails
# if no links are found
INPUT_FAIL=true
# This is a somewhat crude way to check the Markdown output of lychee
if grep -E 'Total\s+\|\s+0' "${LYCHEE_TMP}"; then
echo "No links were found. This usually indicates a configuration error." >> "${LYCHEE_TMP}"
echo "If this was expected, set 'failIfEmpty: false' in the args." >> "${LYCHEE_TMP}"
exit_code=1
should_fail_because_empty=true
fi
fi

Expand All @@ -67,12 +72,16 @@ if [ "${INPUT_FORMAT}" == "markdown" ]; then
fi
fi

# Pass lychee exit code to next step
echo "exit_code=$exit_code" >> $GITHUB_OUTPUT
# Pass lychee exit code to subsequent steps
echo "exit_code=$LYCHEE_EXIT_CODE" >> "$GITHUB_OUTPUT"

# If `fail` is set to `true` (and it is by default), propagate the real exit
# value to the workflow runner. This will cause the pipeline to fail on
# `exit != # 0`.
if [ "$INPUT_FAIL" = true ] ; then
exit ${exit_code}
# Determine the outcome of this step
# Exiting with a nonzero value will fail the pipeline, but the specific value
# does not matter. (GitHub does not share it with subsequent steps for composite actions.)
if [ "$should_fail_because_empty" = true ] ; then
# If we decided previously to fail because no links were found, fail
exit 1
elif [ "$INPUT_FAIL" = true ] ; then
# If `fail` is set to `true` (and it is by default), propagate lychee exit code
exit ${LYCHEE_EXIT_CODE}
fi

0 comments on commit 988c4c1

Please sign in to comment.