Skip to content

Scheduled URL Checks #279

Scheduled URL Checks

Scheduled URL Checks #279

name: Scheduled URL Checks
on:
schedule:
# Run URL validation every Monday at 00:00 UTC
- cron: '0 0 * * 1'
workflow_dispatch: # Allow manual triggering
permissions:
contents: read
issues: write
jobs:
validate-urls:
name: Validate URLs
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: '22'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Validate URLs
id: validate
run: npm run test:urls 2>&1 | tee url-validation.log
continue-on-error: true
env:
NO_COLOR: '1'
- name: Create issue if URLs are broken
if: steps.validate.outcome == 'failure'
uses: actions/github-script@v8
with:
script: |
const fs = require('node:fs');
const title = '🔗 Broken URLs detected in manifests';
const output = fs.readFileSync('url-validation.log', 'utf8');
const excerpt = output.slice(-6000);
const body = `## Scheduled URL Validation Failed
The weekly URL validation check has detected broken or inaccessible URLs in the manifest files.
**Check run:** [View details](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
### Action Required
- Review the URLs flagged in the validation logs
- Update or remove broken URLs
- Consider if these tools/services have been discontinued
### Validation Output
\`\`\`text
${excerpt}
\`\`\`
---
*This issue was automatically created by the scheduled URL validation workflow.*`;
// Check if similar issue already exists
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: 'automated,url-validation'
});
if (issues.data.length === 0) {
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: title,
body: body,
labels: ['automated', 'url-validation', 'maintenance']
});
} else {
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issues.data[0].number,
body: body
});
}
- name: Close resolved URL validation issues
if: steps.validate.outcome == 'success'
uses: actions/github-script@v8
with:
script: |
const issues = await github.paginate(github.rest.issues.listForRepo, {
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: 'automated,url-validation',
per_page: 100
});
for (const issue of issues) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: `URL validation passed in ${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}. Closing this automated maintenance issue.`
});
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
state: 'closed',
state_reason: 'completed'
});
}
- name: Fail workflow after reporting broken URLs
if: steps.validate.outcome == 'failure'
run: exit 1
workflow-summary:
name: Workflow Summary
runs-on: ubuntu-latest
needs: [validate-urls]
if: always()
steps:
- name: Summary
run: |
echo "## Scheduled Checks Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- URL Validation: ${{ needs.validate-urls.result }}" >> $GITHUB_STEP_SUMMARY