Skip to content

Commit c7d8ca0

Browse files
oschwaldclaude
andcommitted
Add lychee link checker config and CI workflow
Adds a lychee configuration and a Links GitHub Actions workflow so that stale or redirecting links are caught automatically going forward. The checker runs on push, pull request, and weekly to catch external link rot. max_redirects is 0 so links that have moved are surfaced and can be updated to their canonical destination. The configured globs cover Markdown docs plus C sources and headers, which is where links appear in this repository. Vendored submodules (maxmind-db, t/libtap), the test harness under t/, build/generated directories, the Hugo site output, and the Changes.md changelog are excluded. Part of STF-557. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 0776342 commit c7d8ca0

5 files changed

Lines changed: 126 additions & 0 deletions

File tree

.github/workflows/links.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Links
2+
3+
on:
4+
push:
5+
pull_request:
6+
schedule:
7+
- cron: "0 13 * * 1" # weekly, to catch external link rot without a commit
8+
workflow_dispatch:
9+
10+
permissions:
11+
contents: read
12+
13+
jobs:
14+
linkChecker:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
18+
with:
19+
persist-credentials: false
20+
21+
- name: Setup mise
22+
uses: jdx/mise-action@6d1e696aa24c1aa1bcc1adea0212707c71ab78a8 # v3.6.1
23+
with:
24+
install: false
25+
26+
# Install only lychee (not the repo's full toolchain) and run the check.
27+
- name: Check links
28+
env:
29+
MISE_AUTO_INSTALL: "false"
30+
run: |
31+
mise install lychee
32+
mise run check-links

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,4 @@ Makefile.in
4646
Testing/
4747
install_manifest.txt
4848
build/
49+
.lycheecache

lychee.toml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Lychee link checker configuration
2+
# https://lychee.cli.rs/#/usage/config
3+
#
4+
# Run locally with:
5+
# lychee './**/*.md' './src/**/*.c' './include/**/*.h'
6+
7+
# Include URL fragments in checks
8+
include_fragments = true
9+
10+
# Don't allow any redirects, so links that have moved are surfaced and updated
11+
# to their canonical destination.
12+
max_redirects = 0
13+
14+
# Accept these HTTP status codes
15+
# 100-103: Informational responses
16+
# 200-299: Success responses
17+
# 403: Forbidden (some sites use this for rate limiting)
18+
# 429: Too Many Requests
19+
# 500-599: Server errors (temporary issues shouldn't fail CI)
20+
# 999: LinkedIn's custom status code
21+
accept = ["100..=103", "200..=299", "403", "429", "500..=599", "999"]
22+
23+
# Exclude URL patterns from checking (treated as regular expressions)
24+
exclude = [
25+
# Local / template file URLs (e.g. Hugo layout placeholders)
26+
'^file://',
27+
# Live / auth-gated endpoints that require login or are queried at runtime
28+
'^https://geoip\.maxmind\.com',
29+
'^https://geolite\.info',
30+
'^https://updates\.maxmind\.com',
31+
'^https://www\.maxmind\.com/en/accounts/',
32+
# Placeholders / local
33+
'^https?://example\.(com|org|net)',
34+
'^http://localhost',
35+
'127\.0\.0\.1',
36+
]
37+
38+
# Exclude file paths from getting checked (treated as regular expressions)
39+
exclude_path = [
40+
'(^|/)\.git/',
41+
# Build / generated directories
42+
'(^|/)build/',
43+
'(^|/)\.libs/',
44+
'(^|/)autom4te\.cache/',
45+
'(^|/)generated/',
46+
# Generated Hugo site output
47+
'(^|/)docs/public/',
48+
# Vendored submodules and test harness/fixtures
49+
'(^|/)maxmind-db/',
50+
'(^|/)t/',
51+
# Changelog: historical entries are preserved as-is, not rewritten
52+
'(^|/)Changes\.md$',
53+
]
54+
55+
# Cache results for 1 day to speed up repeated checks
56+
cache = true
57+
max_cache_age = "1d"
58+
59+
# Skip missing input files instead of erroring
60+
skip_missing = true

mise.lock

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mise.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ disable_backends = [
99

1010
[tools]
1111
hugo = "latest"
12+
lychee = "0.23.0"
1213
node = "latest"
1314
"pipx:clang-format" = "21.1.8"
1415
"github:houseabsolute/precious" = "latest"
@@ -21,3 +22,7 @@ run = "hugo --source docs --minify"
2122
[tasks.serve-docs]
2223
description = "Serve the docs site locally with Hugo dev server"
2324
run = "hugo server --source docs"
25+
26+
[tasks.check-links]
27+
description = "Check links with lychee"
28+
run = "lychee --no-progress './**/*.md' './src/**/*.c' './include/**/*.h'"

0 commit comments

Comments
 (0)