Compare commits

...

7 Commits

Author SHA1 Message Date
Boris Cherny
1579216fc7 Enable auto-close duplicate issues workflow
Remove DRY RUN from workflow name and description to activate the automatic closing of duplicate issues after the testing period.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-08 14:03:43 -07:00
Ashwin Bhat
f0042afb3b Replace lock-threads action with GitHub Script (#5330)
Replaces the dessant/lock-threads action with a direct GitHub Script
implementation to avoid the deprecated search/issues API endpoint warning.
The new implementation:
- Uses github.rest.issues.listForRepo() instead of the deprecated search API
- Maintains the same 7-day inactivity threshold
- Adds the same comment before locking
- Uses 'resolved' as the lock reason
- Handles pagination properly for large repositories

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-08-08 13:02:20 -07:00
Boris Cherny
6059607354 Merge pull request #5420 from anthropics/boris/cmyy
Fix workflow failure by adding workflow_dispatch trigger
2025-08-08 12:57:16 -07:00
Boris Cherny
478f63be73 Fix workflow failure by adding workflow_dispatch trigger
The backfill-duplicate-comments script was failing because it tried to trigger
claude-dedupe-issues.yml via workflow_dispatch, but that workflow only had an
issues trigger. Added workflow_dispatch with issue_number input and updated the
prompt to use either event or input issue number.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-08 12:55:48 -07:00
Boris Cherny
a7edbdc9e7 Merge pull request #5414 from anthropics/boris/aier
Add workflow to backfill duplicate comments
2025-08-08 12:13:19 -07:00
Boris Cherny
399a7dcf2f Add workflow to backfill duplicate comments
🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-08 12:11:08 -07:00
Boris Cherny
9ced2a3470 Merge pull request #5413 from anthropics/boris/bktr
Add script to backfill duplicate comments for old issues
2025-08-08 12:08:17 -07:00
4 changed files with 130 additions and 15 deletions

View File

@@ -1,5 +1,5 @@
name: Auto-close duplicate issues (DRY RUN)
description: Dry run - logs issues that would be auto-closed as duplicates after 3 days if no response
name: Auto-close duplicate issues
description: Auto-closes issues that are duplicates of existing issues
on:
schedule:
- cron: "0 9 * * *"
@@ -16,12 +16,12 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Auto-close duplicate issues
run: bun run scripts/auto-close-duplicates.ts
env:

View File

@@ -0,0 +1,44 @@
name: Backfill Duplicate Comments
description: Triggers duplicate detection for old issues that don't have duplicate comments
on:
workflow_dispatch:
inputs:
days_back:
description: 'How many days back to look for old issues'
required: false
default: '90'
type: string
dry_run:
description: 'Dry run mode (true to only log what would be done)'
required: false
default: 'true'
type: choice
options:
- 'true'
- 'false'
jobs:
backfill-duplicate-comments:
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
issues: read
actions: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Backfill duplicate comments
run: bun run scripts/backfill-duplicate-comments.ts
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DAYS_BACK: ${{ inputs.days_back }}
DRY_RUN: ${{ inputs.dry_run }}

View File

@@ -3,6 +3,12 @@ description: Automatically dedupe GitHub issues using Claude Code
on:
issues:
types: [opened]
workflow_dispatch:
inputs:
issue_number:
description: 'Issue number to process for duplicate detection'
required: true
type: string
jobs:
claude-dedupe-issues:
@@ -19,7 +25,7 @@ jobs:
- name: Run Claude Code slash command
uses: anthropics/claude-code-base-action@beta
with:
prompt: "/dedupe ${{ github.repository }}/issues/${{ github.event.issue.number }}"
prompt: "/dedupe ${{ github.repository }}/issues/${{ github.event.issue.number || inputs.issue_number }}"
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
claude_env: |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -13,16 +13,81 @@ concurrency:
group: lock-threads
jobs:
lock-threads:
lock-closed-issues:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: dessant/lock-threads@1bf7ec25051fe7c00bdd17e6a7cf3d7bfb7dc771 # v5.0.1
- name: Lock closed issues after 7 days of inactivity
uses: actions/github-script@v7
with:
issue-inactive-days: "7"
process-only: "issues"
log-output: true
issue-comment: >
This issue has been automatically locked since it was
closed and has not had any activity for 7 days.
If you're experiencing a similar issue, please file a new issue
and reference this one if it's relevant.
script: |
const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
const lockComment = `This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.`;
let page = 1;
let hasMore = true;
let totalLocked = 0;
while (hasMore) {
// Get closed issues (pagination)
const { data: issues } = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'closed',
sort: 'updated',
direction: 'asc',
per_page: 100,
page: page
});
if (issues.length === 0) {
hasMore = false;
break;
}
for (const issue of issues) {
// Skip if already locked
if (issue.locked) continue;
// Skip pull requests
if (issue.pull_request) continue;
// Check if updated more than 7 days ago
const updatedAt = new Date(issue.updated_at);
if (updatedAt > sevenDaysAgo) {
// Since issues are sorted by updated_at ascending,
// once we hit a recent issue, all remaining will be recent too
hasMore = false;
break;
}
try {
// Add comment before locking
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: lockComment
});
// Lock the issue
await github.rest.issues.lock({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
lock_reason: 'resolved'
});
totalLocked++;
console.log(`Locked issue #${issue.number}: ${issue.title}`);
} catch (error) {
console.error(`Failed to lock issue #${issue.number}: ${error.message}`);
}
}
page++;
}
console.log(`Total issues locked: ${totalLocked}`);