From 3d5ef4e8c01005beca88c1c8359e8584d54c9d19 Mon Sep 17 00:00:00 2001 From: Boris Cherny Date: Mon, 4 Aug 2025 17:07:53 -0700 Subject: [PATCH] Add auto-close functionality for duplicate issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update dedupe command to include auto-close warning - Add commit-push-pr command for streamlined workflow - Add GitHub workflow to automatically close duplicates 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .claude/commands/commit-push-pr.md | 19 +++++ .claude/commands/dedupe.md | 2 + .github/workflows/auto-close-duplicates.yml | 95 +++++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 .claude/commands/commit-push-pr.md create mode 100644 .github/workflows/auto-close-duplicates.yml diff --git a/.claude/commands/commit-push-pr.md b/.claude/commands/commit-push-pr.md new file mode 100644 index 00000000..0a624d60 --- /dev/null +++ b/.claude/commands/commit-push-pr.md @@ -0,0 +1,19 @@ +--- +allowed-tools: Bash(git checkout --branch:*), Bash(git add:*), Bash(git status:*), Bash(git push:*), Bash(git commit:*), Bash(gh pr create:*) +description: Commit, push, and open a PR +--- + +## Context + +- Current git status: !`git status` +- Current git diff (staged and unstaged changes): !`git diff HEAD` +- Current branch: !`git branch --show-current` + +## Your task + +Based on the above changes: +1. Create a new branch if on main +2. Create a single commit with an appropriate message +3. Push the branch to origin +4. Create a pull request using `gh pr create` +5. You have the capability to call multiple tools in a single response. You MUST do all of the above in a single message. Do not use any other tools or do anything else. Do not send any other text or messages besides these tool calls. diff --git a/.claude/commands/dedupe.md b/.claude/commands/dedupe.md index 06c5feba..c675614b 100644 --- a/.claude/commands/dedupe.md +++ b/.claude/commands/dedupe.md @@ -30,6 +30,8 @@ Found 3 possible duplicate issues: If your issue is a duplicate, please close it and 👍 the existing issue instead. +This issue will be automatically closed as a duplicate in 3 days if there are no additional comments. To prevent auto-closure, please 👎 this comment. + 🤖 Generated with [Claude Code](https://claude.ai/code) --- diff --git a/.github/workflows/auto-close-duplicates.yml b/.github/workflows/auto-close-duplicates.yml new file mode 100644 index 00000000..455fc8d2 --- /dev/null +++ b/.github/workflows/auto-close-duplicates.yml @@ -0,0 +1,95 @@ +name: Auto-close duplicate issues +description: Auto-close issues marked as duplicates after 3 days if no response +on: + schedule: + - cron: '0 9 * * *' + +jobs: + auto-close-duplicates: + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + issues: write + + steps: + - name: Auto-close duplicate issues + uses: actions/github-script@v7 + with: + script: | + const threeDaysAgo = new Date(); + threeDaysAgo.setDate(threeDaysAgo.getDate() - 3); + + // Get all open issues + const { data: issues } = await github.rest.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + per_page: 100 + }); + + for (const issue of issues) { + // Get comments for this issue + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number + }); + + // Find duplicate comments (look for "Found 1 possible duplicate" or "Found X possible duplicate") + const dupeComments = comments.filter(comment => + comment.body.includes('Found') && + comment.body.includes('possible duplicate') && + comment.user.type === 'Bot' + ); + + if (dupeComments.length === 0) continue; + + // Get the most recent duplicate comment + const lastDupeComment = dupeComments[dupeComments.length - 1]; + const dupeCommentDate = new Date(lastDupeComment.created_at); + + // Check if the duplicate comment is 3+ days old + if (dupeCommentDate > threeDaysAgo) continue; + + // Check if there are any comments after the duplicate comment + const commentsAfterDupe = comments.filter(comment => + new Date(comment.created_at) > dupeCommentDate + ); + + if (commentsAfterDupe.length > 0) continue; + + // Check if issue author reacted with thumbs down to the duplicate comment + const { data: reactions } = await github.rest.reactions.listForIssueComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: lastDupeComment.id + }); + + const authorThumbsDown = reactions.some(reaction => + reaction.user.id === issue.user.id && reaction.content === '-1' + ); + + if (authorThumbsDown) continue; + + // Auto-close the issue as duplicate + await github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + state: 'closed', + state_reason: 'duplicate' + }); + + // Add closing comment + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + body: `This issue has been automatically closed as a duplicate after 3 days with no response. If this was closed in error, please reopen it. + +🤖 Generated with Claude Code` + }); + + console.log(`Auto-closed issue #${issue.number} as duplicate`); + } \ No newline at end of file