mirror of
https://github.com/qodo-ai/pr-agent.git
synced 2025-07-02 03:40:38 +08:00
@ -164,6 +164,7 @@ Qodo Merge allows you to automatically ignore certain PRs based on various crite
|
||||
|
||||
- PRs with specific titles (using regex matching)
|
||||
- PRs between specific branches (using regex matching)
|
||||
- PRs from specific repositories (using regex matching)
|
||||
- PRs not from specific folders
|
||||
- PRs containing specific labels
|
||||
- PRs opened by specific users
|
||||
@ -172,7 +173,7 @@ Qodo Merge allows you to automatically ignore certain PRs based on various crite
|
||||
|
||||
To ignore PRs with a specific title such as "[Bump]: ...", you can add the following to your `configuration.toml` file:
|
||||
|
||||
```
|
||||
```toml
|
||||
[config]
|
||||
ignore_pr_title = ["\\[Bump\\]"]
|
||||
```
|
||||
@ -183,7 +184,7 @@ Where the `ignore_pr_title` is a list of regex patterns to match the PR title yo
|
||||
|
||||
To ignore PRs from specific source or target branches, you can add the following to your `configuration.toml` file:
|
||||
|
||||
```
|
||||
```toml
|
||||
[config]
|
||||
ignore_pr_source_branches = ['develop', 'main', 'master', 'stage']
|
||||
ignore_pr_target_branches = ["qa"]
|
||||
@ -192,6 +193,18 @@ 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.
|
||||
They are not mutually exclusive, you can use them together or separately.
|
||||
|
||||
### Ignoring PRs from specific repositories
|
||||
|
||||
To ignore PRs from specific repositories, you can add the following to your `configuration.toml` file:
|
||||
|
||||
```toml
|
||||
[config]
|
||||
ignore_repositories = ["my-org/my-repo1", "my-org/my-repo2"]
|
||||
```
|
||||
|
||||
Where the `ignore_repositories` is a list of regex patterns to match the repositories you want to ignore. This is useful when you have multiple repositories and want to exclude certain ones from analysis.
|
||||
|
||||
|
||||
### Ignoring PRs not from specific folders
|
||||
|
||||
To allow only specific folders (often needed in large monorepos), set:
|
||||
|
@ -127,6 +127,14 @@ def should_process_pr_logic(data) -> bool:
|
||||
source_branch = pr_data.get("source", {}).get("branch", {}).get("name", "")
|
||||
target_branch = pr_data.get("destination", {}).get("branch", {}).get("name", "")
|
||||
sender = _get_username(data)
|
||||
repo_full_name = pr_data.get("destination", {}).get("repository", {}).get("full_name", "")
|
||||
|
||||
# logic to ignore PRs from specific repositories
|
||||
ignore_repos = get_settings().get("CONFIG.IGNORE_REPOSITORIES", [])
|
||||
if repo_full_name and ignore_repos:
|
||||
if any(re.search(regex, repo_full_name) for regex in ignore_repos):
|
||||
get_logger().info(f"Ignoring PR from repository '{repo_full_name}' due to 'config.ignore_repositories' setting")
|
||||
return False
|
||||
|
||||
# logic to ignore PRs from specific users
|
||||
ignore_pr_users = get_settings().get("CONFIG.IGNORE_PR_AUTHORS", [])
|
||||
|
@ -258,6 +258,14 @@ def should_process_pr_logic(body) -> bool:
|
||||
source_branch = pull_request.get("head", {}).get("ref", "")
|
||||
target_branch = pull_request.get("base", {}).get("ref", "")
|
||||
sender = body.get("sender", {}).get("login")
|
||||
repo_full_name = body.get("repository", {}).get("full_name", "")
|
||||
|
||||
# logic to ignore PRs from specific repositories
|
||||
ignore_repos = get_settings().get("CONFIG.IGNORE_REPOSITORIES", [])
|
||||
if ignore_repos and repo_full_name:
|
||||
if any(re.search(regex, repo_full_name) for regex in ignore_repos):
|
||||
get_logger().info(f"Ignoring PR from repository '{repo_full_name}' due to 'config.ignore_repositories' setting")
|
||||
return False
|
||||
|
||||
# logic to ignore PRs from specific users
|
||||
ignore_pr_users = get_settings().get("CONFIG.IGNORE_PR_AUTHORS", [])
|
||||
|
@ -113,6 +113,14 @@ def should_process_pr_logic(data) -> bool:
|
||||
return False
|
||||
title = data['object_attributes'].get('title')
|
||||
sender = data.get("user", {}).get("username", "")
|
||||
repo_full_name = data.get('project', {}).get('path_with_namespace', "")
|
||||
|
||||
# logic to ignore PRs from specific repositories
|
||||
ignore_repos = get_settings().get("CONFIG.IGNORE_REPOSITORIES", [])
|
||||
if ignore_repos and repo_full_name:
|
||||
if any(re.search(regex, repo_full_name) for regex in ignore_repos):
|
||||
get_logger().info(f"Ignoring MR from repository '{repo_full_name}' due to 'config.ignore_repositories' setting")
|
||||
return False
|
||||
|
||||
# logic to ignore PRs from specific users
|
||||
ignore_pr_users = get_settings().get("CONFIG.IGNORE_PR_AUTHORS", [])
|
||||
|
@ -55,6 +55,7 @@ ignore_pr_target_branches = [] # a list of regular expressions of target branche
|
||||
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_authors = [] # authors to ignore from PR agent when an PR is created
|
||||
ignore_repositories = [] # a list of regular expressions of repository full names (e.g. "org/repo") to ignore from PR agent processing
|
||||
#
|
||||
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
|
||||
|
79
tests/unittest/test_ignore_repositories.py
Normal file
79
tests/unittest/test_ignore_repositories.py
Normal file
@ -0,0 +1,79 @@
|
||||
import pytest
|
||||
from pr_agent.servers.github_app import should_process_pr_logic as github_should_process_pr_logic
|
||||
from pr_agent.servers.bitbucket_app import should_process_pr_logic as bitbucket_should_process_pr_logic
|
||||
from pr_agent.servers.gitlab_webhook import should_process_pr_logic as gitlab_should_process_pr_logic
|
||||
from pr_agent.config_loader import get_settings
|
||||
|
||||
def make_bitbucket_payload(full_name):
|
||||
return {
|
||||
"data": {
|
||||
"pullrequest": {
|
||||
"title": "Test PR",
|
||||
"source": {"branch": {"name": "feature/test"}},
|
||||
"destination": {
|
||||
"branch": {"name": "main"},
|
||||
"repository": {"full_name": full_name}
|
||||
}
|
||||
},
|
||||
"actor": {"username": "user", "type": "user"}
|
||||
}
|
||||
}
|
||||
|
||||
def make_github_body(full_name):
|
||||
return {
|
||||
"pull_request": {},
|
||||
"repository": {"full_name": full_name},
|
||||
"sender": {"login": "user"}
|
||||
}
|
||||
|
||||
def make_gitlab_body(full_name):
|
||||
return {
|
||||
"object_attributes": {"title": "Test MR"},
|
||||
"project": {"path_with_namespace": full_name}
|
||||
}
|
||||
|
||||
PROVIDERS = [
|
||||
("github", github_should_process_pr_logic, make_github_body),
|
||||
("bitbucket", bitbucket_should_process_pr_logic, make_bitbucket_payload),
|
||||
("gitlab", gitlab_should_process_pr_logic, make_gitlab_body),
|
||||
]
|
||||
|
||||
class TestIgnoreRepositories:
|
||||
def setup_method(self):
|
||||
get_settings().set("CONFIG.IGNORE_REPOSITORIES", [])
|
||||
|
||||
@pytest.mark.parametrize("provider_name, provider_func, body_func", PROVIDERS)
|
||||
def test_should_ignore_matching_repository(self, provider_name, provider_func, body_func):
|
||||
get_settings().set("CONFIG.IGNORE_REPOSITORIES", ["org/repo-to-ignore"])
|
||||
body = {
|
||||
"pull_request": {},
|
||||
"repository": {"full_name": "org/repo-to-ignore"},
|
||||
"sender": {"login": "user"}
|
||||
}
|
||||
result = provider_func(body_func(body["repository"]["full_name"]))
|
||||
# print(f"DEBUG: Provider={provider_name}, test_should_ignore_matching_repository, result={result}")
|
||||
assert result is False, f"{provider_name}: PR from ignored repository should be ignored (return False)"
|
||||
|
||||
@pytest.mark.parametrize("provider_name, provider_func, body_func", PROVIDERS)
|
||||
def test_should_not_ignore_non_matching_repository(self, provider_name, provider_func, body_func):
|
||||
get_settings().set("CONFIG.IGNORE_REPOSITORIES", ["org/repo-to-ignore"])
|
||||
body = {
|
||||
"pull_request": {},
|
||||
"repository": {"full_name": "org/other-repo"},
|
||||
"sender": {"login": "user"}
|
||||
}
|
||||
result = provider_func(body_func(body["repository"]["full_name"]))
|
||||
# print(f"DEBUG: Provider={provider_name}, test_should_not_ignore_non_matching_repository, result={result}")
|
||||
assert result is True, f"{provider_name}: PR from non-ignored repository should not be ignored (return True)"
|
||||
|
||||
@pytest.mark.parametrize("provider_name, provider_func, body_func", PROVIDERS)
|
||||
def test_should_not_ignore_when_config_empty(self, provider_name, provider_func, body_func):
|
||||
get_settings().set("CONFIG.IGNORE_REPOSITORIES", [])
|
||||
body = {
|
||||
"pull_request": {},
|
||||
"repository": {"full_name": "org/repo-to-ignore"},
|
||||
"sender": {"login": "user"}
|
||||
}
|
||||
result = provider_func(body_func(body["repository"]["full_name"]))
|
||||
# print(f"DEBUG: Provider={provider_name}, test_should_not_ignore_when_config_empty, result={result}")
|
||||
assert result is True, f"{provider_name}: PR should not be ignored if ignore_repositories config is empty"
|
Reference in New Issue
Block a user