Skip to content

Check Links

Check Links #122

Workflow file for this run

name: Check Links
# Checks all markdown files for broken links using lychee
# Key flags:
# --cache: Cache results to speed up subsequent runs
# --exclude-link-local: Skip localhost/127.0.0.1 links (not reachable in CI)
# .lycheeignore is auto-detected for URL patterns to exclude
# Creates a GitHub issue on failure for visibility
on:
pull_request:
paths:
- "**.md"
schedule:
- cron: "0 0 * * 0" # Weekly on Sunday at midnight UTC
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
issues: write # Required for creating issue on failure
jobs:
linkChecker:
name: Check Markdown Links
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
# Static key: lychee handles staleness via --max-cache-age 1d
# Split restore/save pattern ensures cache is saved even on failure
- name: Restore lychee cache
id: restore-cache
uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
with:
path: .lycheecache
key: cache-lychee-v1
- name: Link Checker
uses: lycheeverse/lychee-action@a8c4c7cb88f0c7386610c35eb25108e448569cb0 # v2.7.0
with:
args: >-
--cache
--max-cache-age 1d
--verbose
--no-progress
--exclude-link-local
'**/*.md'
fail: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Save lychee cache
uses: actions/cache/save@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
if: always()
with:
path: .lycheecache
key: cache-lychee-v1
# Check for existing issue to avoid duplicates, then create or comment
- name: Check for existing open issue
if: failure()
id: check-issue
run: |
issue=$(gh issue list --state open \
--search "in:title Broken links detected" \
--json number --jq '.[0].number // empty')
echo "issue_number=$issue" >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create issue for broken links
if: failure() && steps.check-issue.outputs.issue_number == ''
run: gh issue create --title "Broken links detected" --body-file ./lychee/out.md
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Comment on existing issue
if: failure() && steps.check-issue.outputs.issue_number != ''
run: |
run_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${RUN_ID}"
{
echo "## 🔄 Link check failed again"
echo ""
echo "**Run**: [${RUN_ID}](${run_url})"
echo "**Triggered by**: ${GITHUB_EVENT_NAME}"
echo ""
cat ./lychee/out.md
} | gh issue comment "${{ steps.check-issue.outputs.issue_number }}" --body-file -
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RUN_ID: ${{ github.run_id }}