diff --git a/.github/workflows/check-links.yml b/.github/workflows/check-links.yml index c5e4d7503..78629e1fc 100644 --- a/.github/workflows/check-links.yml +++ b/.github/workflows/check-links.yml @@ -43,12 +43,14 @@ jobs: git worktree add "$RUNNER_TEMP/base" "$merge_base" git diff -U0 "$merge_base" HEAD > "$RUNNER_TEMP/changes.diff" + # The script exits 1 both with findings and when it crashes. It writes + # its output in one go at the end, so a crash leaves it empty. A crash + # does not fail the check, since it says nothing about the PR; the + # comment step reports it instead of posting the empty report. - name: Record broken links already present on the base branch - # Exit 1 means findings, which is expected here run: | node dev/check-links.mjs --check-anchors --check-self-links --format json \ - --root "$RUNNER_TEMP/base" > "$RUNNER_TEMP/base-links.json" \ - || [ $? -eq 1 ] + --root "$RUNNER_TEMP/base" > "$RUNNER_TEMP/base-links.json" || true - name: Find broken links introduced by this PR id: check @@ -56,14 +58,22 @@ jobs: # File links in the report open the file on the PR branch LINK_BASE: ${{ github.event.pull_request.head.repo.html_url }}/blob/${{ github.event.pull_request.head.ref }} run: | + if ! [ -s "$RUNNER_TEMP/base-links.json" ]; then + echo "::warning::check-links crashed on the base branch, so this PR was not checked" + echo "result=crashed" >> "$GITHUB_OUTPUT" + exit 0 + fi if node dev/check-links.mjs --check-anchors --check-self-links --check-external --format markdown \ --baseline "$RUNNER_TEMP/base-links.json" \ --diff "$RUNNER_TEMP/changes.diff" \ --review "$RUNNER_TEMP/review.json" \ --link-base "$LINK_BASE" > "$RUNNER_TEMP/report.md"; then - echo "broken=false" >> "$GITHUB_OUTPUT" + echo "result=clean" >> "$GITHUB_OUTPUT" + elif [ -s "$RUNNER_TEMP/report.md" ]; then + echo "result=broken" >> "$GITHUB_OUTPUT" else - echo "broken=true" >> "$GITHUB_OUTPUT" + echo "::warning::check-links crashed, so this PR was not checked" + echo "result=crashed" >> "$GITHUB_OUTPUT" fi cat "$RUNNER_TEMP/report.md" @@ -73,21 +83,25 @@ jobs: env: GH_TOKEN: ${{ github.token }} PR_NUMBER: ${{ github.event.pull_request.number }} - BROKEN: ${{ steps.check.outputs.broken }} + RESULT: ${{ steps.check.outputs.result }} + RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} run: | marker='' existing_comment=$(gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" \ --paginate --jq ".[] | select(.body | startswith(\"$marker\")) | .id" | head -n 1) - # Comment only when there is something to report, or an earlier report to resolve - if [ "$BROKEN" = true ]; then - { echo "$marker"; cat "$RUNNER_TEMP/report.md"; } > "$RUNNER_TEMP/comment.md" - elif [ -n "$existing_comment" ]; then - printf '%s\n### ✅ The broken links an earlier revision of this PR introduced are fixed\n' \ - "$marker" > "$RUNNER_TEMP/comment.md" - else - exit 0 - fi + # Comment when there is something to report, or an earlier report to resolve + case "$RESULT" in + broken) + { echo "$marker"; cat "$RUNNER_TEMP/report.md"; } > "$RUNNER_TEMP/comment.md" ;; + crashed) + printf '%s\n### ⚠️ The links check could not run on this revision\n\nThis is a problem with the check, not with this PR; see the [job log](%s).\n' \ + "$marker" "$RUN_URL" > "$RUNNER_TEMP/comment.md" ;; + *) + [ -n "$existing_comment" ] || exit 0 + printf '%s\n### ✅ This revision introduces no broken links\n' \ + "$marker" > "$RUNNER_TEMP/comment.md" ;; + esac if [ -n "$existing_comment" ]; then gh api --method PATCH "repos/$GITHUB_REPOSITORY/issues/comments/$existing_comment" \ @@ -99,12 +113,14 @@ jobs: - name: Suggest fixes as review comments # One suggested change per finding with a fix, kept in sync with the # findings; see dev/sync-review-comments.sh - if: github.event.pull_request.head.repo.full_name == github.repository + if: >- + github.event.pull_request.head.repo.full_name == github.repository + && contains(fromJSON('["clean", "broken"]'), steps.check.outputs.result) env: GH_TOKEN: ${{ github.token }} PR_NUMBER: ${{ github.event.pull_request.number }} run: dev/sync-review-comments.sh '' existing_comment=$(gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" \ --paginate --jq ".[] | select(.body | startswith(\"$marker\")) | .id" | head -n 1) - # Comment only when there is something to report, or an earlier report to resolve - if [ "$BROKEN" = true ]; then - { echo "$marker"; cat "$RUNNER_TEMP/report.md"; } > "$RUNNER_TEMP/comment.md" - elif [ -n "$existing_comment" ]; then - printf '%s\n### ✅ The redirects an earlier revision of this PR broke are fixed\n' \ - "$marker" > "$RUNNER_TEMP/comment.md" - else - exit 0 - fi + # Comment when there is something to report, or an earlier report to resolve + case "$RESULT" in + broken) + { echo "$marker"; cat "$RUNNER_TEMP/report.md"; } > "$RUNNER_TEMP/comment.md" ;; + crashed) + printf '%s\n### ⚠️ The redirects check could not run on this revision\n\nThis is a problem with the check, not with this PR; see the [job log](%s).\n' \ + "$marker" "$RUN_URL" > "$RUNNER_TEMP/comment.md" ;; + *) + [ -n "$existing_comment" ] || exit 0 + printf '%s\n### ✅ This revision breaks no redirects\n' \ + "$marker" > "$RUNNER_TEMP/comment.md" ;; + esac if [ -n "$existing_comment" ]; then gh api --method PATCH "repos/$GITHUB_REPOSITORY/issues/comments/$existing_comment" \ @@ -100,12 +115,14 @@ jobs: - name: Suggest fixes as review comments # One suggested change per fixable entry this PR added, kept in sync # with the findings; see dev/sync-review-comments.sh - if: github.event.pull_request.head.repo.full_name == github.repository + if: >- + github.event.pull_request.head.repo.full_name == github.repository + && contains(fromJSON('["clean", "broken"]'), steps.check.outputs.result) env: GH_TOKEN: ${{ github.token }} PR_NUMBER: ${{ github.event.pull_request.number }} run: dev/sync-review-comments.sh '