fix(ci): make the link check actually check links - #12397
Conversation
`check:links` passed `--skip 'https?://'` to drop off-site links. linkinator applies skip rules to the absolute URL of everything it fetches, and when it is pointed at a directory it serves the build over HTTP and crawls it — so that unanchored rule matched its own crawl root. The command exited 0 having scanned zero links, and had been doing so on every pull request: the sidebar link to the deleted `/api/eventlogs` page shipped through a green link check that never requested a single URL. Anchor the rule and exclude the local server. Both of its hostnames have to be excluded, not just one: linkinator binds to `127.0.0.1` but builds its trailing-slash redirects against `localhost`, so covering only the bind address still skips nearly every page at the redirect hop. The check now crawls 1355 links. It finds no pre-existing breakage — with the previous commit in place the site is clean — and it fails on a reintroduced `/api/eventlogs`. Three supporting changes: - Move the settings into `linkinator.config.mjs`. The `.json` linkinator loads by default was already dead (CLI flags replace config wholesale, so its `skip` list, `^/api` included, never applied). `.mjs` also lets the rule carry the comment explaining the trap and be asserted in a unit test — the failure mode here is a check that silently stops checking, which no amount of green CI would reveal. - Crawl `/enterprise/` as a second entry point. Nothing outside that section links into it — it renders its own nav tree and is filtered out of the sitemap — so recursing from `/` alone reaches none of its eight pages and a broken link there would pass forever. - Lower the concurrency and enable `retryErrors`. Now that pages are actually fetched, linkinator's own static server drops an occasional connection, surfacing as a status-0 failure on a different file each run. `retryErrors` covers status 0, 5xx and 429 only — a 404 is never retried, so this costs nothing in strictness. Its count and jitter are left on the built-in defaults on purpose: meow declares defaults for both, so a value set in the config file would be silently overridden — the same class of dead config as the `.json` this replaces. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Change-Id: I8f9a56dc53b23c7a340b51b471c734298600fd7d
Member
Author
|
This pull request is part of a Mergify stack:
|
Contributor
Merge Protections🔴 3 of 7 protections blocking · waiting on 👀 reviews and ⛓️ dependency
🔴 ⛓️ Depends-On RequirementsWaiting for
This rule is failing.Requirement based on the presence of
🔴 👀 Review RequirementsWaiting for
This rule is failing.
🔴 🔎 ReviewsWaiting for
This rule is failing.
Show 4 satisfied protections🟢 🤖 Continuous Integration
🟢 Enforce conventional commitMake sure that we follow https://www.conventionalcommits.org/en/v1.0.0/
🟢 📕 PR description
🟢 🚦 Auto-queueWhen all merge protections are satisfied, this pull request will be queued automatically. |
sileht
marked this pull request as ready for review
August 15, 2026 20:58
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.
check:linkspassed--skip 'https?://'to drop off-site links. linkinatorapplies skip rules to the absolute URL of everything it fetches, and when it
is pointed at a directory it serves the build over HTTP and crawls it — so
that unanchored rule matched its own crawl root. The command exited 0 having
scanned zero links, and had been doing so on every pull request: the sidebar
link to the deleted
/api/eventlogspage shipped through a green link checkthat never requested a single URL.
Anchor the rule and exclude the local server. Both of its hostnames have to
be excluded, not just one: linkinator binds to
127.0.0.1but builds itstrailing-slash redirects against
localhost, so covering only the bindaddress still skips nearly every page at the redirect hop.
The check now crawls 1355 links. It finds no pre-existing breakage — with the
previous commit in place the site is clean — and it fails on a reintroduced
/api/eventlogs.Three supporting changes:
linkinator.config.mjs. The.jsonlinkinator loadsby default was already dead (CLI flags replace config wholesale, so its
skiplist,^/apiincluded, never applied)..mjsalso lets the rulecarry the comment explaining the trap and be asserted in a unit test — the
failure mode here is a check that silently stops checking, which no amount
of green CI would reveal.
/enterprise/as a second entry point. Nothing outside that sectionlinks into it — it renders its own nav tree and is filtered out of the
sitemap — so recursing from
/alone reaches none of its eight pages and abroken link there would pass forever.
retryErrors. Now that pages are actuallyfetched, linkinator's own static server drops an occasional connection,
surfacing as a status-0 failure on a different file each run.
retryErrorscovers status 0, 5xx and 429 only — a 404 is never retried, so this costs
nothing in strictness. Its count and jitter are left on the built-in
defaults on purpose: meow declares defaults for both, so a value set in the
config file would be silently overridden — the same class of dead config as
the
.jsonthis replaces.Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com
Depends-On: #12396