CI: anchor-integrity guard for in-page #fragment links - #73
Merged
Conversation
Add scripts/check_anchors.py: for every built HTML page in output/, resolve every internal link carrying a #fragment (same-page href="#id", cross-page href="post.html#id", and SITEURL-absolute href="https://rivassec.com/post.html#id") to its destination doc and assert an element with that id (or legacy name=) exists. Reports each unresolved fragment as a GitHub ::error annotation, exits 1 on any violation. This is a class lychee does not check: lychee verifies the linked page 200s, not that the fragment lands on a real element. External hosts, href="#" alone, query-only links, and fragments to pages not built in output/ (link rot, lychee's job) are ignored. Add tests/test_check_anchors.py (stdlib unittest, discover-compatible) and .github/workflows/anchor-check.yml (mirrors link-graph-check.yml).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a CI guard that catches broken in-page anchor links (
#fragmenttargets) in the built site - a class lychee (link-rot.yml) does not check. lychee verifies a linked page 200s; it does not verify the URL fragment lands on a real element. When a heading is renamed the anchor silently rots: the link still resolves, it just jumps to the top of the page.How
scripts/check_anchors.py: for every built HTML page inoutput/, resolves every internal link carrying a#fragmentand asserts a matchingid(or legacyname=) exists on the destination doc.href="#id"href="post.html#id"(document- and root-relative)href="https://rivassec.com/post.html#id"href="#"alone, query-only links, and fragments to pages not built inoutput/(missing pages are link rot, lychee's lane).::error file=...::annotations, exits 1 on any violation, one-line summary to stderr. Builds the site first (pelican content -o output -s publishconf.py, module-form fallback), matching the house style ofcheck_canonical_noindex.py/check_link_graph.py.tests/test_check_anchors.py: stdlib unittest,python3 -m unittest discover tests-compatible, fixture HTML trees covering valid/broken same-page and cross-page fragments plus the ignore rules..github/workflows/anchor-check.yml: push-to-main + pull_request + workflow_dispatch, mirroringlink-graph-check.yml.Pre-existing broken anchors
None. Ran against a real build of the current site: 117 pages, 457 fragment links checked, 0 broken. The guard passes clean on
maincontent.Tests
python3 -m unittest discover tests- all 38 tests pass (26 existing + 12 new).