Skip to content

Broken Link Checker #32

Broken Link Checker

Broken Link Checker #32

name: Broken Link Checker
on:
pull_request:
paths:
- '**/*.md'
workflow_dispatch:
permissions:
contents: read
jobs:
markdown-link-check:
name: Check Markdown Broken Links
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get Added/Modified Markdown Files (PR only)
id: changed-files
if: github.event_name == 'pull_request'
run: |
git fetch origin ${{ github.base_ref }}
files=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep '\.md$' || true)
echo "md_files<<EOF" >> $GITHUB_OUTPUT
echo "$files" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Run Lychee (PR)
if: github.event_name == 'pull_request' && steps.changed-files.outputs.md_files != ''
run: |
npx lychee --verbose --exclude-mail --no-progress --exclude ^https?:// ${{ steps.changed-files.outputs.md_files }} > lychee_output.txt || true
- name: Run Lychee (Manual)
if: github.event_name == 'workflow_dispatch'
run: |
npx lychee --verbose --exclude-mail --no-progress --exclude ^https?:// '**/*.md' > lychee_output.txt || true
- name: Filter Commented-Out Links from Output
run: |
cat > filter_lychee_output.sh <<'EOF'
#!/bin/bash
LYCHEE_OUTPUT_FILE="lychee_output.txt"
FINAL_OUTPUT_FILE="lychee_final_output.txt"
> "$FINAL_OUTPUT_FILE"
current_file=""
while IFS= read -r line; do
if [[ "$line" =~ ^Errors\ in\ (.*)\ \[ERROR\]?$ ]]; then
current_file="${BASH_REMATCH[1]}"
echo "$line" >> "$FINAL_OUTPUT_FILE"
continue
fi
if [[ "$line" =~ file://(.*)\ \| ]]; then
full_path="${BASH_REMATCH[1]}"
broken_link=$(basename "$full_path")
if [ -f "$current_file" ]; then
if grep -zoP "(?s)<!--.*?$broken_link.*?-->" "$current_file" > /dev/null; then
echo "Skipping commented-out link: $broken_link in $current_file"
continue
fi
fi
echo "$line" >> "$FINAL_OUTPUT_FILE"
fi
done < "$LYCHEE_OUTPUT_FILE"
echo "Filtered Lychee output saved to $FINAL_OUTPUT_FILE"
EOF
chmod +x filter_lychee_output.sh
./filter_lychee_output.sh
- name: Save Filtered Errors to Markdown File
run: |
mkdir -p lychee
echo "# 🔗 Broken Link Report" > lychee/out.md
echo "" >> lychee/out.md
if [ -s lychee_final_output.txt ]; then
cat lychee_final_output.txt >> lychee/out.md
else
echo "✅ No non-commented broken links found." >> lychee/out.md
fi
- name: Upload Filtered Report as Artifact
uses: actions/upload-artifact@v4
with:
name: filtered-link-report
path: lychee/out.md
- name: Fail if Real Broken Links Remain
run: |
if grep -q "\[ERROR\]" lychee_final_output.txt; then
echo "❌ Found non-commented broken links:"
cat lychee_final_output.txt
exit 1
else
echo "✅ No real broken links found."
fi