Skip to content

Add check-links PR check - #1858

Open
marcleblanc2 wants to merge 7 commits into
mainfrom
check-links-pr-check
Open

Add check-links PR check#1858
marcleblanc2 wants to merge 7 commits into
mainfrom
check-links-pr-check

Conversation

@marcleblanc2

@marcleblanc2 marcleblanc2 commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Problem

  • Our docs site has hundreds of broken links
  • dev/check-links.mjs can find broken internal links and anchors, but nothing runs it, so PRs regularly break links (renaming a heading, moving or deleting a page) without anyone noticing

Solution

A pull_request workflow that reports only the breakage a PR introduces, and comments on the PR when there is any.

It runs the checker (with --check-anchors) on both the PR head and its merge base, and diffs the findings. That catches both directions:

  • Outbound: a changed page links to a page or #heading that doesn't exist
  • Inbound: the PR renames a heading or removes/moves a page that other, unchanged pages link to — those show up as findings in files the PR didn't touch

Pre-existing broken links on main are ignored, so the check is green today and only fails when a PR makes things worse. The comment is created or updated in place (one comment per PR), and once the PR is fixed it is updated to say so. A PR that never broke anything gets no comment. Fork PRs get a read-only token, so for those the report is only in the job log.

Changes to dev/check-links.mjs

  • --root <dir>: check another checkout (used for the merge base)
  • --format text|json|markdown: json for the baseline, markdown for the PR comment
  • --baseline <file>: report only findings absent from a previous json run
  • Case-mismatch detection: /Code-Search/foo when the route is /code-search/foo, or /Img/Foo.png when the file is public/img/foo.png — resolves on macOS, 404s on the Linux build. Assets under public/ and docs/ are enumerated into a map for this, replacing fs.existsSync (which is case-insensitive on macOS).
  • Scans *.md as well as *.mdx for outbound links. Only .mdx files count as valid routes, matching filePathPattern in contentlayer.config.ts, so a link to a .md file is reported as a missing page.
  • Removes 132 false positives by accepting explicit <a name="…"> / id="…" attributes as anchor targets, as used by the generated admin/telemetry/protocol.mdx file

Verification

Local simulation of a PR that renames ## Search contexts in code-search/features.mdx, deletes admin/telemetry/protocol.mdx, adds bad outbound links and a case-mismatched link, and adds a .md file with a broken link. The report listed exactly those 12 new findings (4 inbound-anchor, 3 inbound-page, 4 outbound, 1 in the .md) and none of the 431 pre-existing ones.

Also actionlint, prettier --check on the workflow, and bash -n on each step.

Related

  • Draft PR Add daily broken link checker with Slack reporting #1562 proposes a daily Slack digest with a separate reimplementation of this script; instead, this PR improves on the existing script, and gates PRs
  • Follow-up coming in a separate PR soon: the live site returns HTTP 200 for missing pages, so external link checkers can't see broken pages

Add a pull_request workflow that runs dev/check-links.mjs --check-anchors
on both the PR head and its merge base, and reports only the findings the
PR introduces: outbound links from changed pages, and inbound links from
other pages to a page or heading the PR removed or renamed. Pre-existing
broken anchors on main are ignored. The job comments on the PR and fails
when new breakage is found.

dev/check-links.mjs gains --root, --format (text|json|markdown) and
--baseline to support that diff, plus case-mismatch detection for routes
(links that resolve on macOS but 404 on Linux) and scanning of *.md files.
Only *.mdx files count as routes, matching contentlayer's filePathPattern.

Amp-Thread-ID: https://ampcode.com/threads/T-01a0753f-0f4f-7478-b36c-87466e7c0261
Co-authored-by: Amp <amp@ampcode.com>
@vercel

vercel Bot commented Sep 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
sourcegraph-docs Ready Ready Preview Sep 6, 2026 7:45am UTC

Request Review

@marcleblanc2 marcleblanc2 changed the title ci: comment on PRs that break internal links or anchors Add check-links PR check Sep 6, 2026
Generated pages such as admin/telemetry/protocol.mdx define anchors with
<a name="..."> rather than headings. Drops 132 false positives on main
(431 -> 299 with --check-anchors).

Amp-Thread-ID: https://ampcode.com/threads/T-01a0753f-0f4f-7478-b36c-87466e7c0261
Co-authored-by: Amp <amp@ampcode.com>
Replace the fs.existsSync asset checks (case-insensitive on macOS, so they
hid links that 404 on the Linux build) with an enumerated lowercase -> real
path map of files under public/ and docs/, mirroring the route check.

Also register docs/index.mdx as the / route. It was never in the path map
(the /index strip needed a leading slash), and existsSync('public/') was
masking that by accepting any '/' link. Six pre-existing broken /#anchor
links on the homepage are now reported.

Amp-Thread-ID: https://ampcode.com/threads/T-01a07597-43c0-751b-8c49-6e5809e714d2
Co-authored-by: Amp <amp@ampcode.com>
A green run posts nothing. If an earlier run left a report and the PR has
since been fixed, delete that comment instead of editing it to a checkmark.

Amp-Thread-ID: https://ampcode.com/threads/T-01a07597-43c0-751b-8c49-6e5809e714d2
Co-authored-by: Amp <amp@ampcode.com>
The checkmark comment only ever appears after an earlier run reported
breakage, so word it that way instead of "introduces no broken links".
Keeps the comment (reverts the delete from the previous commit).

Amp-Thread-ID: https://ampcode.com/threads/T-01a07597-43c0-751b-8c49-6e5809e714d2
Co-authored-by: Amp <amp@ampcode.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant