mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-19 00:56:16 +00:00
ci(docs): treat non-404 4xx link-check failures as warnings, not errors
markdown-link-check has no concept of "warning" vs "error" — it's a binary alive/dead per link, so a transient 429 from a rate-limiting site we don't control (recently: blogspot.com, izndgroup.com) fails the whole CI job exactly like a genuine dead link, with no way to tell them apart from the job's exit code. New scripts/check-doc-links.sh wraps the tool per file, parses its "[✖] <url> → Status: <code>" output, and re-decides pass/fail per link: 404 still fails the build (a real dead link, worth fixing), other 4xx (429, 401, 403, ...) become a GitHub Actions ::warning:: annotation instead, and anything else (5xx, timeouts, DNS failures) still fails the build same as before. De-dupes markdown-link-check's own doubled -v output. Written for bash 3.2 (macOS's default /bin/bash) so it's testable locally, not just on the ubuntu-latest runner. Existing retry config in .github/markdown-link-check.json (retryOn429, 3 retries, 30s backoff) is untouched; this only changes what happens once retries are exhausted. Verified locally: 6 synthetic scenarios (404/429/500/mixed/clean/ duplicate-line) via a stubbed markdown-link-check, plus a real run against the docs tree with the actual tool.
This commit is contained in:
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bash
|
||||
# Wraps markdown-link-check with a status-code-aware pass/fail policy that
|
||||
# the tool itself doesn't support: a 404 is a real dead link (fails the
|
||||
# build), but most other 4xx responses (429 rate-limited, 401/403
|
||||
# anti-bot/access-restricted, ...) just mean the checker couldn't get a
|
||||
# clean answer from a site we don't control — those are downgraded to a
|
||||
# GitHub Actions warning annotation instead of failing CI. Anything else
|
||||
# (5xx, timeouts, DNS failures) still fails the build, same as before.
|
||||
#
|
||||
# Usage: scripts/check-doc-links.sh [root-dir]
|
||||
# Requires markdown-link-check on PATH and .github/markdown-link-check.json.
|
||||
set -euo pipefail
|
||||
|
||||
root="${1:-.}"
|
||||
config=".github/markdown-link-check.json"
|
||||
had_error=0
|
||||
|
||||
while IFS= read -r -d '' file; do
|
||||
echo "Checking links in $file"
|
||||
|
||||
set +e
|
||||
output=$(markdown-link-check -q -v -c "$config" "$file" 2>&1)
|
||||
set -e
|
||||
|
||||
echo "$output"
|
||||
|
||||
# markdown-link-check's -v mode logs each dead link more than once
|
||||
# (inline with the raw error detail, then again in its summary); de-dupe
|
||||
# on (url, code) so each broken link gets one annotation. A plain
|
||||
# delimited string, not an associative array (bash 3.2, macOS's
|
||||
# default /bin/bash, predates those), with a sentinel on both sides of
|
||||
# each key so substring matches can't collide.
|
||||
seen="|"
|
||||
|
||||
while IFS= read -r line; do
|
||||
[ -z "$line" ] && continue
|
||||
|
||||
url=$(sed -E 's/^[[:space:]]*\[✖\] (.*) → Status: .*/\1/' <<<"$line")
|
||||
code=$(sed -E 's/.*Status: ([0-9]+).*/\1/' <<<"$line")
|
||||
|
||||
key="${url}#${code}|"
|
||||
case "$seen" in
|
||||
*"|${key}"*) continue ;;
|
||||
esac
|
||||
seen="${seen}${key}"
|
||||
|
||||
if [[ "$code" =~ ^[0-9]+$ ]] && [ "$code" != "404" ] && [ "$code" -ge 400 ] && [ "$code" -lt 500 ]; then
|
||||
echo "::warning file=${file}::Link check got HTTP ${code} (treated as non-fatal, see scripts/check-doc-links.sh): ${url}"
|
||||
else
|
||||
echo "::error file=${file}::Dead link (${code:-no response}): ${url}"
|
||||
had_error=1
|
||||
fi
|
||||
done < <(grep -F '[✖]' <<<"$output" || true)
|
||||
done < <(find "$root" -name "*.md" -not -path "./tests/*" -not -path "./node_modules/*" -print0)
|
||||
|
||||
exit "$had_error"
|
||||
Reference in New Issue
Block a user