Skip to content

Cron – Check Broken Markdown Links #1

Cron – Check Broken Markdown Links

Cron – Check Broken Markdown Links #1

name: Cron – Check Broken Markdown Links
on:
schedule:
- cron: '0 0 1 * *'
workflow_dispatch:
inputs:
dry_run:
description: 'Run without creating issues? (true/false)'
required: true
default: true
type: boolean
permissions:
contents: read
issues: write
jobs:
cron-check-broken-links:
runs-on: ubuntu-latest
steps:
- name: Harden runner (audit outbound calls)
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Check Markdown links (Lychee)
id: lychee
uses: lycheeverse/lychee-action@a8c4c7cb88f0c7386610c35eb25108e448569cb0 # v2.7.0
continue-on-error: true
with:
args: --verbose --no-progress './**/*.md'
fail: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Report Broken Links (Idempotent Issue Management)
if: steps.lychee.outcome == 'failure'
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: |
// Determine if this is a dry run
const isManual = context.eventName === 'workflow_dispatch';
const dryRun = isManual ? String(context.payload.inputs.dry_run).toLowerCase() === 'true' : false;
// Labels configuration
const targetLabels = ['broken-markdown-links', 'automated'];
const issueTitle = "Scheduled Markdown Link Check Found Broken Links";
const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
console.log(`Event: ${context.eventName}, Dry Run: ${dryRun}`);
// Define Issue Body
const body = `### 🔗 Broken Links Detected\n\n` +
`The scheduled markdown link check workflow has detected broken links.\n\n` +
`**Run Details:**\n` +
`- **Timestamp:** ${new Date().toISOString()}\n` +
`- **Workflow Run:** [View Logs](${runUrl})\n\n` +
`> **Note:** We use [Lychee](https://github.com/lycheeverse/lychee) for link checking. ` +
`Please check the "Check Markdown links" step in the logs to see the specific URLs that failed.`;
if (dryRun) {
console.log("DRY RUN: Would have created or updated an issue.");
return;
}
// Search for existing issue and Update/Create
try {
const { data: issues } = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: targetLabels.join(','),
per_page: 100
});
const existingIssue = issues.find(issue => issue.title === issueTitle);
if (existingIssue) {
console.log(`Updating existing issue #${existingIssue.number}`);
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: existingIssue.number,
body: `**Update ${new Date().toISOString()}:** Still finding broken links.\nCheck new run logs: ${runUrl}`
});
} else {
console.log("Creating a new issue...");
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: issueTitle,
body: body,
labels: targetLabels
});
}
} catch (error) {
console.error('Failed to manage broken link issue:', error);
core.setFailed(`Failed to create or update issue: ${error.message}`);
}