Skip to content

ci: add advisory external-link checker for docs and root prose#653

Merged
DavidCozens merged 3 commits into
mainfrom
ci/docs-external-link-checker
Jul 20, 2026
Merged

ci: add advisory external-link checker for docs and root prose#653
DavidCozens merged 3 commits into
mainfrom
ci/docs-external-link-checker

Conversation

@DavidCozens

@DavidCozens DavidCozens commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Purpose

Implements #626 (S23.15, epic #246) and item 7 of the 0.1.0 milestone. Nothing
currently validates external https:// URLs in the docs — mkdocs build --strict only resolves in-repo links and the source_links.py rewrites — so a
dead third-party link merges silently and rots. This is not hypothetical: a
FreeRTOS-Plus-FAT 404 sat on main until found by chance.

Change Description

New docs-links workflow (separate from ci.yml) running lychee over
docs/ plus the repo-root prose (README, CONTRIBUTING, CODE_OF_CONDUCT,
SECURITY, SUPPORT):

  • Advisory on PRs (fail: false) and intentionally not a required
    status check — a merge must not fail because someone else's docs host had a
    bad minute.
  • Blocking on the weekly schedule (fail: true, Mondays 06:17 UTC) so link
    rot that appears without us touching a file surfaces as a failed run — the
    exact way the Plus-FAT 404 slipped in. Plus workflow_dispatch for manual
    runs.
  • Retries with backoff, a real user agent, accept 429 — a timeout is not a
    404 (config in lychee.toml).
  • Scope decision: own-repo github.com/cososo-ltd/solid-syslog self-links
    are excluded — the strict build already resolves the ~99 source_links.py
    links pre-rewrite. Known suspects are left in scope so the run gives a
    verdict.
  • Separate workflow (not a job in ci.yml) so the weekly cron doesn't drag the
    whole CI suite along.

Action pinned by SHA (lychee-action v2.9.0), per repo convention.

Test Evidence

  • Workflow YAML and lychee.toml validated as well-formed.
  • The lane's path filter includes its own files, so it self-runs on this PR.
  • Pre-checked the issue's known suspect: http(s)://elm-chan.org/fsw/ff/ now
    returns 200
    on both schemes (it was refusing 443 / silent on 80 when
    added) — that concern is cleared.

Areas Affected

.github/workflows/docs-links.yml and lychee.toml only. No source, build, or
existing-CI changes. New check is advisory (not in the required-checks set), so
branch protection is unchanged.

