Lock file maintenance #491
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
| # .github/workflows/check-links.yml | |
| --- | |
| name: Check Links | |
| # Manual testing commands (requires lychee installed): | |
| # | |
| # Internal links check: | |
| # lychee --no-progress --offline --root-dir "$(pwd)/src/content/docs" --fallback-extensions md,mdoc './src/**/*.md' './src/**/*.mdoc' | |
| # | |
| # External links check: | |
| # lychee --no-progress --max-concurrency 8 --timeout 20 --max-retries 3 \ | |
| # --exclude-path ./CHANGELOG.md --accept 200,204,206,301,302,429 \ | |
| # './src/**/*.md' './src/**/*.mdoc' | |
| # | |
| # Note: Static asset paths (/img/*, /socialcards/*) are excluded via .lycheeignore | |
| # since they live in public/, not in the content directory. | |
| # | |
| # Install lychee: https://github.com/lycheeverse/lychee#installation | |
| on: | |
| # Run on PRs to catch issues before merge | |
| pull_request: | |
| branches: [main] | |
| # Run on push to main to catch any issues | |
| push: | |
| branches: [main] | |
| # Run weekly to catch external link rot | |
| schedule: | |
| - cron: "0 0 * * 0" # Every Sunday at midnight UTC | |
| # Allow manual trigger | |
| workflow_dispatch: | |
| inputs: | |
| check_external: | |
| description: "Check external links (slower)" | |
| required: false | |
| default: true | |
| type: boolean | |
| permissions: | |
| contents: read | |
| issues: write | |
| jobs: | |
| check-internal-links: | |
| name: Check Internal Links | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Check internal links with Lychee | |
| uses: lycheeverse/lychee-action@v2 | |
| with: | |
| # Only check markdown files for internal links | |
| # --root-dir resolves root-relative paths (e.g. /en/regions/) | |
| # --fallback-extensions resolves directory links to index.md files | |
| args: >- | |
| --no-progress | |
| --offline | |
| --root-dir ${{ github.workspace }}/src/content/docs | |
| --fallback-extensions md,mdoc | |
| './src/**/*.md' | |
| './src/**/*.mdoc' | |
| fail: true | |
| - name: Create Issue if internal links are broken | |
| if: failure() && github.event_name == 'schedule' | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| github.rest.issues.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| title: '🔗 Broken Internal Links Detected', | |
| body: 'Automated link checking found broken internal links. Please check the workflow run for details:\n\n' + | |
| `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`, | |
| labels: ['documentation', 'bug', 'automated'] | |
| }) | |
| check-external-links: | |
| name: Check External Links | |
| runs-on: ubuntu-latest | |
| # Only run external checks on schedule or manual trigger | |
| if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Check external links with HEAD method | |
| id: lychee-head | |
| uses: lycheeverse/lychee-action@v2 | |
| with: | |
| args: >- | |
| --no-progress | |
| --max-concurrency 8 | |
| --timeout 20 | |
| --max-retries 3 | |
| --method head | |
| --exclude-path ./CHANGELOG.md | |
| --accept 200,204,206,301,302,429 | |
| './src/**/*.md' | |
| './src/**/*.mdoc' | |
| output: ./lychee-head.md | |
| fail: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Retry failures with GET method | |
| id: lychee-get | |
| if: steps.lychee-head.outputs.exit_code != 0 | |
| uses: lycheeverse/lychee-action@v2 | |
| with: | |
| args: >- | |
| --no-progress | |
| --max-concurrency 8 | |
| --timeout 20 | |
| --max-retries 3 | |
| --method get | |
| --exclude-path ./CHANGELOG.md | |
| --accept 200,204,206,301,302,429 | |
| './src/**/*.md' | |
| './src/**/*.mdoc' | |
| output: ./lychee-get.md | |
| fail: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Generate link check report | |
| if: always() | |
| run: | | |
| echo "## Link Check Report" >> $GITHUB_STEP_SUMMARY | |
| if [ -f lychee-head.md ]; then | |
| echo "### HEAD Method Results" >> $GITHUB_STEP_SUMMARY | |
| cat lychee-head.md >> $GITHUB_STEP_SUMMARY | |
| fi | |
| if [ -f lychee-get.md ]; then | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### GET Method Retry Results" >> $GITHUB_STEP_SUMMARY | |
| cat lychee-get.md >> $GITHUB_STEP_SUMMARY | |
| fi | |
| - name: Create Issue if external links are broken | |
| if: failure() && github.event_name == 'schedule' | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| github.rest.issues.create({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| title: '🔗 Broken External Links Detected', | |
| body: 'Automated weekly link checking found broken external links. Please review:\n\n' + | |
| `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}\n\n` + | |
| '**Note:** Some external link failures may be temporary (rate limiting, timeouts, etc.). ' + | |
| 'Please verify before fixing.', | |
| labels: ['documentation', 'external-links', 'automated'] | |
| }) |