Skip to content

ci: add markdown link checker for docs and README #552

@cv

Description

@cv

Summary

Add a CI check that validates relative links in markdown files, catching broken cross-references before they are merged.

Motivation

With many contributors submitting documentation PRs — and files being moved or renamed — broken relative links accumulate quickly. These are invisible until a user clicks them. An automated check catches them at PR time with zero reviewer effort.

Specification

Add a CI step that scans markdown files changed in a PR and verifies that all relative links point to files that exist in the repository.

What to check

  • Standard markdown links: [text](relative/path.md)
  • Image references: ![alt](relative/path.png)
  • MyST cross-references if applicable (e.g., {doc}\path``)

What to skip

  • External URLs (https://..., http://...) — these require network access and are a separate concern
  • Anchor-only links (#section-heading)
  • Links inside fenced code blocks (```)
  • node_modules/, dist/, and other non-documentation paths

Behavior

  • Run on pull_request events (opened, synchronize).
  • Scan all .md files in the PR diff.
  • For each relative link, resolve it relative to the file's directory and check that the target exists in the repo.
  • On failure, print each broken link with the source file, line number, and target path.

Implementation notes

  • A simple approach: a shell or Python script that uses regex to extract [...](...) patterns, filters to relative paths, and checks file existence with test -f.
  • Be careful with links that include anchors (e.g., ./setup.md#prerequisites) — strip the #... suffix before checking file existence.
  • The docs/ directory uses Sphinx/MyST, so also consider paths with or without .md extensions depending on how cross-references are written.
  • Alternatively, markdown-link-check is a popular npm tool, but a custom script avoids adding a dependency and can be tailored to the repo's conventions.

Acceptance criteria

  • CI fails when a PR introduces a broken relative link in a markdown file.
  • Error output shows the source file, line number, and broken target path.
  • External URLs, anchors, and code blocks are not false positives.
  • Works for files in docs/, README.md, and CONTRIBUTING.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: ciCI workflows, checks, release automation, or GitHub Actionsarea: e2eEnd-to-end tests, nightly failures, or validation infrastructure
    No fields configured for Enhancement.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions