fix(reopen): honor collaborator closes and paginate issue-events for last-closer - #1185
Merged
JSONbored merged 5 commits intoJun 24, 2026
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1185 +/- ##
==========================================
+ Coverage 94.69% 94.80% +0.10%
==========================================
Files 157 157
Lines 19077 19083 +6
Branches 6906 6909 +3
==========================================
+ Hits 18065 18091 +26
+ Misses 424 399 -25
- Partials 588 593 +5 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…on branches Branch gaps in the new pagination loop and collaborator-permission check: - getLastCloserLogin: add catch-path test (request throws → null) and null-actor test (actor: null on closed event → null via ??) - maybeRecloseDisallowedReopen: add fast-path admin test (ADMIN_GITHUB_LOGINS hit → no reclose), null-closer test (empty events → unknown closer → allow), bot-closer test (gittensory[bot] closed → reclose), self-close test (contributor closed → non-maintainer closer → allow), and permission-API- error test (fetch throws → null → non-maintainer → allow)
| const closes = events.filter((entry) => entry.event === "closed"); | ||
| return closes.length > 0 ? (closes[closes.length - 1]?.actor?.login ?? null) : null; | ||
| let lastCloser: string | null = null; | ||
| for (let page = 1; ; page += 1) { |
Contributor
There was a problem hiding this comment.
P2: Unbounded pagination loop in issue-events fetch lacks page limit
Unbounded loop fetches every issue-events page with no maximum limit.
Add a maximum page limit (e.g., 10 pages) to prevent rate limit exhaustion.
AI prompt
Check if this security scanner issue is valid. If so, understand the root cause and fix it. If appropriate, update or add tests. Keep the change focused and preserve intended behavior.
<file name="src/github/pr-actions.ts">
<violation number="1" location="src/github/pr-actions.ts:123">
<priority>P2</priority>
<title>Unbounded pagination loop in issue-events fetch lacks page limit</title>
<evidence>The new code introduces a `for (let page = 1; ; page += 1)` loop with no maximum page limit to walk all issue events pages. For PRs with thousands of events, this will make an excessive number of authenticated GitHub API requests, risking rate limit exhaustion and queue processor stalls.</evidence>
<recommendation>Cap pagination at a reasonable maximum (e.g., `page <= 10`) and return `lastCloser` early if the limit is reached. Document the cap in a code comment.</recommendation>
</violation>
</file>
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
closedevent appears beyond the first page.\Description
GET /repos/{owner}/{repo}/issues/{issue_number}/eventspages (per_page=100) ingetLastCloserLoginso the latestclosedevent is discovered across all pages (src/github/pr-actions.ts).\getRepositoryCollaboratorPermission, treatingadmin,maintain, andwriteas maintainer authority when deciding to allow a reopen (src/queue/processors.ts).\test/unit/github-pr-actions.test.ts,test/unit/queue.test.ts).\Testing
npx vitest run test/unit/github-pr-actions.test.ts test/unit/queue.test.ts -t "one-shot reopen prevention|paginated issue events", and the new/regression tests passed.\npm run typecheckandgit diff --checksucceeded.\npm run test:ci(full local gate); execution reached unrelated existing timeouts and coverage post-processing failed withTypeError: jsTokens is not a function, so full CI was not completed here.\npm audit --audit-level=moderate; the npm audit endpoint returned403 Forbiddenso the audit could not be completed in this environment.Codex Task