|
@@ -0,0 +1,113 @@
|
|
|
|
|
+name: Link Checker
|
|
|
|
|
+
|
|
|
|
|
+on:
|
|
|
|
|
+ push:
|
|
|
|
|
+ branches: [ edge ]
|
|
|
|
|
+ pull_request:
|
|
|
|
|
+ branches: [ edge ]
|
|
|
|
|
+ schedule:
|
|
|
|
|
+ - cron: '30 12 1 * *'
|
|
|
|
|
+ workflow_dispatch:
|
|
|
|
|
+
|
|
|
|
|
+permissions:
|
|
|
|
|
+ contents: read
|
|
|
|
|
+
|
|
|
|
|
+concurrency:
|
|
|
|
|
+ group: link-checker-${{ github.ref }}
|
|
|
|
|
+ cancel-in-progress: false
|
|
|
|
|
+
|
|
|
|
|
+jobs:
|
|
|
|
|
+ linkChecker:
|
|
|
|
|
+ name: linkChecker
|
|
|
|
|
+ runs-on: ubuntu-26.04
|
|
|
|
|
+ steps:
|
|
|
|
|
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
|
|
|
+ with:
|
|
|
|
|
+ persist-credentials: false
|
|
|
|
|
+ fetch-depth: 0
|
|
|
|
|
+
|
|
|
|
|
+ # Check local links across the repository first to catch broken links in
|
|
|
|
|
+ # files that are not part of the PR's changed files.
|
|
|
|
|
+ - name: Check local links (offline run)
|
|
|
|
|
+ if: github.event_name == 'pull_request'
|
|
|
|
|
+ uses: lycheeverse/lychee-action@e7477775783ea5526144ba13e8db5eec57747ce8 # v2.9.0
|
|
|
|
|
+ with:
|
|
|
|
|
+ fail: true
|
|
|
|
|
+ failIfEmpty: false
|
|
|
|
|
+ args: >
|
|
|
|
|
+ --offline
|
|
|
|
|
+ .
|
|
|
|
|
+
|
|
|
|
|
+ - name: Get changed files
|
|
|
|
|
+ if: github.event_name == 'pull_request'
|
|
|
|
|
+ env:
|
|
|
|
|
+ BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
|
|
|
|
+ HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
|
|
|
|
+ run: |
|
|
|
|
|
+ git diff --name-only --diff-filter=ACMR \
|
|
|
|
|
+ "$BASE_SHA" \
|
|
|
|
|
+ "$HEAD_SHA" \
|
|
|
|
|
+ > changed-files.txt
|
|
|
|
|
+
|
|
|
|
|
+ # Lychee does not apply `extensions` from the config to files passed via `--files-from`.
|
|
|
|
|
+ # Filter the changed files so only allowed file types are checked.
|
|
|
|
|
+ python3 <<'PY'
|
|
|
|
|
+ import pathlib
|
|
|
|
|
+ import tomllib
|
|
|
|
|
+
|
|
|
|
|
+ with open("lychee.toml", "rb") as fp:
|
|
|
|
|
+ config = tomllib.load(fp)
|
|
|
|
|
+ extensions = {e.lstrip(".").lower() for e in config["extensions"]}
|
|
|
|
|
+
|
|
|
|
|
+ files = pathlib.Path("changed-files.txt").read_text().splitlines()
|
|
|
|
|
+ files = [
|
|
|
|
|
+ f for f in files
|
|
|
|
|
+ if (
|
|
|
|
|
+ pathlib.PurePath(f).suffix.lstrip(".").lower() in extensions
|
|
|
|
|
+ or (
|
|
|
|
|
+ not pathlib.PurePath(f).suffix
|
|
|
|
|
+ and pathlib.PurePath(f).name.startswith(".")
|
|
|
|
|
+ and pathlib.PurePath(f).name.lstrip(".").lower() in extensions
|
|
|
|
|
+ )
|
|
|
|
|
+ or (
|
|
|
|
|
+ not pathlib.PurePath(f).suffix
|
|
|
|
|
+ and not pathlib.PurePath(f).name.startswith(".")
|
|
|
|
|
+ and config.get("default_extension") in extensions
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
|
|
+ ]
|
|
|
|
|
+
|
|
|
|
|
+ pathlib.Path("changed-files.txt").write_text(
|
|
|
|
|
+ "\n".join(files) + ("\n" if files else "")
|
|
|
|
|
+ )
|
|
|
|
|
+ PY
|
|
|
|
|
+
|
|
|
|
|
+ - name: Restore lychee cache
|
|
|
|
|
+ id: restore-cache
|
|
|
|
|
+ uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
|
|
|
+ with:
|
|
|
|
|
+ path: .lycheecache
|
|
|
|
|
+ key: cache-lychee-${{ github.sha }}
|
|
|
|
|
+ restore-keys: cache-lychee-
|
|
|
|
|
+
|
|
|
|
|
+ - name: Run lychee
|
|
|
|
|
+ uses: lycheeverse/lychee-action@e7477775783ea5526144ba13e8db5eec57747ce8 # v2.9.0
|
|
|
|
|
+ with:
|
|
|
|
|
+ # PAT with read-only permissions used to avoid GitHub rate limits (allows 5,000 requests per hour)
|
|
|
|
|
+ # Won't be available to forks in pull requests due to restrictions, so falls back to default
|
|
|
|
|
+ # GITHUB_TOKEN with 1,000 requests per hour instead.
|
|
|
|
|
+ token: ${{ secrets.LYCHEE_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
|
|
|
|
+
|
|
|
|
|
+ fail: true
|
|
|
|
|
+ failIfEmpty: false # Avoid failing in PRs with no links in changed files (`true` is the default)
|
|
|
|
|
+
|
|
|
|
|
+ # Config is loaded from lychee.toml
|
|
|
|
|
+ args: >
|
|
|
|
|
+ ${{ github.event_name == 'pull_request' && '--files-from changed-files.txt' || '.' }}
|
|
|
|
|
+
|
|
|
|
|
+ - name: Save lychee cache
|
|
|
|
|
+ uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
|
|
|
+ if: always()
|
|
|
|
|
+ with:
|
|
|
|
|
+ path: .lycheecache
|
|
|
|
|
+ key: ${{ steps.restore-cache.outputs.cache-primary-key }}
|