Repository navigation
Fix PR comment pagination to prevent duplicate workflow comments - #1136
Conversation
- Add listAllComments() method to fetch all comment pages (per_page=100) - Update findExistingComment() to use pagination - Preserve public API - all existing methods work identically - Add comprehensive pagination test covering 3 pages of comments - All 10 tests passing (9 original + 1 new pagination test) Co-authored-by: litlfred <662242+litlfred@users.noreply.github.com>
🔒 Security Check Report🟢 5 passed • 🟡 1 warnings Security Checks
🔍 Action Items
|
There was a problem hiding this comment.
Pull Request Overview
Adds pagination to PR comment fetching to prevent duplicate workflow comments by ensuring the marker comment is found beyond the first page. Key changes:
- Introduces listAllComments() to fetch all PR comments via paginated GitHub API calls (per_page=100).
- Updates findExistingComment() to search across all pages and adds tests validating pagination behavior.
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| scripts/lib/pr-comment-manager.js | Adds paginated comment retrieval and updates the find logic to search across all comments. |
| scripts/lib/pr-comment-manager.test.js | Adds tests to assert pagination parameters and multi-page fetching behavior. |
| }); | ||
|
|
||
| it('should handle pagination and find comment across multiple pages', async () => { | ||
| // Create 3 pages of comments (100, 100, 50 comments) |
There was a problem hiding this comment.
The inline comment says the third page has 50 comments, but the test constructs only 3 comments on page 3. Update the comment to match the data (3), or generate 50 comments for page 3 to match the description.
Problem
The
PRCommentManagerclass was only fetching the first page of PR comments (default 30 items per page) when searching for existing marker comments. This caused workflows to create duplicate status comments on PRs with more than 30 comments, since the marker comment wouldn't be found if it appeared beyond the first page.Solution
Added proper pagination support to fetch all PR comments across multiple pages:
Implementation Details
New
listAllComments()method:Updated
findExistingComment()method:listAllComments()instead of single-page fetchExample Scenario
Before this fix:
After this fix:
Testing
Added comprehensive pagination test that simulates a PR with 203 comments across 3 pages:
The test verifies:
per_page=100,page=1/2/3)Test Results:
Benefits
PRCommentManagerworks without modificationFiles Changed
scripts/lib/pr-comment-manager.js- Added pagination logicscripts/lib/pr-comment-manager.test.js- Updated existing test and added pagination testOriginal prompt
Summary:
Create a small, surgical PR that only fixes pagination when listing PR comments so workflows reliably find and update the single marker comment instead of creating duplicates. This PR should only change the comment-management code to paginate list requests and preserve all other behavior.
Files to change (small diffs):
New file content:
/**
*/
class PRCommentManager {
constructor(github, context, commentMarker) {
this.github = github;
this.context = context;
this.commentMarker = commentMarker;
}
/**
*/
async listAllComments(prNumber) {
const owner = this.context.repo.owner;
const repo = this.context.repo.repo;
const per_page = 100;
let page = 1;
let all = [];
}
/**
Find existing comment with the given marker
@PARAM {number} prNumber - Pull request number
@returns {Promise<object|null>} - Existing comment or null
*/
async findExistingComment(prNumber) {
try {
const comments = await this.listAllComments(prNumber);
return comments.find(comment =>
comment.body && comment.body.includes(this.commentMarker)
) || null;
} catch (error) {
console.error('Error finding existing comment:', error);
return null;
}
}
/**
Update existing comment or create new one
@PARAM {number} prNumber - Pull request number
@PARAM {string} body - Comment body with marker included
@returns {Promise} - Success status
*/
async updateOrCreateComment(prNumber, body) {
try {
const existing = await this.findExistingComment(prNumber);
if (existing) {
// Update existing comment
console.log(
Updating existing comment (ID: ${existing.id}));await this.github.rest.issues.updateComment({
owner: this.context.repo.owner,
repo: this.context.repo.repo,
comment_id: existing.id,
body: body
});
console.log('\u2705 Comment updated successfully');
} else {
// Create new comment
console.log('Creating new comment');
await this.github.rest.issues.createComment({
owner: this.context.repo.owner,
repo: this.context.repo.repo,
issue_number: prNumber,
body: body
});
console.log('\u2705 Comment created successfully');
}
return true;
} catch (error) {
console.error('Error updating/creating comment:', error);
return false;
}
}
/**
Delete comment if it exists
@PARAM {number} prNumber - Pull request number
@returns {Promise} - Success status
*/
async deleteCommentIfExists(prNumber) {
try {
const existing = await this.findExistingComment(prNumber);
if (existing) {
console.log(
Deleting comment (ID: ${existing.id}));await this.github.rest.issues.deleteComment({
owner: this.context.repo.owner,
repo: this.context.repo.repo,
comment_id: existing.id
});
console.log('\u2705 Comment deleted successfully');
return true;
}
console.log('No comment found to delete');
return true;
} catch (error) {
console.error('Error deleting comment:', error);
return false;
}
}
}
module.exports = PRCommentManager;
New file content (minimal):
#!/usr/bin/env python3
"""Manage PR comment: update existing comment with marker or create a new one.
This script is used by .github/workflows/branch-deployment.yml to post "Build started" and later updates.
It fetches all PR comments using pagination to reliably find the marker comment on PRs with many comments.
"""
import argparse
import json
import requests
import sys
def list_all_comments(owner, repo, pr_number, token):
headers = {'Authorization': f'token {token}', 'Accept': 'application/vnd.github+json'}
per_page = 100
page = 1
all_comments = []
...
This pull request was created as a result of the following prompt from Copilot chat.
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.