From ca4e4d93d25f635f6c6366adf71e332c15bbf87d Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Wed, 10 Jun 2026 14:53:40 +0900 Subject: [PATCH] fix(ci): use cursor pagination for closed issues --- .github/workflows/stale.yml | 95 +++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 45 deletions(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 3734768002d..37c1ef50db8 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -509,60 +509,62 @@ jobs: let locked = 0; let inspected = 0; + let cursor = null; - let page = 1; while (true) { - const { data: issues } = await github.rest.issues.listForRepo({ - owner, - repo, - state: "closed", - sort: "updated", - direction: "desc", - per_page: perPage, - page, - }); + const result = await github.graphql( + `query ClosedIssuesForLocking( + $owner: String! + $repo: String! + $cursor: String + $perPage: Int! + ) { + repository(owner: $owner, name: $repo) { + issues( + first: $perPage + after: $cursor + states: CLOSED + orderBy: { field: CREATED_AT, direction: ASC } + ) { + nodes { + number + locked + closedAt + comments(last: 1) { + nodes { + createdAt + } + } + } + pageInfo { + hasNextPage + endCursor + } + } + } + }`, + { + owner, + repo, + cursor, + perPage, + }, + ); + const issues = result.repository.issues; - if (issues.length === 0) { - break; - } - - for (const issue of issues) { - if (issue.pull_request) { - continue; - } - if (issue.locked) { - continue; - } - if (!issue.closed_at) { + for (const issue of issues.nodes) { + if (issue.locked || !issue.closedAt) { continue; } inspected += 1; - const closedAtMs = Date.parse(issue.closed_at); - if (!Number.isFinite(closedAtMs)) { - continue; - } - if (closedAtMs > cutoffMs) { + const closedAtMs = Date.parse(issue.closedAt); + if (!Number.isFinite(closedAtMs) || closedAtMs > cutoffMs) { continue; } - let lastCommentMs = 0; - if (issue.comments > 0) { - const { data: comments } = await github.rest.issues.listComments({ - owner, - repo, - issue_number: issue.number, - per_page: 1, - page: 1, - sort: "created", - direction: "desc", - }); - - if (comments.length > 0) { - lastCommentMs = Date.parse(comments[0].created_at); - } - } - + const lastComment = issue.comments.nodes[0]; + const lastCommentMs = lastComment ? Date.parse(lastComment.createdAt) : 0; const lastActivityMs = Math.max(closedAtMs, lastCommentMs || 0); if (lastActivityMs > cutoffMs) { continue; @@ -578,7 +580,10 @@ jobs: locked += 1; } - page += 1; + if (!issues.pageInfo.hasNextPage || !issues.pageInfo.endCursor) { + break; + } + cursor = issues.pageInfo.endCursor; } core.info(`Inspected ${inspected} closed issues; locked ${locked}.`);