Skip to content

Commit ec4bbb5

Browse files
authored
Include issues and changed it to weekly instead of daily
1 parent d7fd78b commit ec4bbb5

File tree

1 file changed

+61
-56
lines changed

1 file changed

+61
-56
lines changed

.github/workflows/stale.yml

Lines changed: 61 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
# - If a PR is labeled stale, after 30 days inactivity close the PR.
44
# - `high priority` and `no-stale` PRs are exempt.
55

6-
name: Close stale pull requests
6+
name: Close stale issues and pull requests
77

88
on:
99
schedule:
10-
# Run daily at 00:30 UTC.
11-
- cron: '30 0 * * *'
10+
# Run weekly at 00:30 UTC every Sunday.
11+
- cron: '30 0 * * 0'
1212
workflow_dispatch:
1313

1414
jobs:
@@ -17,13 +17,13 @@ jobs:
1717
runs-on: linux.large
1818
permissions:
1919
contents: read
20+
issues: write
2021
pull-requests: write
2122

2223
steps:
2324
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
2425
with:
2526
script: |
26-
// Do some dumb retries on requests.
2727
const retries = 7;
2828
const baseBackoff = 100;
2929
const sleep = timeout => new Promise(resolve => setTimeout(resolve, timeout));
@@ -43,107 +43,112 @@ jobs:
4343
});
4444
4545
const MAX_API_REQUESTS = 100;
46-
47-
// If a PRs not labeled stale, label them stale after no update for 60 days.
4846
const STALE_LABEL_THRESHOLD_MS = 1000 * 60 * 60 * 24 * 60;
49-
// For PRs already labeled stale, close after not update for 30 days.
5047
const STALE_CLOSE_THRESHOLD_MS = 1000 * 60 * 60 * 24 * 30;
5148
5249
const STALE_MESSAGE =
53-
"Looks like this PR hasn't been updated in a while so we're going to go ahead and mark this as `Stale`. <br>" +
50+
"Looks like this item hasn't been updated in a while so we're going to go ahead and mark this as `Stale`. <br>" +
5451
"Feel free to remove the `Stale` label if you feel this was a mistake. <br>" +
5552
"If you are unable to remove the `Stale` label please contact a maintainer in order to do so. <br>" +
56-
"If you want the bot to never mark this PR stale again, add the `no-stale` label.<br>" +
57-
"`Stale` pull requests will automatically be closed after 30 days of inactivity.<br>";
53+
"If you want the bot to never mark this item stale again, add the `no-stale` label.<br>" +
54+
"`Stale` items will automatically be closed after 30 days of inactivity.<br>";
5855
5956
let numAPIRequests = 0;
6057
let numProcessed = 0;
6158
62-
async function processPull(pull) {
63-
core.info(`[${pull.number}] URL: ${pull.html_url}`);
59+
async function processItem(item, isPR) {
60+
core.info(`[${item.number}] URL: ${item.html_url}`);
6461
numProcessed += 1;
65-
const labels = pull.labels.map((label) => label.name);
62+
const labels = item.labels.map((label) => label.name);
6663
67-
// Skip if certain labels are present.
6864
if (labels.includes("no-stale") || labels.includes("high priority")) {
69-
core.info(`[${pull.number}] Skipping because PR has an exempting label.`);
65+
core.info(`[${item.number}] Skipping because item has an exempting label.`);
7066
return false;
7167
}
7268
73-
// Check if the PR is stale, according to our configured thresholds.
7469
let staleThresholdMillis;
7570
if (labels.includes("Stale")) {
76-
core.info(`[${pull.number}] PR is labeled stale, checking whether we should close it.`);
71+
core.info(`[${item.number}] Item is labeled stale, checking whether we should close it.`);
7772
staleThresholdMillis = STALE_CLOSE_THRESHOLD_MS;
7873
} else {
79-
core.info(`[${pull.number}] Checking whether to label PR as stale.`);
74+
core.info(`[${item.number}] Checking whether to label item as stale.`);
8075
staleThresholdMillis = STALE_LABEL_THRESHOLD_MS;
8176
}
8277
8378
const millisSinceLastUpdated =
84-
new Date().getTime() - new Date(pull.updated_at).getTime();
79+
new Date().getTime() - new Date(item.updated_at).getTime();
8580
8681
if (millisSinceLastUpdated < staleThresholdMillis) {
87-
core.info(`[${pull.number}] Skipping because PR was updated recently`);
82+
core.info(`[${item.number}] Skipping because item was updated recently`);
8883
return false;
8984
}
9085
91-
// At this point, we know we should do something.
92-
// For PRs already labeled stale, close them.
9386
if (labels.includes("Stale")) {
94-
core.info(`[${pull.number}] Closing PR.`);
87+
core.info(`[${item.number}] Closing item.`);
9588
numAPIRequests += 1;
96-
await github.rest.issues.update({
89+
await github.rest.issues.update({
9790
owner: "pytorch",
9891
repo: "executorch",
99-
issue_number: pull.number,
92+
issue_number: item.number,
10093
state: "closed",
101-
});
94+
});
10295
} else {
103-
// For PRs not labeled stale, label them stale.
104-
core.info(`[${pull.number}] Labeling PR as stale.`);
105-
96+
core.info(`[${item.number}] Labeling item as stale.`);
10697
numAPIRequests += 1;
107-
await github.rest.issues.createComment({
98+
await github.rest.issues.createComment({
10899
owner: "pytorch",
109100
repo: "executorch",
110-
issue_number: pull.number,
101+
issue_number: item.number,
111102
body: STALE_MESSAGE,
112103
});
113104
114105
numAPIRequests += 1;
115-
await github.rest.issues.addLabels({
106+
await github.rest.issues.addLabels({
116107
owner: "pytorch",
117108
repo: "executorch",
118-
issue_number: pull.number,
109+
issue_number: item.number,
119110
labels: ["Stale"],
120111
});
121112
}
122113
}
123114
124-
for await (const response of github.paginate.iterator(
125-
github.rest.pulls.list,
126-
{
127-
owner: "pytorch",
128-
repo: "executorch",
129-
state: "open",
130-
sort: "created",
131-
direction: "asc",
132-
per_page: 100,
133-
}
134-
)) {
135-
numAPIRequests += 1;
136-
const pulls = response.data;
137-
// Awaiting in a loop is intentional here. We want to serialize execution so
138-
// that log groups are printed correctl
139-
for (const pull of pulls) {
140-
if (numAPIRequests > MAX_API_REQUESTS) {
141-
core.warning("Max API requests exceeded, exiting.");
142-
process.exit(0);
115+
async function processType(listFn, isPR) {
116+
for await (const response of github.paginate.iterator(
117+
listFn,
118+
{
119+
owner: "pytorch",
120+
repo: "executorch",
121+
state: "open",
122+
sort: "created",
123+
direction: "asc",
124+
per_page: 100,
125+
}
126+
)) {
127+
numAPIRequests += 1;
128+
const items = response.data;
129+
for (const item of items) {
130+
if (numAPIRequests > MAX_API_REQUESTS) {
131+
core.warning("Max API requests exceeded, exiting.");
132+
process.exit(0);
133+
}
134+
await core.group(`Processing ${isPR ? "PR" : "Issue"} #${item.number}`, async () => {
135+
await processItem(item, isPR);
136+
});
143137
}
144-
await core.group(`Processing PR #${pull.number}`, async () => {
145-
await processPull(pull);
146-
});
147138
}
148139
}
149-
core.info(`Processed ${numProcessed} PRs total.`);
140+
141+
// Process PRs
142+
await processType(github.rest.pulls.list, true);
143+
144+
// Process Issues (exclude PRs)
145+
await processType(
146+
async (params) => {
147+
const resp = await github.rest.issues.listForRepo(params);
148+
resp.data = resp.data.filter((issue) => !issue.pull_request);
149+
return resp;
150+
},
151+
false
152+
);
153+
154+
core.info(`Processed ${numProcessed} items total.`);

0 commit comments

Comments
 (0)