diff --git a/.github/workflows/doc-link-validation.yml b/.github/workflows/doc-link-validation.yml new file mode 100644 index 00000000..35ffc1f7 --- /dev/null +++ b/.github/workflows/doc-link-validation.yml @@ -0,0 +1,39 @@ +name: Documentation Link Validation + +on: + pull_request: + paths: + - "**.md" + - "docs/**" + - "scripts/check-doc-links.py" + push: + branches: [main] + paths: + - "**.md" + - "docs/**" + workflow_dispatch: + +concurrency: + group: doc-links-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + validate-links: + name: check-markdown-links + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Run Documentation Link Validator + run: | + python3 scripts/check-doc-links.py --warn-only diff --git a/docs/DOC_LINK_VALIDATION.md b/docs/DOC_LINK_VALIDATION.md new file mode 100644 index 00000000..60aff61f --- /dev/null +++ b/docs/DOC_LINK_VALIDATION.md @@ -0,0 +1,35 @@ +# šŸ”— Documentation Link Validation Policy & Workflow + +This document describes the automated documentation link checking system implemented for NotifyChain (Issue #720). + +--- + +## 1. Motivation + +NotifyChain has a rich documentation tree across smart contracts, listener services, and dashboard components. When files are moved or refactored, relative links in markdown documentation can silently break, degrading contributor experience. + +--- + +## 2. Automated Validation in CI + +The workflow [`.github/workflows/doc-link-validation.yml`](../.github/workflows/doc-link-validation.yml) automatically triggers whenever pull requests modify `.md` files or documentation scripts. + +### Link Verification Policy: +1. **Internal Relative Links**: Checked against the repository filesystem. +2. **Anchor Links (`#section`)**: Base paths are verified. +3. **External URLs (`http://`, `https://`, `mailto:`)**: Safely ignored by default to prevent flaky CI failures caused by external site downtimes or network rate limits. +4. **Code Blocks**: Fenced code blocks and backtick expressions are stripped to avoid false positive matches on code syntax. + +--- + +## 3. Running Locally + +Developers can run the validator locally before submitting a PR: + +```bash +# Run standard link check +python3 scripts/check-doc-links.py + +# Run in warn-only mode (non-zero exit on warnings suppressed) +python3 scripts/check-doc-links.py --warn-only +``` diff --git a/scripts/check-doc-links.py b/scripts/check-doc-links.py new file mode 100755 index 00000000..d8c79a25 --- /dev/null +++ b/scripts/check-doc-links.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 +""" +NotifyChain Documentation Link Validator (Issue #720) + +Scans all Markdown files (.md) across the repository to validate internal relative links, +ensuring zero broken references while safely excluding or warn-logging external URLs +to prevent fragile CI failures. +""" + +import os +import re +import sys +import argparse +from pathlib import Path +from urllib.parse import unquote + +# Regex to find markdown links: [text](target) +LINK_PATTERN = re.compile(r'(? Missing") + if len(broken) > 20: + print(f" ... and {len(broken) - 20} more broken links.") + + if args.warn_only: + print("\nāš ļø Exiting with success (warn-only mode enabled).") + sys.exit(0) + else: + print("\nāŒ Please fix broken relative links above or run with --warn-only.") + sys.exit(1) + else: + print("āœ… All internal documentation links are valid!") + sys.exit(0) + +if __name__ == '__main__': + main()