You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@magpie.apache.org by po...@apache.org on 2026/10/05 15:08:54 UTC

(magpie) branch main updated: fix(bitbucket): report pull request state and source commit in Cloud pr status (#1526)

This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/magpie.git


The following commit(s) were added to refs/heads/main by this push:
     new 20dd624f fix(bitbucket): report pull request state and source commit in Cloud pr status (#1526)
20dd624f is described below

commit 20dd624f83d00d6d7607f530fddc3112c57a7a2a
Author: Davide Polato <dp...@apache.org>
AuthorDate: Mon Oct 5 17:08:47 2026 +0200

    fix(bitbucket): report pull request state and source commit in Cloud pr status (#1526)
    
    On Bitbucket Cloud, `pr status` fetched only the pull request's
    /statuses endpoint. The normalizer reads the state from the pull request
    and the head commit from a `commit` field, so every Cloud run reported
    "state": "unknown" and "commit": null.
    
    Cloud get_pull_request_status() now fetches the pull request first and
    returns it under `pull_request`, with the source commit hash under
    `commit`, matching the Data Center payload. Build checks are still read
    from /statuses with pagination.
    
    test_cli_pr_status_cloud now fakes the HTTP transport with a realistic
    Cloud pull request and statuses page, covering the OPEN, MERGED and
    DECLINED states. Before, it mocked get_pull_request_status() with a
    shape the Cloud backend never returned.
    
    Closes #1495
    
    Signed-off-by: Davide Polato <dp...@apache.org>
---
 tools/bitbucket/src/magpie_bitbucket/cloud.py |  8 ++++-
 tools/bitbucket/tests/test_bitbucket.py       | 46 ++++++++++++++++++++-------
 2 files changed, 41 insertions(+), 13 deletions(-)

diff --git a/tools/bitbucket/src/magpie_bitbucket/cloud.py b/tools/bitbucket/src/magpie_bitbucket/cloud.py
index 8ba80b3c..d542cb53 100644
--- a/tools/bitbucket/src/magpie_bitbucket/cloud.py
+++ b/tools/bitbucket/src/magpie_bitbucket/cloud.py
@@ -493,7 +493,11 @@ def get_pull_request_merge_checks(config: BitbucketConfig, pull_request_id: str)
 
 
 def get_pull_request_status(config: BitbucketConfig, pull_request_id: str) -> dict[str, Any]:
-    """Fetch build statuses for a Bitbucket Cloud pull request."""
+    """Fetch a Bitbucket Cloud pull request and its build statuses."""
+    pull_request = get_pull_request(config, pull_request_id)
+    source = pull_request.get("source")
+    source_commit = source.get("commit") if isinstance(source, dict) else None
+
     workspace = quote_path(require(config.workspace, "BITBUCKET_WORKSPACE"))
     repo_slug = quote_path(require(config.repo_slug, "BITBUCKET_REPO_SLUG"))
     pr_id = quote_path(pull_request_id)
@@ -501,9 +505,11 @@ def get_pull_request_status(config: BitbucketConfig, pull_request_id: str) -> di
 
     combined: dict[str, Any] = {
         "pull_request_id": pull_request_id,
+        "commit": source_commit.get("hash") if isinstance(source_commit, dict) else None,
         "values": [],
         "paginated": True,
         "pages": [],
+        "pull_request": pull_request,
     }
 
     seen_urls = {url}
diff --git a/tools/bitbucket/tests/test_bitbucket.py b/tools/bitbucket/tests/test_bitbucket.py
index fa1b5d13..65fd107d 100644
--- a/tools/bitbucket/tests/test_bitbucket.py
+++ b/tools/bitbucket/tests/test_bitbucket.py
@@ -346,6 +346,7 @@ def test_cloud_get_pull_request_status_follows_next(
 ) -> None:
     opener = mock_opener(
         mock_build_opener,
+        {"id": 7, "state": "OPEN", "source": {"commit": {"hash": "abc123"}}},
         {
             "values": [{"key": "build", "state": "SUCCESSFUL"}],
             "next": "https://api.bitbucket.org/2.0/repositories/apache/magpie/pullrequests/7/statuses?page=2",
@@ -357,12 +358,14 @@ def test_cloud_get_pull_request_status_follows_next(
 
     first_request = opener.open.call_args_list[0].args[0]
     second_request = opener.open.call_args_list[1].args[0]
+    third_request = opener.open.call_args_list[2].args[0]
+    assert first_request.full_url == "https://api.bitbucket.org/2.0/repositories/apache/magpie/pullrequests/7"
     assert (
-        first_request.full_url
+        second_request.full_url
         == "https://api.bitbucket.org/2.0/repositories/apache/magpie/pullrequests/7/statuses"
     )
     assert (
-        second_request.full_url
+        third_request.full_url
         == "https://api.bitbucket.org/2.0/repositories/apache/magpie/pullrequests/7/statuses?page=2"
     )
     assert result["pull_request_id"] == "7"
@@ -874,17 +877,35 @@ def test_cli_pr_reviews_datacenter(datacenter_env: None, capsys: pytest.CaptureF
     assert output["review_decision"] == "approved"
 
 
-@patch("magpie_bitbucket.cloud.get_pull_request_status")
+@patch("urllib.request.build_opener")
+@pytest.mark.parametrize(
+    ("cloud_state", "expected_state"),
+    [("OPEN", "open"), ("MERGED", "merged"), ("DECLINED", "declined")],
+)
 def test_cli_pr_status_cloud(
-    mock_get_pull_request_status: MagicMock,
+    mock_build_opener: MagicMock,
+    cloud_state: str,
+    expected_state: str,
     cloud_env: None,
     capsys: pytest.CaptureFixture[str],
 ) -> None:
-    mock_get_pull_request_status.return_value = {
-        "pull_request_id": "7",
-        "commit": "abc123",
-        "values": [{"key": "build", "state": "SUCCESSFUL"}],
-    }
+    mock_opener(
+        mock_build_opener,
+        {
+            "type": "pullrequest",
+            "id": 7,
+            "title": "Fix docs",
+            "state": cloud_state,
+            "source": {"branch": {"name": "fix-docs"}, "commit": {"type": "commit", "hash": "abc123def456"}},
+            "destination": {"branch": {"name": "main"}, "commit": {"type": "commit", "hash": "0f1e2d3c4b5a"}},
+        },
+        {
+            "values": [
+                {"type": "build", "key": "build", "name": "Build", "state": "SUCCESSFUL"},
+                {"type": "build", "key": "lint", "name": "Lint", "state": "FAILED"},
+            ],
+        },
+    )
 
     exit_code = main(["pr", "status", "7"])
 
@@ -892,9 +913,10 @@ def test_cli_pr_status_cloud(
     output = json.loads(captured.out)
     assert exit_code == 0
     assert output["pull_request_id"] == "7"
-    assert output["commit"] == "abc123"
-    assert output["checks"] == "passing"
-    assert output["check_details"][0]["key"] == "build"
+    assert output["state"] == expected_state
+    assert output["commit"] == "abc123def456"
+    assert output["checks"] == "failing"
+    assert [check["key"] for check in output["check_details"]] == ["build", "lint"]
 
 
 def test_normalize_pull_request_status_aggregate_values() -> None: