fix: resolve issue # - - #291
matthiasL-scality wants to merge 1 commit into
Conversation
|
📋 PR Summary With this change, Bert-E edits its previous status comment on a pull request instead of posting a new comment each time. A new Changes
|
There was a problem hiding this comment.
Caution
1 critical finding in this review. Details below.
Caution
Changes requested — 🔴 1 critical · 🟡 3 warnings
🔍 Full review · 6 files reviewed
Verification
AbstractComment.editdefaults to raising NotImplementedError, and_send_commentcatches it and falls back toadd_comment, so Bitbucket-style hosts keep the old behaviour.- The GitHub
Comment.editPATCHesself.data['url']throughupdate, and that url field is part ofschema.Comment, so it is loaded. find_status_commentonly matches comments bysettings.robot, so the marker in another user's comment is ignored.- The
CommentAlreadyExistsraised for an unchanged status is caught bynotify_user, the same way the existing dedup path is.
The new bert_e/tests/unit/test_comment_update.py drives _send_comment with FakePR/FakeComment stubs only. No workflow-level test covers how editing comments interacts with send_greetings or with command handling in handle_comments, and that interaction is where the reset loop happens.
Review details
- Commit: 23cb096
- Model: claude-opus-5-5
Review 1 of 10 for this pull request · View the full run
| ) | ||
| try: | ||
| LOG.debug('UPDATING STATUS COMMENT %s', msg) | ||
| status_comment.edit(msg) |
There was a problem hiding this comment.
🔴 Critical — PRs loop on reset forever and can never merge.
handle_comments only treats commands posted after the bot's last comment as new: it walks reversed(pull_request.comments) and returns at the first comment by the robot (gitwaterflow/init.py ~L344). When a status is updatable, _send_comment now edits an older status comment instead of appending a new one. The bot then has no comment after the triggering command, so the command runs again on every later webhook.
Concrete case:
- A user posts
@bert-e reset. _resetraisesResetComplete, which is updatable.- The bot edits the InitMessage, which is the first comment and carries the marker. No new bot comment is added.
- On the next run
handle_commandsfinds@bert-e resetagain and deletes the integration branches again. It raisesResetCompleteagain, which is now swallowed asCommentAlreadyExists.
The flow stops at the reset on every run, so the PR never reaches integration or queuing. The same thing happens for any command whose answer is an updatable message.
| # template for informative exceptions | ||
| class InformationException(TemplateException): | ||
| dont_repeat_if_in_history = NEVER_REPEAT | ||
| updatable = True |
There was a problem hiding this comment.
🟡 Warning — Users lose the bot's manual and greeting on every PR.
InformationException.updatable = True makes InitMessage updatable. InitMessage goes through notify_user, so the marker is appended to the greeting, and the greeting becomes the status comment. The first later updatable message (IntegrationDataCreated, ResetComplete, BranchHistoryMismatch, IncorrectFixVersion, PendingHotfixVersionReminder) edits the greeting in place. That wipes the welcome text and the list of available options and commands from the PR.
| return | ||
|
|
||
| if updatable: | ||
| status_comment = find_status_comment(pull_request, settings.robot) |
There was a problem hiding this comment.
🟡 Warning — Blocking failures become invisible to PR authors.
find_status_comment returns the newest marked comment, however far back in the thread it is. Non-updatable messages such as ApprovalRequired, Conflict, BuildFailed and Queued are posted as new comments after it. So a new updatable failure, for example BranchHistoryMismatch or IncorrectFixVersion, silently rewrites a comment that may sit many comments above the current discussion, often the original greeting.
Git hosts do not notify anyone on comment edits. The PR author gets no visible message that their PR is now blocked, and the latest visible bot comment can be an outdated status.
| # template for informative exceptions | ||
| class InformationException(TemplateException): | ||
| dont_repeat_if_in_history = NEVER_REPEAT | ||
| updatable = True |
There was a problem hiding this comment.
🟡 Warning — The status comment flip-flops and loses important messages.
PendingHotfixVersionReminder inherits updatable = True. check_pending_hotfix in jira.py skips the reminder only if a bot comment still starts with _PENDING_HOTFIX_TITLE.
- The reminder edits the shared status comment.
- Any later updatable status, such as ResetComplete or IntegrationDataCreated, overwrites that comment and removes the title.
- The dedup no longer finds the title, so the next run edits the reminder back in, replacing the other status.
The reminder and the other statuses keep overwriting each other in the same comment.
| # template for informative exceptions | ||
| class InformationException(TemplateException): | ||
| dont_repeat_if_in_history = NEVER_REPEAT | ||
| updatable = True |
There was a problem hiding this comment.
InitMessage inherits updatable = True from InformationException, which means the initial welcome/instructions comment will be silently replaced in place by the next updatable status message (e.g. IntegrationDataCreated). This is likely unintended — the init message serves a different purpose than status updates. Consider either overriding updatable = False on InitMessage, or setting updatable = True only on specific subclasses rather than on the base class.
— Claude Code
| LOG.debug('UPDATING STATUS COMMENT %s', msg) | ||
| status_comment.edit(msg) | ||
| return | ||
| except NotImplementedError: |
There was a problem hiding this comment.
The except NotImplementedError only catches the case where the git host does not support editing. If the status comment was deleted by a user between find_status_comment() and edit(), an HTTP error (e.g. 404) would propagate uncaught and crash the notification flow instead of falling back to posting a new comment. Consider also catching requests.HTTPError (or a broader exception with a log warning) so the fallback works for API failures too.
— Claude Code
|
Automated Fix for Issue
Issue:
Description:
Changes Made
This PR was automatically generated by Claude Code based on the issue analysis.
AI Evaluation
Files Modified
[]
Tests Created
[]
Generated by n8n automation workflow