From ae4699150ab670dcfb64cc74e8680e776d9caae2 Mon Sep 17 00:00:00 2001 From: LitoMore Date: Sun, 27 Oct 2024 16:17:00 +0800 Subject: [PATCH 1/3] Add missing argument `failIfEmpty` (#261) --- README.md | 10 ++++++---- entrypoint.sh | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 62d77bc..e36e604 100644 --- a/README.md +++ b/README.md @@ -52,16 +52,17 @@ lychee arguments can be passed to the action via the `args` parameter. On top of that, the action also supports some additional arguments. -| Argument | Examples | Description | -| ------------- | ----------------------- | -------------------------------------------------------------------------------- | +| Argument | Examples | Description | +| ------------- | ----------------------- | ------------------------------------------------------------------------------- | | args | `--cache`, `--insecure` | See [lychee's documentation][lychee-args] for all arguments and values | | debug | `false` | Enable debug output in action (set -x). Helpful for troubleshooting | | fail | `false` | Fail workflow run on error (i.e. when [lychee exit code][lychee-exit] is not 0) | +| failIfEmpty | `false` | Fail entire pipeline if no links were found | | format | `markdown`, `json` | Summary output format | | jobSummary | `false` | Write GitHub job summary (on Markdown output only) | | lycheeVersion | `v0.15.0`, `nightly` | Overwrite the lychee version to be used | | output | `lychee/results.md` | Summary output file path | -| token | `""` | Custom GitHub token to use for API calls | +| token | `""` | Custom GitHub token to use for API calls | See [action.yml](./action.yml) for a full list of supported arguments and their default values. @@ -79,7 +80,7 @@ Here is how to pass the arguments. format: json # Use different output file path output: /tmp/foo.txt - # Use a custom GitHub token, which + # Use a custom GitHub token, which token: ${{ secrets.CUSTOM_TOKEN }} # Don't fail action on broken links fail: false @@ -113,6 +114,7 @@ So in this setup, as long as a user triggers the CI run from the same commit, it For restoring the cache, the most recent available one is used (commit hash doesn't matter). If you need more control over when caches are restored and saved, you can split the cache step and e.g. ensure to always save the cache (also when the link check step fails): + ```yml - name: Restore lychee cache id: restore-cache diff --git a/entrypoint.sh b/entrypoint.sh index ba2a65c..e5cbb55 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -32,7 +32,7 @@ eval lychee ${FORMAT} --output ${LYCHEE_TMP} ${ARGS} exit_code=$? # Overwrite the exit code in case no links were found -# and `fail-if-empty` is set to `true` (and it is by default) +# and `failIfEmpty` is set to `true` (and it is by default) if [ "${INPUT_FAILIFEMPTY}" = "true" ]; then # Explicitly set INPUT_FAIL to true to ensure the script fails # if no links are found @@ -40,7 +40,7 @@ if [ "${INPUT_FAILIFEMPTY}" = "true" ]; then # 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 'fail-if-empty: false' in the args." >> "${LYCHEE_TMP}" + echo "If this was expected, set 'failIfEmpty: false' in the args." >> "${LYCHEE_TMP}" exit_code=1 fi fi From 988c4c129a79e6d2aa7e28cc1ec14997c3b4e831 Mon Sep 17 00:00:00 2001 From: "Y.D.X." <73375426+YDX-2147483647@users.noreply.github.com> Date: Thu, 7 Nov 2024 08:34:17 +0800 Subject: [PATCH 2/3] Fix bugs about the exit code (#262) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - **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 <12570668+sebastiaanspeck@users.noreply.github.com> --- .github/workflows/links.yml | 3 +- .github/workflows/test.yml | 56 +++++++++++++++++++++++++++++++++++++ README.md | 2 +- action.yml | 15 +--------- entrypoint.sh | 37 ++++++++++++++---------- 5 files changed, 83 insertions(+), 30 deletions(-) diff --git a/.github/workflows/links.yml b/.github/workflows/links.yml index 1f078fe..374af07 100644 --- a/.github/workflows/links.yml +++ b/.github/workflows/links.yml @@ -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' @@ -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 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 10bb9e1..c4fe117 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -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: ./ @@ -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 diff --git a/README.md b/README.md index e36e604..211ef26 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/action.yml b/action.yml index 9402faa..8e1e6e4 100644 --- a/action.yml +++ b/action.yml @@ -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 }} diff --git a/entrypoint.sh b/entrypoint.sh index e5cbb55..5711db3 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -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" @@ -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 @@ -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 From f81112d0d2814ded911bd23e3beaa9dda9093915 Mon Sep 17 00:00:00 2001 From: Matthias Endler Date: Thu, 7 Nov 2024 01:39:37 +0100 Subject: [PATCH 3/3] Bump version to 0.17.0 (#263) --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 8e1e6e4..0d6e4ca 100644 --- a/action.yml +++ b/action.yml @@ -28,7 +28,7 @@ inputs: required: false lycheeVersion: description: "Use custom version of lychee link checker" - default: v0.16.1 + default: v0.17.0 required: false output: description: "Summary output file path"