Skip to content

Commit 27b4988

Browse files
authored
autoLabelBot: don't re-add triage review if already triaged (#8095)
1 parent 0bd9264 commit 27b4988

2 files changed

Lines changed: 121 additions & 1 deletion

File tree

torchci/lib/bot/autoLabelBot.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,28 @@ function getReleaseNotesCategoryAndTopic(
357357
return ["uncategorized", topic];
358358
}
359359

360+
export async function wasLabelRecentlyRemoved(
361+
context: Context,
362+
issueNumber: number,
363+
labelName: string,
364+
withinMs: number
365+
): Promise<boolean> {
366+
const events = await context.octokit.paginate(
367+
context.octokit.issues.listEvents,
368+
context.repo({
369+
issue_number: issueNumber,
370+
per_page: 100,
371+
})
372+
);
373+
const cutoff = Date.now() - withinMs;
374+
return events.some(
375+
(e: any) =>
376+
e.event === "unlabeled" &&
377+
e.label?.name === labelName &&
378+
new Date(e.created_at).getTime() >= cutoff
379+
);
380+
}
381+
360382
export async function addNewLabels(
361383
existingLabels: string[],
362384
labelsToAdd: string[],
@@ -412,7 +434,20 @@ function myBot(app: Probot): void {
412434
switch (addedLabel) {
413435
case "high priority":
414436
case "critical":
415-
newLabels.push("triage review");
437+
// Don't re-add triage review if a human just triaged the issue
438+
// (removed triage review within the last hour). Older removals
439+
// are ignored so that resurfacing an old issue with hi-pri does
440+
// re-request triage.
441+
if (
442+
!(await wasLabelRecentlyRemoved(
443+
context,
444+
context.payload.issue.number,
445+
"triage review",
446+
60 * 60 * 1000
447+
))
448+
) {
449+
newLabels.push("triage review");
450+
}
416451
break;
417452
}
418453

torchci/test/autoLabelBot.test.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,91 @@ describe("auto-label-bot", () => {
6262
emptyMockConfig(payload.repository.full_name);
6363

6464
const scope = nock("https://api.github.com")
65+
.get(
66+
"/repos/ezyang/testing-ideal-computing-machine/issues/5/events?per_page=100"
67+
)
68+
.reply(200, [])
69+
.post(
70+
"/repos/ezyang/testing-ideal-computing-machine/issues/5/labels",
71+
(body) => {
72+
expect(body).toMatchObject({ labels: ["triage review"] });
73+
return true;
74+
}
75+
)
76+
.reply(200);
77+
78+
await probot.receive({ name: "issues", payload, id: "2" });
79+
80+
scope.done();
81+
});
82+
83+
test("do not re-add triage review if it was just removed (within the hour)", async () => {
84+
nock("https://api.github.com")
85+
.post("/app/installations/2/access_tokens")
86+
.reply(200, { token: "test" });
87+
88+
const payload = requireDeepCopy("./fixtures/issues.labeled");
89+
payload["label"] = { name: "high priority" };
90+
payload["issue"]["labels"] = [{ name: "high priority" }];
91+
emptyMockConfig(payload.repository.full_name);
92+
93+
const recent = new Date(Date.now() - 5 * 60 * 1000).toISOString();
94+
const scope = nock("https://api.github.com")
95+
.get(
96+
"/repos/ezyang/testing-ideal-computing-machine/issues/5/events?per_page=100"
97+
)
98+
.reply(200, [
99+
{
100+
event: "labeled",
101+
label: { name: "high priority" },
102+
created_at: recent,
103+
},
104+
{
105+
event: "labeled",
106+
label: { name: "triage review" },
107+
created_at: recent,
108+
},
109+
{
110+
event: "unlabeled",
111+
label: { name: "triage review" },
112+
created_at: recent,
113+
},
114+
]);
115+
116+
await probot.receive({ name: "issues", payload, id: "2" });
117+
118+
scope.done();
119+
});
120+
121+
test("re-add triage review if old issue resurfaces (stale removal)", async () => {
122+
nock("https://api.github.com")
123+
.post("/app/installations/2/access_tokens")
124+
.reply(200, { token: "test" });
125+
126+
const payload = requireDeepCopy("./fixtures/issues.labeled");
127+
payload["label"] = { name: "high priority" };
128+
payload["issue"]["labels"] = [{ name: "high priority" }];
129+
emptyMockConfig(payload.repository.full_name);
130+
131+
// Triage review was removed long ago — issue is resurfacing and
132+
// should be triaged again.
133+
const old = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString();
134+
const scope = nock("https://api.github.com")
135+
.get(
136+
"/repos/ezyang/testing-ideal-computing-machine/issues/5/events?per_page=100"
137+
)
138+
.reply(200, [
139+
{
140+
event: "labeled",
141+
label: { name: "triage review" },
142+
created_at: old,
143+
},
144+
{
145+
event: "unlabeled",
146+
label: { name: "triage review" },
147+
created_at: old,
148+
},
149+
])
65150
.post(
66151
"/repos/ezyang/testing-ideal-computing-machine/issues/5/labels",
67152
(body) => {

0 commit comments

Comments
 (0)