mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
Fix duplicate issue bot to respect 👎 reactions and not re-close reopened issues (#24203)
## Summary Fixed two bugs in the auto-close-duplicates bot: - **Respect 👎 reactions from ANY user**: Previously only the issue author's thumbs down would prevent auto-closing. Now any user can indicate disagreement with the duplicate detection. - **Don't re-close reopened issues**: The bot now checks if an issue was previously reopened and skips auto-closing to respect user intent. ## Changes 1. Modified `fetchAllReactions` call to check all reactions, not just the author's 2. Changed `authorThumbsDown` logic to `hasThumbsDown` (checks any user's reaction) 3. Added `wasIssueReopened()` function to query issue events timeline 4. Added check to skip issues with "reopened" events in their history ## Test plan - [ ] Manually test the script doesn't close issues with 👎 reactions from non-authors - [ ] Verify reopened issues are not auto-closed again - [ ] Check that legitimate duplicates without objections still get closed properly 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Bot <claude-bot@bun.sh> Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,11 @@ interface GitHubReaction {
|
||||
content: string;
|
||||
}
|
||||
|
||||
interface GitHubEvent {
|
||||
event: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
async function sleep(ms: number): Promise<void> {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
@@ -153,6 +158,13 @@ async function fetchAllReactions(
|
||||
return allReactions;
|
||||
}
|
||||
|
||||
async function wasIssueReopened(owner: string, repo: string, issueNumber: number, token: string): Promise<boolean> {
|
||||
const events: GitHubEvent[] = await githubRequest(`/repos/${owner}/${repo}/issues/${issueNumber}/events`, token);
|
||||
|
||||
// Check if there's a "reopened" event in the issue's timeline
|
||||
return events.some(event => event.event === "reopened");
|
||||
}
|
||||
|
||||
function escapeRegExp(str: string): string {
|
||||
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
}
|
||||
@@ -299,16 +311,23 @@ async function autoCloseDuplicates(): Promise<void> {
|
||||
}
|
||||
|
||||
console.log(`[DEBUG] Issue #${issue.number} - checking reactions on duplicate comment...`);
|
||||
const reactions = await fetchAllReactions(owner, repo, lastDupeComment.id, token, issue.user.id);
|
||||
const reactions = await fetchAllReactions(owner, repo, lastDupeComment.id, token);
|
||||
console.log(`[DEBUG] Issue #${issue.number} - duplicate comment has ${reactions.length} reactions`);
|
||||
|
||||
const authorThumbsDown = reactions.some(
|
||||
reaction => reaction.user.id === issue.user.id && reaction.content === "-1",
|
||||
);
|
||||
console.log(`[DEBUG] Issue #${issue.number} - author thumbs down reaction: ${authorThumbsDown}`);
|
||||
const hasThumbsDown = reactions.some(reaction => reaction.content === "-1");
|
||||
console.log(`[DEBUG] Issue #${issue.number} - has thumbs down reaction: ${hasThumbsDown}`);
|
||||
|
||||
if (authorThumbsDown) {
|
||||
console.log(`[DEBUG] Issue #${issue.number} - author disagreed with duplicate detection, skipping`);
|
||||
if (hasThumbsDown) {
|
||||
console.log(`[DEBUG] Issue #${issue.number} - someone disagreed with duplicate detection, skipping`);
|
||||
continue;
|
||||
}
|
||||
|
||||
console.log(`[DEBUG] Issue #${issue.number} - checking if issue was reopened...`);
|
||||
const wasReopened = await wasIssueReopened(owner, repo, issue.number, token);
|
||||
console.log(`[DEBUG] Issue #${issue.number} - was reopened: ${wasReopened}`);
|
||||
|
||||
if (wasReopened) {
|
||||
console.log(`[DEBUG] Issue #${issue.number} - issue was previously reopened, skipping auto-close`);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user