Skip to content

feat: consolidate PR comments into single comment per PR#30

Merged
zkoppert merged 5 commits intomainfrom
feat/consolidated-pr-comments
Mar 15, 2026
Merged

feat: consolidate PR comments into single comment per PR#30
zkoppert merged 5 commits intomainfrom
feat/consolidated-pr-comments

Conversation

@zkoppert
Copy link
Contributor

@zkoppert zkoppert commented Mar 14, 2026

Closes #29

Changes

Instead of posting one comment per conflict pair, this groups all conflicts for a given PR into a single consolidated comment with a table format. Existing bot comments are updated in place.

Before (3 conflicts = 3 separate comments on one PR)

⚠️ Potential Merge Conflict Detected

This PR may conflict with #200 (Refactor auth module).

Conflicting Files:

  • src/auth.py (lines: L10-L20, L50-L60)
  • src/middleware.py (lines: L8-L15)

⚠️ Potential Merge Conflict Detected

This PR may conflict with #300 (Add rate limiting).

Conflicting Files:

  • src/middleware.py (lines: L30-L45)

⚠️ Potential Merge Conflict Detected

This PR may conflict with #400 (Update config loader).

Conflicting Files:

  • src/config.py (lines: L5-L12)

After (3 conflicts = 1 consolidated comment)

⚠️ Potential Merge Conflicts Detected

This PR may conflict with 3 other PR(s):

Conflicting PR Conflicting Files (Lines)
#200 (Refactor auth module) src/auth.py (L10-L20, L50-L60), src/middleware.py (L8-L15)
#300 (Add rate limiting) src/middleware.py (L30-L45)
#400 (Update config loader) src/config.py (L5-L12)

What to do: Review the overlapping changes and coordinate with @alice, @bob, @charlie to resolve conflicts.

Key changes

  • New _build_consolidated_comment() groups conflicts per PR
  • Existing bot comments are updated via PATCH instead of creating new ones
  • _has_existing_comment() replaced by _find_existing_comment() (returns comment object for updates)
  • _group_conflicts_by_pr() restructures conflict data by PR number
  • New _update_comment() edits existing comments in place
  • File-to-line-range attribution: each file's ranges appear next to the filename (no ambiguity for multi-file conflicts)
  • Full test coverage for consolidation and update logic (210 tests, all passing)

Testing

  • make lint - all 5 linters pass (flake8, isort, pylint 10.00/10, mypy, black)
  • make test - 210 tests pass, 99% coverage (required: 80%)
  • ✅ Local integration test with DRY_RUN=true against github/new-user-experience - scanned 6 open PRs, found 1 potential conflict, consolidated PR comment posting triggered successfully with no errors

Instead of posting one comment per conflict pair, group all conflicts
for a given PR into a single consolidated comment with a table format.
Existing bot comments are updated in place rather than creating new ones.

This significantly reduces notification noise for PRs involved in
multiple conflicts.

Closes #29

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions bot added the feature New feature or functionality label Mar 14, 2026
@zkoppert zkoppert self-assigned this Mar 14, 2026
@zkoppert zkoppert marked this pull request as ready for review March 14, 2026 08:11
@zkoppert zkoppert requested a review from jmeridth as a code owner March 14, 2026 08:11
…mments

Combine filename and its line ranges together (e.g. `auth.py` (L10-L20))
instead of listing them in separate columns where the association was
ambiguous for multi-file conflicts.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Collaborator

@jmeridth jmeridth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review

The consolidation logic is well-structured and test coverage is thorough. A few items to consider:

1. Stale comment cleanup on migration (main concern)

When this deploys on repos that already have old-format per-conflict comments, _find_existing_comment returns the first comment matching COMMENT_SIGNATURE. On a PR that currently has 3 separate bot comments (old format), this will:

  • Find comment #1, update it to the new consolidated format
  • Leave comments #2 and #3 as stale orphans

Suggestion: delete extra bot comments when consolidating, or at minimum document this as a known limitation.

2. Missing return type annotation on _find_existing_comment

def _find_existing_comment(repo, pr_number: int):

The rest of the codebase consistently uses type hints. This should have a return type (Optional[Any] or the github3 comment type).

3. Untyped inner data structure

_group_conflicts_by_pr returns dict[int, list[dict[str, Any]]] — the inner dicts use string keys "other_pr" and "files" which are easy to typo silently. A TypedDict or small dataclass would make this safer:

@dataclass
class ConflictEntry:
    other_pr: PRInfo
    files: list[FileOverlap]

Style preference, not a blocker.

4. Dry run doesn't distinguish new vs. update

The dry run path continues before reaching _find_existing_comment, so it always reports everything as "new" comments. The log message will say "Posted X new comment(s), updated 0 existing comment(s)" even if some would have been updates. Minor inaccuracy for a debug mode.


Item #1 is the only one I'd consider blocking. The rest could be addressed here or as follow-ups.

@jmeridth
Copy link
Collaborator

jmeridth commented Mar 14, 2026

I'm also good with this merging and #1 (in previous comment) being handled in a follow-up PR? I'll approve and let you decide.

Fix #1 - Stale comment cleanup: _find_existing_comments now returns ALL
bot comments. The first is updated to the consolidated format, and any
extras (left over from the old per-conflict format) are deleted.

Fix #2 - Type annotations: Added proper return type and parameter types
to _find_existing_comments, _update_comment, and _delete_comment.

Fix #3 - Typed data structure: Replaced dict[str, Any] inner dicts with
a ConflictEntry dataclass for type-safe access to other_pr and files.

Fix #4 - Dry run accuracy: Dry run now calls _find_existing_comments
first and correctly reports whether each PR would get a new comment or
an update, including how many stale comments would be cleaned up.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@zkoppert
Copy link
Contributor Author

zkoppert commented Mar 15, 2026

Thanks for the thorough review! All four items addressed in 44e8299.

  1. Stale cleanup - _find_existing_comment is now _find_existing_comments and returns all bot comments. First one gets updated, rest get deleted. Added _delete_comment with full test coverage for the migration path.
  2. Return type - Added proper type annotations to _find_existing_comments, _update_comment, and _delete_comment.
  3. Typed data structure - Went with a ConflictEntry dataclass instead of dict[str, Any]. Clean and no string key typos possible.
  4. Dry run accuracy - Dry run now calls _find_existing_comments first and correctly reports create vs. update, including how many stale comments would be cleaned up.

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
@zkoppert zkoppert enabled auto-merge (squash) March 15, 2026 05:33
@zkoppert zkoppert merged commit ea0dd7d into main Mar 15, 2026
36 checks passed
@zkoppert zkoppert deleted the feat/consolidated-pr-comments branch March 15, 2026 05:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or functionality release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: consolidate PR comments into single comment per PR

2 participants