Check for Dead Links #3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Check for Dead Links | |
| on: | |
| schedule: | |
| # Run every Sunday at 2 AM UTC | |
| - cron: '0 2 * * 0' | |
| workflow_dispatch: | |
| pull_request: | |
| paths: | |
| - '**.md' | |
| - 'mkdocs.yml' | |
| jobs: | |
| link-check: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Link Checker | |
| uses: lycheeverse/lychee-action@v2 | |
| with: | |
| # Check all markdown files | |
| args: > | |
| --verbose | |
| --no-progress | |
| --accept=200,201,202,203,204,301,302,303,307,308 | |
| --timeout 20 | |
| --max-retries 3 | |
| --user-agent "Mozilla/5.0 (compatible; pms-wiki-link-checker)" | |
| --exclude-private | |
| --exclude "^(?i:mailto)" | |
| --exclude "^(?i:javascript)" | |
| --exclude "github.com/.*/edit/" | |
| --exclude "github.com/.*/blob/" | |
| --exclude "localhost" | |
| --exclude "127.0.0.1" | |
| --exclude "example.com" | |
| --exclude "example.org" | |
| --exclude "plausible.ktz.cloud" | |
| --exclude "techhub.social" | |
| --exclude "reddit.com" | |
| --exclude "www.reddit.com" | |
| --exclude-path node_modules/ | |
| --exclude-path .git/ | |
| '**/*.md' | |
| fail: true | |
| format: markdown | |
| output: ./lychee-report.md | |
| jobSummary: true | |
| - name: Upload link check report | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: link-check-report | |
| path: lychee-report.md | |
| - name: Create actionable issue for broken links | |
| if: failure() && github.event_name == 'schedule' | |
| uses: actions/github-script@v7 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const fs = require('fs'); | |
| const report = fs.readFileSync('./lychee-report.md', 'utf8'); | |
| // Parse the lychee report to extract broken links | |
| const lines = report.split('\n'); | |
| const brokenLinks = []; | |
| let currentFile = ''; | |
| for (const line of lines) { | |
| // Match file paths in the report | |
| if (line.includes('.md') && !line.includes('|')) { | |
| currentFile = line.trim().replace(/^\*\*/, '').replace(/\*\*$/, ''); | |
| } | |
| // Match broken links | |
| if (line.includes('[') && line.includes('](') && line.includes('Failed')) { | |
| const match = line.match(/\[.*?\]\((.*?)\)/); | |
| if (match) { | |
| brokenLinks.push({ | |
| file: currentFile, | |
| url: match[1], | |
| line: line.trim() | |
| }); | |
| } | |
| } | |
| } | |
| const issueBody = `## Broken Links Detected | |
| The automated link checker found ${brokenLinks.length} broken link(s) in the documentation that need to be fixed. | |
| ### Instructions for fixing: | |
| Please update the following broken links in the documentation files. For each broken link, either: | |
| 1. Update the URL to the correct destination | |
| 2. Remove the link if it's no longer relevant | |
| 3. Replace with an archived version from Wayback Machine if appropriate | |
| ### Broken Links to Fix: | |
| ${brokenLinks.map((link, index) => | |
| `${index + 1}. **File:** \`${link.file}\` | |
| **Broken URL:** ${link.url} | |
| **Action:** Find this URL in the file and update or remove it | |
| `).join('\n')} | |
| ### Full Report: | |
| <details> | |
| <summary>Click to see the full lychee report</summary> | |
| \`\`\` | |
| ${report} | |
| \`\`\` | |
| </details> | |
| --- | |
| *This issue was automatically generated by the dead link checker workflow.*`; | |
| await github.rest.issues.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| title: `Fix ${brokenLinks.length} broken link(s) in documentation`, | |
| body: issueBody, | |
| labels: ['documentation', 'broken-links', 'automated', 'good first issue'] | |
| }); | |
| - name: Comment PR with link check results | |
| if: failure() && github.event_name == 'pull_request' | |
| uses: actions/github-script@v7 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const fs = require('fs'); | |
| const report = fs.readFileSync('./lychee-report.md', 'utf8'); | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: `## ❌ Dead Links Found\n\n${report}\n\nPlease fix these broken links before merging.` | |
| }); |