Support triggering commands via review assignment in Gitlab#2388
Conversation
Review Summary by QodoSupport auto-triggering commands on GitLab reviewer assignment
WalkthroughsDescription• Add GitLab reviewer assignment detection via webhook payload • Auto-trigger configured commands when bot assigned as reviewer • Implement bot user ID resolution with per-process caching • Add configurable toggle and command list for reviewer assignment Diagramflowchart LR
A["GitLab Webhook<br/>MR Update Event"] -->|"Check action=update"| B["is_bot_assigned_as_reviewer()"]
B -->|"Parse reviewers<br/>changes"| C["_get_bot_user_id()"]
C -->|"Resolve via API<br/>with cache"| D["Bot ID Match"]
D -->|"If enabled"| E["apply_repo_settings()"]
E -->|"handle_reviewer_assignment=true"| F["Execute<br/>reviewer_commands"]
F -->|"Run /review etc"| G["Process MR"]
File Changes1. pr_agent/servers/gitlab_webhook.py
|
Code Review by Qodo
1. Reviewer toggle key casing
|
| # for reviewer assignment triggered merge requests | ||
| elif object_attributes.get('action') == 'update' and is_bot_assigned_as_reviewer(data): | ||
| url = object_attributes.get('url') | ||
| apply_repo_settings(url) | ||
| if get_settings().gitlab.get('handle_reviewer_assignment', False): | ||
| get_logger().info(f"Bot was assigned as reviewer on MR: {url}") | ||
| await _perform_commands_gitlab("reviewer_commands", PRAgent(), url, log_context, data) |
There was a problem hiding this comment.
2. No tests for reviewer assignment 📘 Rule violation ⚙ Maintainability
The PR adds new behavior to auto-trigger commands when the bot is assigned as a reviewer, but no corresponding pytest coverage is added/updated. This increases regression risk for webhook parsing and configuration toggle behavior.
Agent Prompt
## Issue description
Reviewer-assignment-triggered command execution is new behavior and needs tests to prevent regressions.
## Issue Context
Add unit tests to validate:
- detection logic for bot assignment based on `changes.reviewers.previous/current`
- `handle_reviewer_assignment` gating
- correct command list used (`reviewer_commands`)
## Fix Focus Areas
- pr_agent/servers/gitlab_webhook.py[296-303]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
133a196 to
dfe13bf
Compare
|
Persistent review updated to latest commit dfe13bf |
|
Persistent review updated to latest commit efbbf0d |
|
Persistent review updated to latest commit b00b975 |
b00b975 to
779a192
Compare
|
Persistent review updated to latest commit 779a192 |
779a192 to
c47b201
Compare
|
Persistent review updated to latest commit c47b201 |
c47b201 to
58c4c52
Compare
|
Persistent review updated to latest commit 58c4c52 |
58c4c52 to
c110e50
Compare
|
Persistent review updated to latest commit c110e50 |
c110e50 to
959aacd
Compare
|
Persistent review updated to latest commit 959aacd |
959aacd to
c950ba8
Compare
|
Persistent review updated to latest commit c950ba8 |
…b MR Add support for detecting when the PR-Agent bot is assigned as a reviewer on a GitLab merge request via the webhook payload, and automatically running configured commands (e.g. /review) in response. - Add handle_reviewer_assignment toggle and reviewer_commands config under [gitlab] in configuration.toml (disabled by default) - Add is_bot_assigned_as_reviewer() to parse changes.reviewers from the webhook payload and detect initial bot assignment - Add _get_bot_user_id() to auto-resolve the bot's GitLab user ID via API, with per-process caching - Add new dispatch branch in the merge_request event handler for reviewer-assignment updates - Call apply_repo_settings() before reading the toggle, enabling per-project configuration via .pr_agent.toml Assisted-by: opencode:deepseek-v4-pro
c950ba8 to
f54d0b9
Compare
|
Persistent review updated to latest commit f54d0b9 |
| apply_repo_settings(url) | ||
| handle_assignment = get_settings().gitlab.get("handle_reviewer_assignment", False) | ||
| if isinstance(handle_assignment, str): | ||
| handle_assignment = handle_assignment.lower() in ("true", "1", "yes") | ||
| if not handle_assignment: | ||
| return JSONResponse(status_code=status.HTTP_200_OK, | ||
| content=jsonable_encoder({"message": "success"})) | ||
|
|
||
| # Check PR logic after applying repo settings | ||
| if not should_process_pr_logic(data): | ||
| return JSONResponse(status_code=status.HTTP_200_OK, content=jsonable_encoder({"message": "success"})) | ||
|
|
||
| if is_draft(data): | ||
| get_logger().info(f"Skipping draft MR reviewer assignment: {url}") | ||
| return JSONResponse(status_code=status.HTTP_200_OK, | ||
| content=jsonable_encoder({"message": "success"})) | ||
| if await is_bot_assigned_as_reviewer(data): | ||
| reviewer_commands = get_settings().gitlab.get("reviewer_commands", []) | ||
| if not isinstance(reviewer_commands, list) or not all(isinstance(c, str) for c in reviewer_commands): | ||
| get_logger().warning("gitlab.reviewer_commands is not a list of strings, skipping") |
There was a problem hiding this comment.
1. Reviewer toggle key casing 🐞 Bug ≡ Correctness
The reviewer-assignment handler reads handle_reviewer_assignment/reviewer_commands via
get_settings().gitlab.get("…") using lowercase keys, which can return defaults when Dynaconf
normalizes stored keys to uppercase. This can prevent the feature from enabling (or from reading the
configured commands) even when configured via file/env/secrets.
Agent Prompt
### Issue description
The reviewer-assignment branch retrieves settings via `get_settings().gitlab.get("handle_reviewer_assignment")` and `get_settings().gitlab.get("reviewer_commands")`. In this codebase, settings are commonly accessed using `get_settings().get("GITLAB.X")` / `get_settings().get("gitlab.x")`, and other code paths explicitly normalize keys to uppercase, so the lowercase `.gitlab.get()` lookups can miss the configured values.
### Issue Context
This can break the new feature in real deployments (especially when configured via env/secrets), because the toggle/commands may be read as defaults.
### Fix Focus Areas
- pr_agent/servers/gitlab_webhook.py[357-376]
### Proposed fix
- Replace:
- `get_settings().gitlab.get("handle_reviewer_assignment", False)`
- `get_settings().gitlab.get("reviewer_commands", [])`
with a single canonical accessor, e.g.:
- `handle_assignment = get_settings().get("gitlab.handle_reviewer_assignment", False)`
- `reviewer_commands = get_settings().get("gitlab.reviewer_commands", [])`
(or the equivalent `GITLAB.HANDLE_REVIEWER_ASSIGNMENT`/`GITLAB.REVIEWER_COMMANDS` form).
- Keep the existing string-to-bool coercion for `handle_assignment` after reading the value.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Gitlab comes with built-it in commands
/request_review,/reviewer,/assign_reviewerwhich all pop-up when one tries to write/reviewin comment.I thought it might come handy if assigning reviewer would actually trigger the same thing, as it is now by default ignored.
I made the change as an togglable setting via
handle_reviewer_assignmentwhich is off by default so it does not break current behavior under[gitlab]section.In addition one can set
reviewer_commands = ["/review"]array optionally triggering several commands upon assignment.Example use in config: