mirror of
https://github.com/anthropics/claude-code.git
synced 2026-08-12 18:02:25 -06:00
Fix lock-closed-issues workflow: use search API instead of offset pagination (#69470)
The workflow has been failing daily since 2026-04-27 with HTTP 422 "Pagination with the page parameter is not supported for large datasets" at page=100. The repo now has ~58k closed issues and the script was paging past ~10k already-locked ones every run before reaching any candidates. Replace listForRepo + page=N with the search API (is:issue is:closed is:unlocked updated:<cutoff), which returns only the issues that actually need locking. Cap at 250/run with a 1s sleep between locks to stay under secondary rate limits. Claude-Session: https://claude.ai/code/session_016EWY3FKCJyfUdCAZkXfi7i
This commit is contained in:
@@ -22,71 +22,56 @@ jobs:
|
|||||||
script: |
|
script: |
|
||||||
const sevenDaysAgo = new Date();
|
const sevenDaysAgo = new Date();
|
||||||
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
|
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
|
||||||
|
const cutoff = sevenDaysAgo.toISOString().split('T')[0];
|
||||||
|
|
||||||
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.`;
|
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;
|
const query = `repo:${context.repo.owner}/${context.repo.repo} is:issue is:closed is:unlocked updated:<${cutoff}`;
|
||||||
let hasMore = true;
|
console.log(`Search query: ${query}`);
|
||||||
|
|
||||||
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||||
|
const MAX_PER_RUN = 250;
|
||||||
|
const processed = new Set();
|
||||||
let totalLocked = 0;
|
let totalLocked = 0;
|
||||||
|
|
||||||
while (hasMore) {
|
while (totalLocked < MAX_PER_RUN) {
|
||||||
// Get closed issues (pagination)
|
const { data } = await github.rest.search.issuesAndPullRequests({
|
||||||
const { data: issues } = await github.rest.issues.listForRepo({
|
q: query,
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
state: 'closed',
|
|
||||||
sort: 'updated',
|
sort: 'updated',
|
||||||
direction: 'asc',
|
order: 'asc',
|
||||||
per_page: 100,
|
per_page: 100,
|
||||||
page: page
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (issues.length === 0) {
|
if (totalLocked === 0) {
|
||||||
hasMore = false;
|
console.log(`Total candidates: ${data.total_count}`);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const issue of issues) {
|
const fresh = data.items.filter((i) => !processed.has(i.number));
|
||||||
// Skip if already locked
|
if (fresh.length === 0) break;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
for (const issue of fresh) {
|
||||||
|
if (totalLocked >= MAX_PER_RUN) break;
|
||||||
|
processed.add(issue.number);
|
||||||
try {
|
try {
|
||||||
// Add comment before locking
|
|
||||||
await github.rest.issues.createComment({
|
await github.rest.issues.createComment({
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
issue_number: issue.number,
|
issue_number: issue.number,
|
||||||
body: lockComment
|
body: lockComment,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Lock the issue
|
|
||||||
await github.rest.issues.lock({
|
await github.rest.issues.lock({
|
||||||
owner: context.repo.owner,
|
owner: context.repo.owner,
|
||||||
repo: context.repo.repo,
|
repo: context.repo.repo,
|
||||||
issue_number: issue.number,
|
issue_number: issue.number,
|
||||||
lock_reason: 'resolved'
|
lock_reason: 'resolved',
|
||||||
});
|
});
|
||||||
|
|
||||||
totalLocked++;
|
totalLocked++;
|
||||||
console.log(`Locked issue #${issue.number}: ${issue.title}`);
|
console.log(`Locked issue #${issue.number}: ${issue.title}`);
|
||||||
|
await sleep(1000);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Failed to lock issue #${issue.number}: ${error.message}`);
|
console.error(`Failed to lock issue #${issue.number}: ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
page++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Total issues locked: ${totalLocked}`);
|
console.log(`Total issues locked: ${totalLocked}`);
|
||||||
|
|||||||
Reference in New Issue
Block a user