name: Broken Links Report on: schedule: # Run every Saturday at 2 AM UTC - cron: "0 2 * * 6" workflow_dispatch: jobs: check-links: runs-on: ubuntu-latest permissions: contents: read issues: write steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # ratchet:actions/checkout@v5.0.0 - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # ratchet:actions/setup-node@v5.0.0 with: node-version: lts/* - uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # ratchet:actions/cache@v4.3.0 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-node- - name: Install Dependencies run: npm ci --ignore-scripts --no-audit --no-progress --prefer-offline - name: Run Link Check id: link_check run: | npm test > link_check_output.txt 2>&1 || true if grep -q "❌ ERROR" link_check_output.txt; then echo "has_errors=true" >> $GITHUB_OUTPUT else echo "has_errors=false" >> $GITHUB_OUTPUT fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Create/Update Issue for Broken Links if: steps.link_check.outputs.has_errors == 'true' uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # ratchet:actions/github-script@v8 with: script: | const fs = require('fs'); const output = fs.readFileSync('link_check_output.txt', 'utf8'); // Extract error information const errorMatch = output.match(/❌ ERROR[\s\S]*$/); const errorInfo = errorMatch ? errorMatch[0] : 'Link check failed - see workflow logs'; const issueBody = `# 🔗 Broken Links Detected The weekly link check has found broken or inaccessible links in the repository. ## Error Details \`\`\` ${errorInfo} \`\`\` ## Action Required Please review and fix the broken links above. Options: - Update the URL if the resource moved - Remove the entry if it's permanently unavailable - Add to \`tests/exclude_in_test.json\` if it's a known false positive --- *Auto-generated by [broken_links.yml](https://github.com/veggiemonk/awesome-docker/blob/master/.github/workflows/broken_links.yml)* `; // Check for existing issue const issues = await github.rest.issues.listForRepo({ owner: context.repo.owner, repo: context.repo.repo, state: 'open', labels: 'broken-links', per_page: 1 }); if (issues.data.length > 0) { await github.rest.issues.update({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issues.data[0].number, body: issueBody }); console.log(`Updated issue #${issues.data[0].number}`); } else { const issue = await github.rest.issues.create({ owner: context.repo.owner, repo: context.repo.repo, title: '🔗 Broken Links Detected - Action Required', body: issueBody, labels: ['broken-links', 'bug'] }); console.log(`Created issue #${issue.data.number}`); } - name: Close Issue if No Errors if: steps.link_check.outputs.has_errors == 'false' uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # ratchet:actions/github-script@v8 with: script: | const issues = await github.rest.issues.listForRepo({ owner: context.repo.owner, repo: context.repo.repo, state: 'open', labels: 'broken-links', per_page: 1 }); if (issues.data.length > 0) { await github.rest.issues.update({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issues.data[0].number, state: 'closed', state_reason: 'completed' }); await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: issues.data[0].number, body: '✅ All links are now working! Closing this issue.' }); console.log(`Closed issue #${issues.data[0].number}`); }