Skip to content

Commit 4c6a3d5

Browse files
committed
Fix stale pr closing script
1 parent 6433d8e commit 4c6a3d5

File tree

2 files changed

+114
-151
lines changed

2 files changed

+114
-151
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
---
2+
name: "Close Stale PRs"
3+
4+
on:
5+
schedule:
6+
# Run daily at 00:00 UTC
7+
- cron: '0 0 * * *'
8+
workflow_dispatch:
9+
10+
permissions:
11+
pull-requests: write
12+
issues: write
13+
14+
jobs:
15+
stale:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Warn and close stale PRs
19+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd
20+
with:
21+
script: |
22+
const daysUntilStale = 46; // Tag as stale after 46 days
23+
const daysUntilClose = 60; // Close after 60 days total
24+
25+
// Add the 'no-autoclose' label to any PR to prevent automatic closure
26+
const exemptLabel = 'no-autoclose';
27+
const staleLabel = 'stale';
28+
29+
const now = new Date();
30+
31+
// Get all open pull requests
32+
const pulls = await github.paginate(github.rest.pulls.list, {
33+
owner: context.repo.owner,
34+
repo: context.repo.repo,
35+
state: 'open',
36+
per_page: 100
37+
});
38+
39+
console.log(`Found ${pulls.length} open pull requests`);
40+
41+
for (const pr of pulls) {
42+
console.log(`\nProcessing PR #${pr.number}: ${pr.title}`);
43+
44+
// Get PR labels
45+
const labels = pr.labels.map(l => l.name);
46+
47+
// Skip if PR has the no-autoclose label
48+
if (labels.includes(exemptLabel)) {
49+
console.log(` Skipping: has '${exemptLabel}' label`);
50+
continue;
51+
}
52+
53+
// Calculate days since last update
54+
const updatedAt = new Date(pr.updated_at);
55+
const daysSinceUpdate = Math.floor((now - updatedAt) / (1000 * 60 * 60 * 24));
56+
console.log(` Days since update: ${daysSinceUpdate}`);
57+
58+
// If PR was updated and has stale label, remove it
59+
if (labels.includes(staleLabel) && daysSinceUpdate < daysUntilStale) {
60+
console.log(` Removing stale label (PR was updated)`);
61+
try {
62+
await github.rest.issues.removeLabel({
63+
owner: context.repo.owner,
64+
repo: context.repo.repo,
65+
issue_number: pr.number,
66+
name: staleLabel
67+
});
68+
} catch (error) {
69+
console.log(` Error removing stale label: ${error.message}`);
70+
}
71+
}
72+
// If PR is old enough and not yet tagged as stale, tag it
73+
else if (!labels.includes(staleLabel) && daysSinceUpdate >= daysUntilStale) {
74+
console.log(` Tagging as stale (${daysSinceUpdate} days inactive)`);
75+
try {
76+
await github.rest.issues.createComment({
77+
owner: context.repo.owner,
78+
repo: context.repo.repo,
79+
issue_number: pr.number,
80+
body: `This pull request has been inactive for ${daysSinceUpdate} days and will be closed in approximately ${daysUntilClose - daysSinceUpdate} days if no further activity (commits, comments...) occurs.\n\n💡 **Tip:** Add the \`${exemptLabel}\` label to prevent automatic closure.`
81+
});
82+
83+
await github.rest.issues.addLabels({
84+
owner: context.repo.owner,
85+
repo: context.repo.repo,
86+
issue_number: pr.number,
87+
labels: [staleLabel]
88+
});
89+
} catch (error) {
90+
console.log(` Error tagging as stale: ${error.message}`);
91+
}
92+
}
93+
// If PR is tagged as stale and old enough, close it
94+
else if (labels.includes(staleLabel) && daysSinceUpdate >= daysUntilClose - daysUntilStale) {
95+
console.log(` Closing stale PR (${daysSinceUpdate} days inactive)`);
96+
try {
97+
await github.rest.issues.createComment({
98+
owner: context.repo.owner,
99+
repo: context.repo.repo,
100+
issue_number: pr.number,
101+
body: `This pull request has been closed due to inactivity (${daysUntilClose} days with no updates). If you would like to continue this work, please feel free to reopen the PR or create a new one. Thank you for your contribution!`
102+
});
103+
104+
await github.rest.pulls.update({
105+
owner: context.repo.owner,
106+
repo: context.repo.repo,
107+
pull_number: pr.number,
108+
state: 'closed'
109+
});
110+
} catch (error) {
111+
console.log(` Error closing PR: ${error.message}`);
112+
}
113+
}
114+
}

.github/workflows/stale-prs.yml

Lines changed: 0 additions & 151 deletions
This file was deleted.

0 commit comments

Comments
 (0)