From 9a89b197d2a50a2ab2e86b8c733aee1670a5b8e3 Mon Sep 17 00:00:00 2001 From: Big Wella <267203242+bigwellaadmin-dev@users.noreply.github.com> Date: Tue, 26 May 2026 07:56:18 +1000 Subject: [PATCH] ci(links): tolerate auth walls and anti-bot 403s in link checker Add lychee.toml at the repo root so the link-checker configuration is auditable in one place. Accept 403 and 429 as success (these mean "the link works but lychee cannot follow it"), follow redirects up to 5 hops, retry once on transient errors, and use a browser-shaped UA so CDN-fronted sites do not bot-block. Excludes the Private Vulnerability Reporting URL from checking. The URL is correct, but it 302-redirects to a GitHub login wall that lychee cannot follow. --- .github/workflows/validate.yml | 10 ++++----- lychee.toml | 41 ++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 lychee.toml diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 8b996f7..bff6ee7 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -38,13 +38,11 @@ jobs: - name: Lychee link checker uses: lycheeverse/lychee-action@1d97d84f0bc547f7b25f4c2170d87d810dc2fb2c # v2.6.1 with: - # Check every committed markdown file. Skip mailto: and localhost. - # `--no-progress` makes the log readable. `--max-redirects` allows - # githubusercontent and short-link hops. + # Configuration lives in lychee.toml at the repo root. Args here + # only point lychee at the markdown files to check; everything + # else (accepted status codes, retries, user agent, exclude list) + # is driven by the config so it stays auditable in one place. args: >- --no-progress - --max-redirects 5 - --exclude-mail - --exclude '^https?://(localhost|127\.0\.0\.1)' './**/*.md' fail: true diff --git a/lychee.toml b/lychee.toml new file mode 100644 index 0000000..19f2556 --- /dev/null +++ b/lychee.toml @@ -0,0 +1,41 @@ +# Lychee link-checker configuration. +# +# CI runs `lychee './**/*.md'` against every committed markdown file. Most +# defaults are fine; the overrides below stop lychee from flagging links +# that are correct but answer with non-200 status codes for legitimate +# reasons (authentication walls, anti-bot 403s, transient rate limits). + +# Status codes treated as success. Defaults are 200-299; we add common +# redirect codes (handled by --max-redirects but listed explicitly for +# clarity) and 403/429 which mean "the link works but lychee is not +# allowed to fetch it." Both are normal for GitHub security pages and +# CDN-fronted sites. +accept = ["200..=299", "301..=308", "403", "429"] + +# Follow redirects (e.g. lowercase repo aliases, shortened URLs). +max_redirects = 5 + +# Be polite, retry once with a small backoff on transient errors. +max_retries = 2 +retry_wait_time = 2 + +# Send a real browser UA — some hosts (Cloudflare, Squarespace, etc.) +# 403 anything that looks like a bot. +user_agent = "Mozilla/5.0 (compatible; lychee-link-checker)" + +# Per-link timeout in seconds. +timeout = 20 + +# Skip mail addresses and any link that would resolve to the local host. +exclude_mail = true +exclude = [ + # localhost / loopback + "^https?://(localhost|127\\.0\\.0\\.1|0\\.0\\.0\\.0)", + # The PVR URL 302-redirects to a GitHub login wall, which lychee + # cannot follow. The URL itself is correct. + "^https://github\\.com/bigwellaadmin-dev/verify/security/advisories/new$", +] + +# Tell lychee where to look. The workflow also passes this on the +# command line as a safety net. +include_verbatim = false