Follow-ups (noted, out of scope)

  • Anchors (validation.links.anchors: info in mkdocs.yml): a broken
    internal #fragment still passes the strict build silently. A different
    mechanism (checking the built site's HTML); worth a separate story.
  • Promote this lane to a required check only once it proves stable.

Closes #626

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added automated documentation link checking on pull requests, with weekly scheduled runs and manual triggering.
    • Introduced a link-checking configuration for external HTTP/HTTPS URL liveness with retry handling.
  • Chores
    • Scoped checks to relevant documentation and Markdown files, with non-blocking results for PR/manual runs while scheduled runs enforce outcomes.
  • Documentation
    • Corrected external documentation link paths in the Mbed TLS integration guide.
    • Updated the cosign installation link in the release verification documentation.

`mkdocs build --strict` validates in-repo links and the source_links.py
rewrites but never checks external https URLs, so a dead third-party link
merges silently and rots (#626: a FreeRTOS-Plus-FAT 404 sat on main until
found by chance).

Adds a separate `docs-links` workflow running lychee over docs/ plus the
repo-root prose files:

- Advisory on pull requests (fail: false) and not a required status check —
  a merge must not fail because someone else's host had a bad minute.
- Blocking on the weekly schedule (fail: true) so link rot that appears
  without us touching a file surfaces as a failed run.
- Retries with backoff, a real user agent, and accept 429 (see lychee.toml).
- Own-repo github.com self-links excluded (already covered by the strict
  build); known suspects left in scope so the run gives a verdict.

Separate workflow (not a job in ci.yml) so the weekly cron doesn't drag the
whole CI suite along.

Closes #626

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3d898922-d0ae-4fb3-a8fa-3cb22518a34b

📥 Commits

Reviewing files that changed from the base of the PR and between 3bc8a7d and d4b31ec.

📒 Files selected for processing (2)
  • .github/workflows/docs-links.yml
  • lychee.toml

Walkthrough

Adds a GitHub Actions lane that checks external documentation links on pull requests, weekly, and manually. Lychee configuration defines retries, timeouts, accepted responses, HTTP(S) scope, and repository self-link exclusions. Two documentation URLs are corrected.

Changes

External documentation links

Layer / File(s) Summary
Lychee checking policy
lychee.toml
Defines external URL scope, retry and timeout behaviour, user-agent handling, accepted HTTP statuses, repository self-link exclusions, and first-run suspect URL reporting.
Documentation link CI lane
.github/workflows/docs-links.yml
Runs lychee against docs and selected root Markdown files on pull requests, weekly schedules, and manual dispatches; only scheduled runs fail on checker errors.
Documentation link corrections
docs/integrating-mbedtls.md, docs/security/release-verification.md
Updates the Mbed TLS porting guide and cosign installation URLs to their revised paths.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GitHubActions
  participant Repository
  participant LycheeAction
  participant ExternalDocumentationHosts
  GitHubActions->>Repository: checkout documentation sources
  GitHubActions->>LycheeAction: check docs and root Markdown files with lychee.toml
  LycheeAction->>ExternalDocumentationHosts: request external HTTP(S) URLs
  ExternalDocumentationHosts-->>LycheeAction: return HTTP status results
  LycheeAction-->>GitHubActions: report link-check outcome
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise, conventional, and accurately names the new advisory external-link checker for docs and root prose.
Description check ✅ Passed All required sections are present and the content explains purpose, changes, tests, and affected areas clearly enough.
Linked Issues check ✅ Passed The PR meets #626: it adds a non-blocking docs-link lane, schedules it weekly, retries, uses a user agent, scopes docs and root prose, and verifies FatFs.
Out of Scope Changes check ✅ Passed The extra workflow config and doc link fixes are directly tied to the new link-checking lane, with no unrelated changes evident.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/docs-external-link-checker

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/docs-links.yml:
- Around line 19-30: Add workflow-level concurrency to the docs link-check
workflow, using a shared group keyed by the workflow and ref so pull_request,
workflow_dispatch, and scheduled runs are serialized. Configure cancellation of
in-progress runs only for pull_request events, while allowing scheduled and
manual runs to finish.
- Around line 45-59: Update the lychee-action configuration in the docs-links
workflow to set failIfEmpty to the same schedule-based guard as fail, so empty
PR and manual scans remain non-blocking while scheduled scans still fail when
empty.

In `@lychee.toml`:
- Line 24: Update the self-repository exclusion regex in the configuration to
require a repository boundary after “solid-syslog,” such as a slash, query,
fragment, or end of string. Preserve matching for the intended repository while
preventing matches for names like “solid-syslog-extra.”
- Line 14: Update the lychee `accept` configuration to accept the full
successful HTTP status range from 200 through 299 while retaining 429 as
accepted.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: eeaab043-2eff-492d-b9c2-dc9c0deb6bcf

📥 Commits

Reviewing files that changed from the base of the PR and between 37bb09e and 31b598d.

📒 Files selected for processing (2)
  • .github/workflows/docs-links.yml
  • lychee.toml

Comment thread .github/workflows/docs-links.yml
Comment thread .github/workflows/docs-links.yml
Comment thread lychee.toml Outdated
Comment thread lychee.toml Outdated
DavidCozens and others added 2 commits July 20, 2026 20:44
The docs-links lane's first run flagged two 404s:

- integrating-mbedtls.md: the Mbed TLS porting KB page moved to an
  uppercase `-OS/` slug (casing-only change upstream).
- security/release-verification.md: the sigstore cosign install page moved
  under a `/cosign/` path prefix.

Both replacements verified 200.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Add workflow-level concurrency (cancel superseded pull_request runs only) so
  PR, manual, and weekly runs don't overlap and burn external crawl quota.
- Set failIfEmpty to the same schedule guard as fail — v2.9.0 defaults it to
  true, so an empty scan must not fail a PR or manual run.
- Widen accept to 200..=299 (any 2xx is success, not just 200..=206).
- Bound the self-repo exclusion regex with (?:[/?#]|$) so it can't also match
  a hypothetical solid-syslog-extra.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   JUnit   build-linux-gcc (Whole Project): ✅ successful — 1524 passed
   JUnit   build-freertos-host-tdd-plustcp (Whole Project): ✅ successful — 1876 passed
   JUnit   build-linux-clang (Whole Project): ✅ successful — 1455 passed
   JUnit   sanitize-linux-gcc (Whole Project): ✅ successful — 1455 passed
   JUnit   integration-linux-openssl (Whole Project): ✅ successful — 16 passed
   JUnit   integration-linux-mbedtls (Whole Project): ✅ successful — 14 passed
   JUnit   integration-windows-openssl (Whole Project): ✅ successful — 16 passed
   JUnit   bdd-linux-syslog-ng (Whole Project): ✅ successful — 49 passed, 3 skipped
   JUnit   bdd-windows-otel (Whole Project): ✅ successful — 46 passed, 6 skipped
   JUnit   bdd-freertos-qemu-plustcp (Whole Project): ✅ successful — 45 passed, 7 skipped
   JUnit   bdd-freertos-qemu-lwip (Whole Project): ✅ successful — 45 passed, 7 skipped
   JUnit   build-windows-msvc (Whole Project): ✅ successful — 1300 passed
   JUnit   build-linux-tunable-override (Whole Project): ✅ successful — 1455 passed
   ⚠️   Clang-Tidy (Whole Project): No warnings
   ⚠️   CPPCheck (Whole Project): No warnings


Created by Quality Monitor v4.15.0 (#82d77af). More details are shown in the GitHub Checks Result.

@DavidCozens
DavidCozens merged commit 37aaec0 into main Jul 20, 2026
31 checks passed
@DavidCozens
DavidCozens deleted the ci/docs-external-link-checker branch July 20, 2026 21:07
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.

S23.15: External link checker CI lane

1 participant