Skip to content

Implement comprehensive link checker with image focus and CI/CD integration #5

Implement comprehensive link checker with image focus and CI/CD integration

Implement comprehensive link checker with image focus and CI/CD integration #5

Workflow file for this run

---
name: PR Link Check
on:
pull_request:
types: [labeled, synchronize, reopened]
jobs:
check-label:
name: Check for link-check label
runs-on: ubuntu-latest
outputs:
should-run: ${{ steps.check.outputs.should-run }}
steps:
- name: Check for link-check label
id: check
run: |
if [[ "${{ contains(github.event.pull_request.labels.*.name, 'link-check') }}" == "true" ]]; then
echo "should-run=true" >> $GITHUB_OUTPUT
else
echo "should-run=false" >> $GITHUB_OUTPUT
fi
build-and-linkcheck:
name: Build Site and Run Link Check
runs-on: ubuntu-latest
needs: check-label
if: needs.check-label.outputs.should-run == 'true'
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Build site with Docker Compose
run: |
docker compose --profile manual run --rm dist
docker compose --profile manual run --rm build
- name: Start HTTP server and run link checker
run: |
# Start HTTP server in background
docker compose up -d http_serve
# Wait for server to be ready
echo "⏳ Waiting for server to be ready..."
timeout 60 bash -c 'until curl -s http://localhost:8082 > /dev/null; do sleep 2; done' || {
echo "❌ Server not ready"
docker compose logs http_serve
exit 1
}
# Run quick link checker (2min max)
docker compose --profile manual run --rm broken_links_quick
# Stop services
docker compose down
- name: Upload Link Check Report
uses: actions/upload-artifact@v4
if: always()
with:
name: pr-link-check-report-${{ github.event.number }}
path: linkchecker_reports/
retention-days: 14
- name: Comment on PR with results
uses: actions/github-script@v7
if: always()
with:
script: |
const fs = require('fs');
const path = './.github/linkchecker/output.csv';
let message = '## 🔗 Link Check Results\n\n';
if (fs.existsSync(path)) {
const lines = fs.readFileSync(path, 'utf8')
.split('\n')
.filter(line => line.trim());
if (lines.length > 1) {
const brokenCount = lines.length - 1; // Subtract header
message += `❌ **Found ${brokenCount} broken links**\n\n`;
message += `📊 [View detailed report](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})\n\n`;
if (brokenCount <= 10) {
message += '### Broken Links:\n';
const csvContent = fs.readFileSync(path, 'utf8');
const rows = csvContent.split('\n').slice(1, 11);
for (const row of rows) {
if (row.trim()) {
const cols = row.split(';');
if (cols.length >= 3) {
message += `- **${cols[1]}** in ${cols[0]} - ${cols[2]}\n`;
}
}
}
if (brokenCount > 10) {
message += `\n... and ${brokenCount - 10} more. See full report above.\n`;
}
}
} else {
message += '✅ **No broken links found!**\n\n';
}
} else {
message += '⚠️ **Link check could not be completed**\n\n';
message += 'Please check the workflow logs for more information.\n';
}
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: message
});