mirror of
https://github.com/anthropics/claude-code.git
synced 2026-04-16 07:42:48 +00:00
Fix issues being auto-closed despite human activity (#26360)
The sweep script was closing issues based solely on when a lifecycle label was applied, ignoring any human comments posted after the label. This caused active issues (like #11792) to be closed even when users responded to the stale warning. Three changes: 1. Teach the triage bot about `stale` and `autoclose` labels so it removes them when a human comments on the issue. 2. Add a safety net in `closeExpired()` that checks for non-bot comments posted after the lifecycle label was applied — if any exist, skip closing. 3. Extend the 10-upvote protection (which previously only applied to enhancements) to all issue types, in both `markStale()` and `closeExpired()`. Fixes #16497 ## Test plan Trace through scenarios manually: - Issue with stale label + human comment after → triage removes label; sweep skips even if triage hasn't run yet (safety net) - Issue with stale label + no human comment → closes as before - Issue with 10+ upvotes of any type → never marked stale or closed Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -70,11 +70,8 @@ async function markStale(owner: string, repo: string) {
|
||||
);
|
||||
if (alreadyStale) continue;
|
||||
|
||||
const isEnhancement = issue.labels?.some(
|
||||
(l: any) => l.name === "enhancement"
|
||||
);
|
||||
const thumbsUp = issue.reactions?.["+1"] ?? 0;
|
||||
if (isEnhancement && thumbsUp >= STALE_UPVOTE_THRESHOLD) continue;
|
||||
if (thumbsUp >= STALE_UPVOTE_THRESHOLD) continue;
|
||||
|
||||
const base = `/repos/${owner}/${repo}/issues/${issue.number}`;
|
||||
|
||||
@@ -109,6 +106,10 @@ async function closeExpired(owner: string, repo: string) {
|
||||
for (const issue of issues) {
|
||||
if (issue.pull_request) continue;
|
||||
if (issue.locked) continue;
|
||||
|
||||
const thumbsUp = issue.reactions?.["+1"] ?? 0;
|
||||
if (thumbsUp >= STALE_UPVOTE_THRESHOLD) continue;
|
||||
|
||||
const base = `/repos/${owner}/${repo}/issues/${issue.number}`;
|
||||
|
||||
const events = await githubRequest<any[]>(`${base}/events?per_page=100`);
|
||||
@@ -120,6 +121,22 @@ async function closeExpired(owner: string, repo: string) {
|
||||
|
||||
if (!labeledAt || labeledAt > cutoff) continue;
|
||||
|
||||
// Skip if a non-bot user commented after the label was applied.
|
||||
// The triage workflow should remove lifecycle labels on human
|
||||
// activity, but check here too as a safety net.
|
||||
const comments = await githubRequest<any[]>(
|
||||
`${base}/comments?since=${labeledAt.toISOString()}&per_page=100`
|
||||
);
|
||||
const hasHumanComment = comments.some(
|
||||
(c) => c.user && c.user.type !== "Bot"
|
||||
);
|
||||
if (hasHumanComment) {
|
||||
console.log(
|
||||
`#${issue.number}: skipping (human activity after ${label} label)`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (DRY_RUN) {
|
||||
const age = Math.floor((Date.now() - labeledAt.getTime()) / 86400000);
|
||||
console.log(`#${issue.number}: would close (${label}, ${age}d old) — ${issue.title}`);
|
||||
|
||||
Reference in New Issue
Block a user