Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions tasks/lint/links.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,66 @@ LYCHEE_CONFIG="${LYCHEE_CONFIG:-.github/config/lychee.toml}"

eval "lychee_args=(${usage_lychee_args:-})"

# Build --remap args to redirect base-branch GitHub URLs to the PR branch.
# This ensures links like /blob/main/README.md resolve on the PR branch.
build_remap_args() {
local repo base_ref head_ref head_repo

# Resolve repo name
if [ -n "${GITHUB_REPOSITORY:-}" ]; then
repo="$GITHUB_REPOSITORY"
else
local remote_url
remote_url=$(git config --get remote.origin.url 2>/dev/null) || return 0
# Extract owner/repo from HTTPS or SSH URLs
repo=$(echo "$remote_url" | sed -n 's|.*github\.com[:/]\(.*\)\.git$|\1|p; s|.*github\.com[:/]\(.*\)$|\1|p' | head -1)
[ -n "$repo" ] || return 0
fi

# Resolve base branch
if [ -n "${GITHUB_BASE_REF:-}" ]; then
base_ref="$GITHUB_BASE_REF"
else
base_ref=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|.*/||') || true
base_ref="${base_ref:-main}"
fi

# Resolve head branch
if [ -n "${GITHUB_HEAD_REF:-}" ]; then
head_ref="$GITHUB_HEAD_REF"
else
head_ref=$(git rev-parse --abbrev-ref HEAD 2>/dev/null) || return 0
fi

# Skip if on the base branch (no point remapping main → main)
[ "$head_ref" != "$base_ref" ] || return 0

# Resolve head repo (for forks; only matters in CI)
head_repo="${PR_HEAD_REPO:-$repo}"

local base_url="https://github.com/${repo}"
local head_url="https://github.com/${head_repo}"

echo "--remap"
echo "${base_url}/blob/${base_ref}/(.*) ${head_url}/blob/${head_ref}/\$1"
echo "--remap"
echo "${base_url}/tree/${base_ref}/(.*) ${head_url}/tree/${head_ref}/\$1"
Comment on lines +57 to +59
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The remap pattern is missing regex anchors (^ and $). Without anchors, the pattern could match partial URLs incorrectly. The pattern should be anchored to match complete URLs: ^${base_url}/blob/${base_ref}/(.*)$

This is particularly important because lychee uses these patterns for regex matching, and without anchors, a URL like https://example.com/link-to-https://github.com/owner/repo/blob/main/file.md could be incorrectly matched and remapped.

Suggested change
echo "${base_url}/blob/${base_ref}/(.*) ${head_url}/blob/${head_ref}/\$1"
echo "--remap"
echo "${base_url}/tree/${base_ref}/(.*) ${head_url}/tree/${head_ref}/\$1"
echo "^${base_url}/blob/${base_ref}/(.*)\$ ${head_url}/blob/${head_ref}/\$1"
echo "--remap"
echo "^${base_url}/tree/${base_ref}/(.*)\$ ${head_url}/tree/${head_ref}/\$1"

Copilot uses AI. Check for mistakes.
Comment on lines +57 to +59
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The remap pattern is missing regex anchors (^ and $). Without anchors, the pattern could match partial URLs incorrectly. The pattern should be anchored to match complete URLs: ^${base_url}/tree/${base_ref}/(.*)$

This is particularly important because lychee uses these patterns for regex matching, and without anchors, a URL like https://example.com/link-to-https://github.com/owner/repo/tree/main/path could be incorrectly matched and remapped.

Suggested change
echo "${base_url}/blob/${base_ref}/(.*) ${head_url}/blob/${head_ref}/\$1"
echo "--remap"
echo "${base_url}/tree/${base_ref}/(.*) ${head_url}/tree/${head_ref}/\$1"
echo "^${base_url}/blob/${base_ref}/(.*)$ ${head_url}/blob/${head_ref}/\$1"
echo "--remap"
echo "^${base_url}/tree/${base_ref}/(.*)$ ${head_url}/tree/${head_ref}/\$1"

Copilot uses AI. Check for mistakes.
Comment on lines +53 to +59
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Branch names and repository names may contain special characters (like / in branch names for feature branches like feature/my-feature) that could break the regex pattern. These values should be escaped before being used in the regex pattern to prevent regex interpretation of special characters.

Consider using a regex escaping function or quoting mechanism to handle special characters like ., *, +, ?, [, ], {, }, (, ), ^, $, |, \, and /.

Copilot uses AI. Check for mistakes.
}

run_lychee() {
local description="$1"
shift

local remap_args=()
while IFS= read -r line; do
[ -n "$line" ] && remap_args+=("$line")
done < <(build_remap_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[@]}"}" \
"$@"
}

Expand Down