Skip to content

Close Stale closing-soon PRs #99

Close Stale closing-soon PRs

Close Stale closing-soon PRs #99

name: Close Stale closing-soon PRs
on:
schedule:
- cron: '0 */6 * * *' # every 6 hours
workflow_dispatch:
jobs:
close-stale:
runs-on: ubuntu-latest
permissions:
pull-requests: write
issues: write
steps:
- uses: actions/github-script@v7
with:
script: |
const label = 'closing-soon';
const staleDays = 1;
const cutoff = new Date(Date.now() - staleDays * 24 * 60 * 60 * 1000);
const prs = await github.rest.pulls.list({
...context.repo,
state: 'open',
per_page: 100
});
for (const pr of prs.data) {
if (!pr.labels.some(l => l.name === label)) continue;
// Find when the label was added
const events = await github.rest.issues.listEvents({
...context.repo,
issue_number: pr.number,
per_page: 100
});
const labelEvent = events.data
.filter(e => e.event === 'labeled' && e.label?.name === label)
.pop();
if (!labelEvent) continue;
const labeledAt = new Date(labelEvent.created_at);
if (labeledAt > cutoff) continue;
await github.rest.issues.createComment({
...context.repo,
issue_number: pr.number,
body: `🔒 Auto-closing: this PR has had the \`${label}\` label for more than ${staleDays} days without activity from the author.\n\nIf you'd like to continue working on this, please submit a new PR and link to this one if necessary.`
});
await github.rest.pulls.update({
...context.repo,
pull_number: pr.number,
state: 'closed'
});
console.log(`Closed PR #${pr.number} (labeled ${labeledAt.toISOString()})`);
}