Skip to content

Introduce markdownlint-cli2 and verify docs build on PRs #717

@laughingman7743

Description

@laughingman7743

Summary

Introduce markdownlint-cli2 to lint Markdown files under docs/ (and project-root *.md files), and add a CI workflow that runs on PRs to:

  1. Lint Markdown with markdownlint-cli2.
  2. Build the Sphinx docs (make docs) to catch broken references, syntax errors, or other build failures before merge.

Currently the docs build only runs on push to master via .github/workflows/docs.yaml, so syntax or reference errors in docs PRs are only caught after merge.

Proposal

Tool: markdownlint-cli2

  • Node-based, no Python dev-deps impact.
  • Mature ruleset, widely used.
  • Config via .markdownlint-cli2.jsonc at repo root.

CI workflow: .github/workflows/docs-lint.yaml

Triggered on PRs only when docs change (the inverse of the test workflow's paths-ignore):

on:
  pull_request:
    paths:
      - 'docs/**'
      - '**.md'
      - '.github/workflows/docs-lint.yaml'

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@...
      - uses: DavidAnson/markdownlint-cli2-action@...
        with:
          globs: 'docs/**/*.md ./*.md'

  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@...
      - uses: astral-sh/setup-uv@...
      - run: uv sync --group dev && make docs

Scope of files

  • docs/**/*.md — primary target
  • Project root: README.md, CLAUDE.md — include if violations are minor
  • Exclude: docs/_build/**, .github/**/*.md (PR template etc.)

Initial config

Suggested rule overrides (to be discussed):

  • MD013 (line-length): disable, or set to ~120
  • MD033 (no inline HTML): allow specific tags used in MyST (<details>, <summary>)
  • MD041 (first line must be H1): keep enabled
  • MD024 (no duplicate headings): allow siblings_only since cursor docs reuse subsection names

Definition of Done

  • .markdownlint-cli2.jsonc committed with a reasonable ruleset.
  • Existing Markdown violations fixed (or explicitly ignored in config with rationale).
  • .github/workflows/docs-lint.yaml runs on docs-touching PRs and runs both lint + Sphinx build.
  • Documented in CLAUDE.md how to run markdownlint locally (e.g. npx markdownlint-cli2 'docs/**/*.md').

Notes

  • The test workflow's paths-ignore (added in PR docs: note Result Reuse semantic-equivalence behavior change (2025-11) #714) and this workflow's paths filter are deliberately complementary — one fires when the other doesn't.
  • Branch protection currently has no required status check contexts, so this won't immediately block merges. Once stable, we may want to mark docs-lint and docs-build as required for docs-only PRs.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions