mirror of
https://github.com/qodo-ai/pr-agent.git
synced 2025-07-06 05:40:38 +08:00
feat: add support for ignoring PRs from specific users
This commit is contained in:
@ -138,7 +138,17 @@ LANGSMITH_BASE_URL=<url>
|
|||||||
|
|
||||||
## Ignoring automatic commands in PRs
|
## Ignoring automatic commands in PRs
|
||||||
|
|
||||||
In some cases, you may want to automatically ignore specific PRs . Qodo Merge enables you to ignore PR with a specific title, or from/to specific branches (regex matching).
|
Qodo Merge allows you to automatically ignore certain PRs based on various criteria:
|
||||||
|
|
||||||
|
- PRs with specific titles (using regex matching)
|
||||||
|
- PRs between specific branches (using regex matching)
|
||||||
|
- PRs that don't include changes from specific folders (using regex matching)
|
||||||
|
- PRs containing specific labels
|
||||||
|
- PRs opened by specific users
|
||||||
|
|
||||||
|
### Example usage
|
||||||
|
|
||||||
|
#### Ignoring PRs with specific titles
|
||||||
|
|
||||||
To ignore PRs with a specific title such as "[Bump]: ...", you can add the following to your `configuration.toml` file:
|
To ignore PRs with a specific title such as "[Bump]: ...", you can add the following to your `configuration.toml` file:
|
||||||
|
|
||||||
@ -149,6 +159,7 @@ ignore_pr_title = ["\\[Bump\\]"]
|
|||||||
|
|
||||||
Where the `ignore_pr_title` is a list of regex patterns to match the PR title you want to ignore. Default is `ignore_pr_title = ["^\\[Auto\\]", "^Auto"]`.
|
Where the `ignore_pr_title` is a list of regex patterns to match the PR title you want to ignore. Default is `ignore_pr_title = ["^\\[Auto\\]", "^Auto"]`.
|
||||||
|
|
||||||
|
#### Ignoring PRs between specific branches
|
||||||
|
|
||||||
To ignore PRs from specific source or target branches, you can add the following to your `configuration.toml` file:
|
To ignore PRs from specific source or target branches, you can add the following to your `configuration.toml` file:
|
||||||
|
|
||||||
@ -161,6 +172,7 @@ ignore_pr_target_branches = ["qa"]
|
|||||||
Where the `ignore_pr_source_branches` and `ignore_pr_target_branches` are lists of regex patterns to match the source and target branches you want to ignore.
|
Where the `ignore_pr_source_branches` and `ignore_pr_target_branches` are lists of regex patterns to match the source and target branches you want to ignore.
|
||||||
They are not mutually exclusive, you can use them together or separately.
|
They are not mutually exclusive, you can use them together or separately.
|
||||||
|
|
||||||
|
#### Ignoring PRs that don't include changes from specific folders
|
||||||
|
|
||||||
To allow only specific folders (often needed in large monorepos), set:
|
To allow only specific folders (often needed in large monorepos), set:
|
||||||
|
|
||||||
@ -170,3 +182,35 @@ allow_only_specific_folders=['folder1','folder2']
|
|||||||
```
|
```
|
||||||
|
|
||||||
For the configuration above, automatic feedback will only be triggered when the PR changes include files from 'folder1' or 'folder2'
|
For the configuration above, automatic feedback will only be triggered when the PR changes include files from 'folder1' or 'folder2'
|
||||||
|
|
||||||
|
#### Ignoring PRs containg specific labels
|
||||||
|
|
||||||
|
To ignore PRs containg specific labels, you can add the following to your `configuration.toml` file:
|
||||||
|
|
||||||
|
```
|
||||||
|
[config]
|
||||||
|
ignore_pr_labels = ["do-not-merge"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Where the `ignore_pr_labels` is a list of labels that when present in the PR, the PR will be ignored.
|
||||||
|
|
||||||
|
#### Ignoring PRs from specific users
|
||||||
|
|
||||||
|
Qodo Merge automatically identifies and ignores pull requests created by bots using:
|
||||||
|
|
||||||
|
- GitHub's native bot detection system
|
||||||
|
- Name-based pattern matching
|
||||||
|
|
||||||
|
While this detection is robust, it may not catch all cases, particularly when:
|
||||||
|
|
||||||
|
- Bots are registered as regular user accounts
|
||||||
|
- Bot names don't match common patterns
|
||||||
|
|
||||||
|
To supplement the automatic bot detection, you can manually specify users to ignore. Add the following to your `configuration.toml` file to ignore PRs from specific users:
|
||||||
|
```
|
||||||
|
[config]
|
||||||
|
ignore_pr_authors = ["my-special-bot-user", ...]
|
||||||
|
```
|
||||||
|
|
||||||
|
Where the `ignore_pr_authors` is a list of usernames that you want to ignore.
|
||||||
|
|
||||||
|
@ -24,10 +24,6 @@ from pr_agent.identity_providers import get_identity_provider
|
|||||||
from pr_agent.identity_providers.identity_provider import Eligibility
|
from pr_agent.identity_providers.identity_provider import Eligibility
|
||||||
from pr_agent.log import LoggingFormat, get_logger, setup_logger
|
from pr_agent.log import LoggingFormat, get_logger, setup_logger
|
||||||
from pr_agent.secret_providers import get_secret_provider
|
from pr_agent.secret_providers import get_secret_provider
|
||||||
from pr_agent.servers.github_action_runner import get_setting_or_env, is_true
|
|
||||||
from pr_agent.tools.pr_code_suggestions import PRCodeSuggestions
|
|
||||||
from pr_agent.tools.pr_description import PRDescription
|
|
||||||
from pr_agent.tools.pr_reviewer import PRReviewer
|
|
||||||
|
|
||||||
setup_logger(fmt=LoggingFormat.JSON, level="DEBUG")
|
setup_logger(fmt=LoggingFormat.JSON, level="DEBUG")
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
@ -75,6 +71,18 @@ async def handle_manifest(request: Request, response: Response):
|
|||||||
return JSONResponse(manifest_obj)
|
return JSONResponse(manifest_obj)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_username(data):
|
||||||
|
actor = data.get("data", {}).get("actor", {})
|
||||||
|
if actor:
|
||||||
|
if "username" in actor:
|
||||||
|
return actor["username"]
|
||||||
|
elif "display_name" in actor:
|
||||||
|
return actor["display_name"]
|
||||||
|
elif "nickname" in actor:
|
||||||
|
return actor["nickname"]
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
async def _perform_commands_bitbucket(commands_conf: str, agent: PRAgent, api_url: str, log_context: dict, data: dict):
|
async def _perform_commands_bitbucket(commands_conf: str, agent: PRAgent, api_url: str, log_context: dict, data: dict):
|
||||||
apply_repo_settings(api_url)
|
apply_repo_settings(api_url)
|
||||||
if commands_conf == "pr_commands" and get_settings().config.disable_auto_feedback: # auto commands for PR, and auto feedback is disabled
|
if commands_conf == "pr_commands" and get_settings().config.disable_auto_feedback: # auto commands for PR, and auto feedback is disabled
|
||||||
@ -118,6 +126,14 @@ def should_process_pr_logic(data) -> bool:
|
|||||||
title = pr_data.get("title", "")
|
title = pr_data.get("title", "")
|
||||||
source_branch = pr_data.get("source", {}).get("branch", {}).get("name", "")
|
source_branch = pr_data.get("source", {}).get("branch", {}).get("name", "")
|
||||||
target_branch = pr_data.get("destination", {}).get("branch", {}).get("name", "")
|
target_branch = pr_data.get("destination", {}).get("branch", {}).get("name", "")
|
||||||
|
sender = _get_username(data)
|
||||||
|
|
||||||
|
# logic to ignore PRs from specific users
|
||||||
|
ignore_pr_users = get_settings().get("CONFIG.IGNORE_PR_AUTHORS", [])
|
||||||
|
if ignore_pr_users and sender:
|
||||||
|
if sender in ignore_pr_users:
|
||||||
|
get_logger().info(f"Ignoring PR from user '{sender}' due to 'config.ignore_pr_authors' setting")
|
||||||
|
return False
|
||||||
|
|
||||||
# logic to ignore PRs with specific titles
|
# logic to ignore PRs with specific titles
|
||||||
if title:
|
if title:
|
||||||
@ -167,16 +183,7 @@ async def handle_github_webhooks(background_tasks: BackgroundTasks, request: Req
|
|||||||
return "OK"
|
return "OK"
|
||||||
|
|
||||||
# Get the username of the sender
|
# Get the username of the sender
|
||||||
actor = data.get("data", {}).get("actor", {})
|
log_context["sender"] = _get_username(data)
|
||||||
if actor:
|
|
||||||
try:
|
|
||||||
username = actor["username"]
|
|
||||||
except KeyError:
|
|
||||||
try:
|
|
||||||
username = actor["display_name"]
|
|
||||||
except KeyError:
|
|
||||||
username = actor["nickname"]
|
|
||||||
log_context["sender"] = username
|
|
||||||
|
|
||||||
sender_id = data.get("data", {}).get("actor", {}).get("account_id", "")
|
sender_id = data.get("data", {}).get("actor", {}).get("account_id", "")
|
||||||
log_context["sender_id"] = sender_id
|
log_context["sender_id"] = sender_id
|
||||||
|
@ -257,6 +257,14 @@ def should_process_pr_logic(body) -> bool:
|
|||||||
pr_labels = pull_request.get("labels", [])
|
pr_labels = pull_request.get("labels", [])
|
||||||
source_branch = pull_request.get("head", {}).get("ref", "")
|
source_branch = pull_request.get("head", {}).get("ref", "")
|
||||||
target_branch = pull_request.get("base", {}).get("ref", "")
|
target_branch = pull_request.get("base", {}).get("ref", "")
|
||||||
|
sender = body.get("sender", {}).get("login")
|
||||||
|
|
||||||
|
# logic to ignore PRs from specific users
|
||||||
|
ignore_pr_users = get_settings().get("CONFIG.IGNORE_PR_AUTHORS", [])
|
||||||
|
if ignore_pr_users and sender:
|
||||||
|
if sender in ignore_pr_users:
|
||||||
|
get_logger().info(f"Ignoring PR from user '{sender}' due to 'config.ignore_pr_authors' setting")
|
||||||
|
return False
|
||||||
|
|
||||||
# logic to ignore PRs with specific titles
|
# logic to ignore PRs with specific titles
|
||||||
if title:
|
if title:
|
||||||
@ -276,6 +284,7 @@ def should_process_pr_logic(body) -> bool:
|
|||||||
get_logger().info(f"Ignoring PR with labels '{labels_str}' due to config.ignore_pr_labels settings")
|
get_logger().info(f"Ignoring PR with labels '{labels_str}' due to config.ignore_pr_labels settings")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# logic to ignore PRs with specific source or target branches
|
||||||
ignore_pr_source_branches = get_settings().get("CONFIG.IGNORE_PR_SOURCE_BRANCHES", [])
|
ignore_pr_source_branches = get_settings().get("CONFIG.IGNORE_PR_SOURCE_BRANCHES", [])
|
||||||
ignore_pr_target_branches = get_settings().get("CONFIG.IGNORE_PR_TARGET_BRANCHES", [])
|
ignore_pr_target_branches = get_settings().get("CONFIG.IGNORE_PR_TARGET_BRANCHES", [])
|
||||||
if pull_request and (ignore_pr_source_branches or ignore_pr_target_branches):
|
if pull_request and (ignore_pr_source_branches or ignore_pr_target_branches):
|
||||||
|
@ -100,6 +100,14 @@ def should_process_pr_logic(data) -> bool:
|
|||||||
if not data.get('object_attributes', {}):
|
if not data.get('object_attributes', {}):
|
||||||
return False
|
return False
|
||||||
title = data['object_attributes'].get('title')
|
title = data['object_attributes'].get('title')
|
||||||
|
sender = data.get("user", {}).get("username", "")
|
||||||
|
|
||||||
|
# logic to ignore PRs from specific users
|
||||||
|
ignore_pr_users = get_settings().get("CONFIG.IGNORE_PR_AUTHORS", [])
|
||||||
|
if ignore_pr_users and sender:
|
||||||
|
if sender in ignore_pr_users:
|
||||||
|
get_logger().info(f"Ignoring PR from user '{sender}' due to 'config.ignore_pr_authors' settings")
|
||||||
|
return False
|
||||||
|
|
||||||
# logic to ignore MRs for titles, labels and source, target branches.
|
# logic to ignore MRs for titles, labels and source, target branches.
|
||||||
ignore_mr_title = get_settings().get("CONFIG.IGNORE_PR_TITLE", [])
|
ignore_mr_title = get_settings().get("CONFIG.IGNORE_PR_TITLE", [])
|
||||||
|
@ -43,6 +43,7 @@ ignore_pr_title = ["^\\[Auto\\]", "^Auto"] # a list of regular expressions to ma
|
|||||||
ignore_pr_target_branches = [] # a list of regular expressions of target branches to ignore from PR agent when an PR is created
|
ignore_pr_target_branches = [] # a list of regular expressions of target branches to ignore from PR agent when an PR is created
|
||||||
ignore_pr_source_branches = [] # a list of regular expressions of source branches to ignore from PR agent when an PR is created
|
ignore_pr_source_branches = [] # a list of regular expressions of source branches to ignore from PR agent when an PR is created
|
||||||
ignore_pr_labels = [] # labels to ignore from PR agent when an PR is created
|
ignore_pr_labels = [] # labels to ignore from PR agent when an PR is created
|
||||||
|
ignore_pr_authors = [] # authors to ignore from PR agent when an PR is created
|
||||||
#
|
#
|
||||||
is_auto_command = false # will be auto-set to true if the command is triggered by an automation
|
is_auto_command = false # will be auto-set to true if the command is triggered by an automation
|
||||||
enable_ai_metadata = false # will enable adding ai metadata
|
enable_ai_metadata = false # will enable adding ai metadata
|
||||||
|
Reference in New Issue
Block a user