fix(gitlab): keep persistent /improve thread stable when it has replies#2404
Conversation
In publish_persistent_comment_with_history, edit the previously-found persistent comment in place and remove the throwaway "Preparing suggestions..." progress note, instead of the other way around. The previous ordering targeted the progress note for the merged update and tried to delete the original; GitLabProvider.remove_comment silently no-ops when GitLab refuses to delete a note that has replies (HTTP 403), so any /improve run on an MR where the author had engaged with the suggestions thread left the original intact and promoted the progress note to a duplicate thread on every subsequent push. The original ordering was deliberate — a freshly-posted note refreshes in the GitLab UI faster than an edit of an older note — but that benefit is lost silently the moment the thread has a reply, and the duplicate-thread cost is much worse than the slower-UI cost. Refs The-PR-Agent#2402.
Review Summary by QodoFix GitLab duplicate suggestions thread with replies
WalkthroughsDescription• Swap edit/delete targets in GitLab persistent comment handling • Edit original persistent comment instead of progress note • Remove throwaway progress note instead of original comment • Prevents duplicate suggestion threads when replies exist Diagramflowchart LR
A["progress_response exists"] -->|Before| B["Edit progress_response"]
B --> C["Delete original comment"]
C --> D["Duplicate thread on replies"]
A -->|After| E["Edit original comment"]
E --> F["Delete progress_response"]
F --> G["Stable thread across pushes"]
File Changes1. pr_agent/tools/pr_code_suggestions.py
|
Code Review by Qodo
Context used 1.
|
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
Edit the progress note to a benign final-state message before attempting its deletion. The previous code relied on remove_comment succeeding to clean up the "Work in progress ..." body; if the delete fails for any reason (transient network errors, or GitLab silently swallowing a 403), the leftover note keeps displaying stale WIP text. Pre-editing to a short "Code suggestions published in the persistent thread above." message means a failed delete leaves a non-misleading breadcrumb instead. Addresses the Qodo review on PR The-PR-Agent#2404.
Good catch — applied in Scoped to the path Qodo flagged ( |
|
Persistent review updated to latest commit 8f52792 |
Wrap the progress-note edit-and-delete cleanup in its own try/except so that an exception there (most realistically a GitLab edit_comment API failure, which is not caught by the provider) does not fall through to the outer exception handler and re-trigger the "no previous comment found" fallback below. The fallback path would then publish a new suggestions thread despite the persistent comment update at the top of the block having already succeeded, recreating the duplicate thread this PR is meant to prevent. Cleanup is best-effort and never affects the success of the persistent update. Addresses the Qodo follow-up review on PR The-PR-Agent#2404.
Real bug, applied in Did not take the optional third part of the suggestion (guarding the fallback block itself). The new try/except already prevents cleanup failures from reaching the fallback; the fallback remains as before for the "persistent edit truly failed" case, which is its original intent. Happy to scope that broader guard into a follow-up PR if maintainers prefer it bundled here. |
|
Persistent review updated to latest commit 8c000f1 |
What
Flip the edit/delete pairing in
publish_persistent_comment_with_historyfor theprogress_responsebranch: edit the previously-found persistent comment in place and remove the throwaway progress note, instead of editing the progress note and trying to delete the original.Why
Fixes #2402. On GitLab, the previous behaviour leaves a duplicate
## PR Code Suggestions ✨thread on every push once the original has any reply, becauseGitLabProvider.remove_commentsilently no-ops when GitLab refuses to delete a note with replies (HTTP 403). The fix keeps the original persistent thread stable across pushes; the progress note is throwaway and safe to delete (and harmless if its delete ever fails).Changes
pr_agent/tools/pr_code_suggestions.py— swap the targets ofedit_commentandremove_commentin theif progress_response:branch.Trade-off
The previous ordering was deliberate — the inline comment at the call site read
# publish to 'progress_response' comment, because it refreshes immediately. The intent was that on GitLab a freshly-posted note renders in the UI more promptly than an edit of an older note. This PR gives that up on the happy path (no replies) in exchange for stability when replies are present. In practice GitLab does update edited notes, so the UX cost is small, but it is a real behavioural change rather than a pure bug fix. The duplicate-thread cost on engaged MRs seems clearly worse than the slower-refresh cost on quiet ones.Tests
PYTHONPATH=. ./.venv/bin/pytest tests/unittest -q— 390 passed).## PR Code Suggestions ✨discussion per push.Risk
Scoped to the
progress_responsecode path insidepublish_persistent_comment_with_history. GitHub and other providers exercise the same branch but theirremove_commentpaths are stable for either ordering, so the swap is content-equivalent for them (the resulting comment ID changes, but the visible content does not).A defence-in-depth follow-up — making
GitLabProvider.remove_commentdetect the "cannot delete a note with replies" case and skip the delete cleanly rather than swallowing the 403 — is purely additive and worth doing separately. Left out of this PR to keep it minimal.