This repository was archived by the owner on May 20, 2026. It is now read-only.
Close Stale closing-soon PRs #3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Close Stale closing-soon PRs | |
| on: | |
| schedule: | |
| - cron: '0 9 * * *' # daily at 09:00 UTC | |
| 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 = 3; | |
| 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 a Discord Discussion URL being added.\n\nFeel free to reopen after adding the discussion link to the PR body.` | |
| }); | |
| await github.rest.pulls.update({ | |
| ...context.repo, | |
| pull_number: pr.number, | |
| state: 'closed' | |
| }); | |
| console.log(`Closed PR #${pr.number} (labeled ${labeledAt.toISOString()})`); | |
| } |