diff --git a/services/github/pulls/get_open_pull_requests.py b/services/github/pulls/get_open_pull_requests.py index 2eba477b..72607b32 100644 --- a/services/github/pulls/get_open_pull_requests.py +++ b/services/github/pulls/get_open_pull_requests.py @@ -5,7 +5,7 @@ @handle_exceptions(default_return_value=[], raise_on_error=False) -def get_open_pull_requests(owner: str, repo: str, target_branch: str, token: str): +def get_open_pull_requests(owner: str, repo: str, token: str): """https://docs.github.com/en/rest/pulls/pulls?apiVersion=2022-11-28#list-pull-requests""" url = f"{GITHUB_API_URL}/repos/{owner}/{repo}/pulls" headers = create_headers(token=token) @@ -13,8 +13,7 @@ def get_open_pull_requests(owner: str, repo: str, target_branch: str, token: str page = 1 while True: - params = { - "base": target_branch, + params: dict[str, str | int] = { "state": "open", "per_page": PER_PAGE, "page": page, diff --git a/services/github/pulls/test_get_open_pull_requests.py b/services/github/pulls/test_get_open_pull_requests.py index 5e212d96..a0507a63 100644 --- a/services/github/pulls/test_get_open_pull_requests.py +++ b/services/github/pulls/test_get_open_pull_requests.py @@ -35,7 +35,6 @@ def test_get_open_pull_requests_success(): result = get_open_pull_requests( owner="test-owner", repo="test-repo", - target_branch="main", token="test-token", ) @@ -75,7 +74,6 @@ def test_get_open_pull_requests_pagination(): result = get_open_pull_requests( owner="test-owner", repo="test-repo", - target_branch="develop", token="test-token", ) @@ -92,7 +90,6 @@ def test_get_open_pull_requests_empty(): result = get_open_pull_requests( owner="test-owner", repo="test-repo", - target_branch="main", token="test-token", ) @@ -104,7 +101,6 @@ def test_get_open_pull_requests_error(): result = get_open_pull_requests( owner="test-owner", repo="test-repo", - target_branch="main", token="test-token", ) @@ -151,7 +147,6 @@ def test_get_open_pull_requests_filters_non_gitauto_prs(): result = get_open_pull_requests( owner="test-owner", repo="test-repo", - target_branch="main", token="test-token", ) @@ -193,7 +188,6 @@ def test_get_open_pull_requests_no_gitauto_prs(): result = get_open_pull_requests( owner="test-owner", repo="test-repo", - target_branch="main", token="test-token", ) diff --git a/services/webhook/push_handler.py b/services/webhook/push_handler.py index 6dfa3960..6f873224 100644 --- a/services/webhook/push_handler.py +++ b/services/webhook/push_handler.py @@ -39,9 +39,7 @@ def handle_push(payload: PushWebhookPayload): token = get_installation_access_token(installation_id=installation_id) - open_prs = get_open_pull_requests( - owner=owner_name, repo=repo_name, target_branch=target_branch, token=token - ) + open_prs = get_open_pull_requests(owner=owner_name, repo=repo_name, token=token) if not open_prs: # No GitAuto PRs targeting this branch diff --git a/services/webhook/schedule_handler.py b/services/webhook/schedule_handler.py index 893f2236..49ca950f 100644 --- a/services/webhook/schedule_handler.py +++ b/services/webhook/schedule_handler.py @@ -185,9 +185,7 @@ def schedule_handler(event: EventBridgeSchedulerEvent): ) # Get open PRs once before the loop - open_prs = get_open_pull_requests( - owner=owner_name, repo=repo_name, target_branch=target_branch, token=token - ) + open_prs = get_open_pull_requests(owner=owner_name, repo=repo_name, token=token) # Find the first suitable file from sorted list target_item = None @@ -284,8 +282,16 @@ def schedule_handler(event: EventBridgeSchedulerEvent): continue # Skip files that have open PRs (temporary, don't exclude) - if any(item_path in pr.get("title", "") for pr in open_prs): - logger.info("Skipping %s: has open PR", item_path) + matching_pr = next( + (pr for pr in open_prs if item_path in pr.get("title", "")), None + ) + if matching_pr: + logger.info( + "Skipping %s: has open PR #%s (%s)", + item_path, + matching_pr.get("number"), + matching_pr.get("base", {}).get("ref"), + ) continue # Final check: Use Claude AI to determine if this file should be tested (expensive, so run last) diff --git a/services/webhook/test_push_handler.py b/services/webhook/test_push_handler.py index 4b090a6d..593492d6 100644 --- a/services/webhook/test_push_handler.py +++ b/services/webhook/test_push_handler.py @@ -170,7 +170,7 @@ def test_handle_push_no_open_prs_returns_early( mock_get_repository.assert_called_once_with(owner_id=123, repo_id=456) mock_get_token.assert_called_once_with(installation_id=789) mock_get_open_prs.assert_called_once_with( - owner="test-owner", repo="test-repo", target_branch="main", token="test-token" + owner="test-owner", repo="test-repo", token="test-token" ) mock_update_pr.assert_not_called() mock_logger.info.assert_not_called() @@ -212,7 +212,7 @@ def test_handle_push_local_main_to_remote_main_handled( mock_get_repository.assert_called_once_with(owner_id=123, repo_id=456) mock_get_token.assert_called_once_with(installation_id=789) mock_get_open_prs.assert_called_once_with( - owner="test-owner", repo="test-repo", target_branch="main", token="test-token" + owner="test-owner", repo="test-repo", token="test-token" ) assert mock_update_pr.call_count == 2 mock_update_pr.assert_any_call( @@ -257,7 +257,7 @@ def test_handle_push_remote_feature_to_remote_main_handled( mock_get_repository.assert_called_once_with(owner_id=123, repo_id=456) mock_get_token.assert_called_once_with(installation_id=789) mock_get_open_prs.assert_called_once_with( - owner="test-owner", repo="test-repo", target_branch="main", token="test-token" + owner="test-owner", repo="test-repo", token="test-token" ) mock_update_pr.assert_called_once_with( owner="test-owner", repo="test-repo", pr_number=5, token="test-token" @@ -390,7 +390,7 @@ def test_handle_push_no_gitauto_prs_returns_early( mock_get_repository.assert_called_once_with(owner_id=123, repo_id=456) mock_get_token.assert_called_once_with(installation_id=789) mock_get_open_prs.assert_called_once_with( - owner="test-owner", repo="test-repo", target_branch="main", token="test-token" + owner="test-owner", repo="test-repo", token="test-token" ) mock_update_pr.assert_not_called() mock_logger.info.assert_not_called() diff --git a/services/webhook/test_schedule_handler.py b/services/webhook/test_schedule_handler.py index 9139a847..17f21950 100644 --- a/services/webhook/test_schedule_handler.py +++ b/services/webhook/test_schedule_handler.py @@ -464,6 +464,180 @@ def test_schedule_handler_prioritizes_zero_coverage_files( assert "updated_at" not in coverage_record +@patch("services.webhook.schedule_handler.get_open_pull_requests") +@patch("services.webhook.schedule_handler.should_skip_test") +@patch("services.webhook.schedule_handler.is_schedule_paused") +@patch("services.webhook.schedule_handler.get_installation_access_token") +@patch("services.webhook.schedule_handler.get_repository") +@patch("services.webhook.schedule_handler.check_availability") +@patch("services.webhook.schedule_handler.get_default_branch") +@patch("services.webhook.schedule_handler.get_file_tree") +@patch("services.webhook.schedule_handler.get_all_coverages") +@patch("services.webhook.schedule_handler.get_raw_content") +def test_schedule_handler_skips_file_with_open_pr_on_different_branch( + mock_get_raw_content, + mock_get_all_coverages, + mock_get_file_tree, + mock_get_default_branch, + mock_check_availability, + mock_get_repository, + mock_get_token, + mock_is_paused, + mock_should_skip_test, + mock_get_open_pull_requests, + mock_event, +): + mock_get_token.return_value = "test-token" + mock_is_paused.return_value = False + mock_get_repository.return_value = { + "trigger_on_schedule": True, + "target_branch": "master", + } + mock_check_availability.return_value = { + "can_proceed": True, + "billing_type": "exception", + "requests_left": None, + "credit_balance_usd": 0, + "period_end_date": None, + "user_message": "", + "log_message": "Exception owner - unlimited access.", + } + mock_get_default_branch.return_value = ("master", None) + mock_get_file_tree.return_value = [ + {"path": "src/app.php", "type": "blob", "size": 100}, + ] + mock_get_all_coverages.return_value = [ + { + "id": 1, + "full_path": "src/app.php", + "owner_id": 123, + "repo_id": 456, + "branch_name": "master", + "created_by": "test-user", + "updated_by": "test-user", + "level": "file", + "file_size": 100, + "statement_coverage": 10.0, + "function_coverage": 50.0, + "branch_coverage": 100.0, + "line_coverage": 10.0, + "package_name": None, + "language": "php", + "uncovered_lines": None, + "uncovered_functions": None, + "uncovered_branches": None, + "created_at": "2024-01-01", + "updated_at": "2024-01-01", + "github_issue_url": None, + "is_excluded_from_testing": False, + }, + ] + mock_get_raw_content.return_value = "