From 6b0802f0df43a7adca17365d9dc5ab55d699fd66 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Mon, 23 Feb 2026 10:58:02 +0100 Subject: [PATCH] feat: handle line-number anchors and issue comments globally Add global GitHub URL handling that applies to ALL repositories, not just the current one: - Line-number anchors (#L123, #L10-L20) on any GitHub /blob/ URL are stripped so the file is still checked but the JS-rendered fragment is skipped - Issue comment anchors (#issuecomment-*) are excluded entirely as they are JS-rendered This means consuming repos no longer need to add these exclusions to their lychee.toml configs. Signed-off-by: Gregor Zeitlinger --- .github/config/lychee.toml | 4 ++-- README.md | 17 ++++++++++++++++- tasks/lint/links.sh | 34 +++++++++++++++++++++++++++++++--- tests/test-links.md | 19 +++++++++++++++++++ 4 files changed, 68 insertions(+), 6 deletions(-) diff --git a/.github/config/lychee.toml b/.github/config/lychee.toml index f848aab..7e803e8 100644 --- a/.github/config/lychee.toml +++ b/.github/config/lychee.toml @@ -10,8 +10,8 @@ max_concurrency = 4 include_fragments = true remap = [ - # workaround for https://github.com/lycheeverse/lychee/issues/1729 - "https://github.com/(.*?)/(.*?)/blob/(.*?)/(.*#.*)$ https://raw.githubusercontent.com/$1/$2/$3/$4" + # GitHub blob URL fragment workaround (lychee#1729) is handled by + # the lint:links script — no global remap needed here ] exclude = [ diff --git a/README.md b/README.md index 473b168..83beae3 100644 --- a/README.md +++ b/README.md @@ -227,8 +227,23 @@ For `/blob/` URLs, three ordered remap rules are applied For `/tree/` URLs, rules 1 and 3 apply (no raw remap needed). +**Global GitHub URL handling:** + +In addition to the PR-specific remaps above, the script handles +two patterns that affect ALL GitHub URLs (any repository): + +- **Line-number anchors** (`#L123`, `#L10-L20`): Stripped from + any GitHub `/blob/` URL. The file is still checked, but the + JS-rendered line-number fragment is skipped. This means + consuming repos don't need to exclude these in their + `lychee.toml`. +- **Issue comment anchors** (`#issuecomment-*`): Excluded + entirely. These are JS-rendered and cannot be verified by + lychee. + Set `LYCHEE_SKIP_GITHUB_REMAPS=true` to disable all GitHub-specific -remaps as an escape hatch if they cause unexpected behavior. +remaps and exclusions as an escape hatch if they cause unexpected +behavior. **Environment variables:** diff --git a/tasks/lint/links.sh b/tasks/lint/links.sh index c86722b..ddd8a3e 100755 --- a/tasks/lint/links.sh +++ b/tasks/lint/links.sh @@ -98,20 +98,48 @@ build_remap_args() { echo "^${base_url}/tree/${base_ref}/(.*)\$ ${head_url}/tree/${head_ref}/\$1" } +# Build global --remap and --exclude args for GitHub URLs that lychee +# cannot verify regardless of repository. +# +# These rules apply to ALL GitHub repos (not just the current one): +# - Line-number anchors (#L123, #L10-L20): rendered by JavaScript, +# lychee cannot verify them. We strip the fragment so the file +# itself is still checked. +# - Issue comment anchors (#issuecomment-*): rendered by JavaScript, +# lychee cannot verify them. +# +# Set LYCHEE_SKIP_GITHUB_REMAPS=true to skip these (same escape hatch +# as for the repo-specific remaps above). +build_global_github_args() { + [ "${LYCHEE_SKIP_GITHUB_REMAPS:-}" != "true" ] || return 0 + + # Strip line-number anchors from /blob/ URLs (still checks the file exists) + echo "--remap" + # shellcheck disable=SC2016 # single quotes are intentional: these are regex capture groups, not shell vars + echo '^https://github.com/([^/]+/[^/]+)/blob/([^/]+)/(.*?)#L[0-9]+.*$ https://github.com/$1/blob/$2/$3' + + # Exclude issue comment anchors (JS-rendered, not in static HTML) + echo "--exclude" + echo '^https://github.com/.*#issuecomment-.*$' +} + run_lychee() { local description="$1" shift - local remap_args=() + local extra_args=() while IFS= read -r line; do - [ -n "$line" ] && remap_args+=("$line") + [ -n "$line" ] && extra_args+=("$line") done < <(build_remap_args) + while IFS= read -r line; do + [ -n "$line" ] && extra_args+=("$line") + done < <(build_global_github_args) echo "==> $description" # shellcheck disable=SC2154 # lychee_args is set via eval above lychee --config "$LYCHEE_CONFIG" \ "${lychee_args[@]+"${lychee_args[@]}"}" \ - "${remap_args[@]+"${remap_args[@]}"}" \ + "${extra_args[@]+"${extra_args[@]}"}" \ "$@" } diff --git a/tests/test-links.md b/tests/test-links.md index d90b0a9..709215e 100644 --- a/tests/test-links.md +++ b/tests/test-links.md @@ -20,3 +20,22 @@ these links verify that each remap rule works correctly during CI. ## Tree URLs — remapped to PR branch - [tasks/lint directory](https://github.com/grafana/flint/tree/main/tasks/lint) + +## External repository line-number anchors — fragment stripped globally + +These test the global remap that strips line-number anchors from ANY +GitHub repository (not just the current one). The file is still checked, +but the JS-rendered fragment is skipped. + + + +- [okhttp build.gradle#L144-L153](https://github.com/square/okhttp/blob/96a2118dd447ebc28a64d9b11a431ca642edc441/build.gradle#L144-L153) + +- [lychee main.rs#L1](https://github.com/lycheeverse/lychee/blob/master/lychee-bin/src/main.rs#L1) + +## Issue comment anchors — excluded globally + +Issue comment anchors are rendered by JavaScript and cannot be +verified by lychee. + +- [example issue comment](https://github.com/grafana/flint/issues/1#issuecomment-1)