Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/labels-and-capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ or a contract-free mix of substrates (e.g. `tools/spec-inventory` is
| [`tools/egress-gateway`](../tools/egress-gateway/) | `substrate:sandbox` | Egress-allowlist forward proxy (proxy.py plugin); host-level egress chokepoint — defence-in-depth for RFC-AI-0003 §4.4 |
| [`tools/container-gateway`](../tools/container-gateway/) | `substrate:sandbox` | Per-project policy proxy for the podman / docker API; label-scoped, mount- and privilege-checked container access from inside the sandbox |
| [`tools/forwarder-relay`](../tools/forwarder-relay/) | `contract:report-relay` | Adapter contract for inbound-relay backends (ASF Security relay, huntr.com, HackerOne triagers). Pure interface spec; adapters declare detection + credit-extraction + reporter-addressing rules. |
| [`tools/bitbucket`](../tools/bitbucket/) | `contract:change-request` + `contract:tracker` | Coverage: `partial`. Bitbucket Cloud and Bitbucket Data Center bridge foundation for repository metadata context, branch restriction context for PR-management decisions, pull-request discovery/fetching, read-only commit fetching, read-only diff fetching, comments-only discussion fetching, read-only review-state fetching, Cloud-only pull-request task listing/fetching, read-only merge-check context fetching, and read-only status fetching, plus narrowly scoped pull-request comment creation on Cloud and Data Center and Cloud-only approve/unapprove actions. Native Bitbucket issue operations are not implemented: Atlassian removed the native Bitbucket Cloud Issue Tracker API on 2026-08-20 and Data Center native issues were never supported, so the historical issue CLI surface fails closed before any request. Data Center `pr jira-issues <id>` provides read-only discovery of Jira keys associated with pull-request commits and hands them to the Jira bridge (`tools/jira`) for tracker operations. The `partial` qualifier means this tool implements named contract operations but does not satisfy the complete contract and must not be counted as a complete/selectable backend. Broader linked Jira coverage and the remaining pull-request coverage are incomplete. |
| [`tools/bitbucket`](../tools/bitbucket/) | `contract:change-request` + `contract:tracker` | Coverage: `partial`. Bitbucket Cloud and Bitbucket Data Center bridge foundation for repository metadata context, branch restriction context for PR-management decisions, pull-request discovery/fetching, read-only commit fetching, read-only diff fetching, comments-only discussion fetching, read-only review-state fetching, Cloud-only pull-request task listing/fetching, read-only merge-check context fetching, and read-only status fetching, plus narrowly scoped pull-request comment creation, approve/unapprove, and request-changes/remove-request-changes actions on Cloud and Data Center. Native Bitbucket issue operations are not implemented: Atlassian removed the native Bitbucket Cloud Issue Tracker API on 2026-08-20 and Data Center native issues were never supported, so the historical issue CLI surface fails closed before any request. Data Center `pr jira-issues <id>` provides read-only discovery of Jira keys associated with pull-request commits and hands them to the Jira bridge (`tools/jira`) for tracker operations. The `partial` qualifier means this tool implements named contract operations but does not satisfy the complete contract and must not be counted as a complete/selectable backend. Broader linked Jira coverage and the remaining pull-request coverage are incomplete. |
| [`tools/forgejo`](../tools/forgejo/) | `contract:tracker` + `contract:source-control` + `contract:change-request` | Coverage: `partial`. Forgejo / Gitea REST API and `tea` CLI forge bridge foundation for issue listing/fetching, confirmed issue creation, body edits, comments, labels, and milestones under `contract:tracker`, git-backed branch/commit/push operations under `contract:source-control`, and pull-request creation via REST API / compare URL and label edits under `contract:change-request`. Project boards are unsupported (`no-op`) due to absence of REST card/column endpoints. The `partial` qualifier means this tool implements named contract operations but does not satisfy the complete contract and must not be counted as a complete/selectable backend. |
| [`tools/fossil`](../tools/fossil/) | `contract:tracker` + `contract:source-control` | Fossil SCM forge bridge: integrates local SQLite-backed ticket tracking, wiki, and forum reads with the version-control shim |
| [`tools/github`](../tools/github/) | `contract:tracker` + `contract:source-control` + `contract:change-request` + `contract:people` | GitHub REST / GraphQL tracker substrate (called by every lifecycle phase) plus the Git source-control binding documented in [`source-control.md`](../tools/github/source-control.md) (runnable backend in [`tools/vcs`](../tools/vcs/)), the pull-request review/merge gate (`change-request`; the ASF default backend, alongside `tools/jira-patch/` and `tools/mail-patch/` for SVN-first projects), and account profiles / collaborators / team membership (`people`) |
Expand Down
33 changes: 17 additions & 16 deletions tools/bitbucket/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@ Implemented commands and compatibility stubs:
- `magpie-bitbucket pr comment <id> --body-file <path>` (Cloud and Data Center write)
- `magpie-bitbucket pr reviews <id>`
- `magpie-bitbucket pr review <id> --verdict {comment,approve,request-changes} --body-file <path>` (Cloud-only write)
- `magpie-bitbucket pr approve <id>` (Cloud-only write)
- `magpie-bitbucket pr unapprove <id>` (Cloud-only write)
- `magpie-bitbucket pr request-changes <id>` (Cloud-only write)
- `magpie-bitbucket pr remove-request-changes <id>` (Cloud-only write)
- `magpie-bitbucket pr approve <id>` (Cloud and Data Center write)
- `magpie-bitbucket pr unapprove <id>` (Cloud and Data Center write)
- `magpie-bitbucket pr request-changes <id>` (Cloud and Data Center write)
- `magpie-bitbucket pr remove-request-changes <id>` (Cloud and Data Center write)
- `magpie-bitbucket pr decline <id>` (Cloud-only write)
- `magpie-bitbucket pr reject <id> --reason-file <path>` (Cloud-only write)
- `magpie-bitbucket pr merge <id> --strategy {merge,squash,rebase} --expected-source-commit <sha>` (Cloud-only write)
Expand All @@ -105,9 +105,10 @@ activity where exposed by the configured Bitbucket backend.

Write coverage is intentionally narrow. The bridge supports confirmed
top-level pull-request comment creation on Bitbucket Cloud and Data Center.
Additional confirmed Cloud-only writes cover pull-request approve/unapprove,
request-changes/remove-request-changes, decline, backend-neutral reject, and
merge actions after the calling skill has obtained explicit user confirmation. Native Bitbucket Cloud issue writes
Additional confirmed Cloud and Data Center writes cover pull-request
approve/unapprove and request-changes/remove-request-changes. Cloud-only writes
cover decline, backend-neutral reject, and merge actions after the calling
skill has obtained explicit user confirmation. Native Bitbucket Cloud issue writes
are unavailable because Atlassian removed the native Issue Tracker API.
Other writes, such as editing/deleting pull-request comments, changing
branches, or triggering builds, remain out of scope and should be added
Expand All @@ -123,7 +124,7 @@ separately with narrow command surfaces and maintainer review.

## Features

This implementation primarily covers read-only operations, plus narrowly scoped Cloud write operations:
This implementation primarily covers read-only operations, plus narrowly scoped write operations:

1. **Authentication preflight:** verify the configured Bitbucket backend and credentials can reach the selected repository.
2. **Repository metadata:** fetch normalized repository details from Bitbucket Cloud or Data Center.
Expand All @@ -136,8 +137,8 @@ This implementation primarily covers read-only operations, plus narrowly scoped
9. **Pull-request diff fetch:** fetch the pull request unified diff as normalized read-only output.
10. **Pull-request discussion fetch:** fetch a comments-only pull request discussion subset as normalized read-only output.
11. **Pull-request review-state fetch:** fetch reviewers, approvals, change-request signals, pending review requests, and normalized review activity.
12. **Cloud pull-request approve:** approve one pull request as the authenticated user after explicit caller-side confirmation.
13. **Cloud pull-request unapprove:** withdraw the authenticated user's approval after explicit caller-side confirmation.
12. **Pull-request approve:** approve one Cloud or Data Center pull request as the authenticated user after explicit caller-side confirmation.
13. **Pull-request unapprove:** withdraw the authenticated user's Cloud or Data Center pull-request approval after explicit caller-side confirmation.
14. **Pull-request tasks fetch:** list Bitbucket Cloud pull-request tasks and fetch one task as partial read-only change-request context.
15. **Pull-request merge-check context fetch:** fetch known read-only mergeability, conflict, status-check, and review blocker context while preserving unknown values where the backend does not expose a clear signal.
16. **Pull-request status fetch:** fetch build/status checks for the pull request as normalized read-only output.
Expand All @@ -162,8 +163,8 @@ surface:
| Change requests | `get_discussion` / `pr discussion <id>` | Partial read-only | Fetches a comments-only discussion subset with pagination. Participants beyond comment authors and unresolved-thread accounting remain incomplete. |
| Change requests | `pr comment <id> --body-file <path>` | Partial write | Creates one top-level Bitbucket Cloud or Data Center pull-request comment from a caller-supplied body file after explicit caller-side confirmation. |
| Change requests | `reviews` supplement / `pr reviews <id>` | Partial read-only | Fetches reviewers, approvals, change-request signals, pending review requests, normalized review events, and an aggregate review decision. This does not post reviews or mutate PR state. |
| Change requests | `pr approve <id>` / `pr unapprove <id>` | Partial write, Cloud only | Approves or withdraws the authenticated user's approval after explicit caller-side confirmation. Data Center approval writes remain unsupported by these commands. For a review body together with a verdict, use `pr review` (the `post_review` contract). |
| Change requests | `pr request-changes <id>` / `pr remove-request-changes <id>` | Partial write, Cloud only | Requests changes or removes the authenticated user's change request after explicit caller-side confirmation. Data Center change-request writes remain unsupported by these commands. For a review body together with a verdict, use `pr review` (the `post_review` contract). |
| Change requests | `pr approve <id>` / `pr unapprove <id>` | Partial write | Approves or withdraws the authenticated user's approval on Bitbucket Cloud or Data Center after explicit caller-side confirmation. For a review body together with a verdict, use `pr review` (the `post_review` contract), which remains Cloud-only. |
| Change requests | `pr request-changes <id>` / `pr remove-request-changes <id>` | Partial write | Requests changes or removes the authenticated user's change request on Bitbucket Cloud or Data Center after explicit caller-side confirmation. Data Center maps these states to `NEEDS_WORK` and `UNAPPROVED`. For a review body together with a verdict, use `pr review` (the `post_review` contract), which remains Cloud-only. |
| Change requests | `pr decline <id>` | Partial write, Cloud only | Declines one Bitbucket Cloud pull request after explicit caller-side confirmation. Data Center decline writes remain unsupported by this command. |
| Change requests | `merge_checks` supplement / `pr merge-checks <id>` | Partial read-only | Fetches known read-only merge-check context, including Data Center merge-test results, reported mergeability/conflict fields, status checks, review decision, and normalized blockers. Unknown backend signals remain unknown. This does not merge or mutate PR state. |
| Change requests | `post_review` / `pr review <id> --verdict {comment,approve,request-changes} --body-file <path>` | Partial write, Cloud only | Implements the backend-neutral review contract for Bitbucket Cloud after explicit caller-side confirmation. `comment` posts the review body only. `approve` and `request-changes` post the body first and then apply the corresponding Bitbucket verdict. If the second mutation fails after the body was posted, the command fails with an explicit partial-outcome warning so callers inspect the PR before retrying. Data Center post-review writes remain unsupported. |
Expand Down Expand Up @@ -265,7 +266,7 @@ injected by the caller as `BITBUCKET_TOKEN` / `BITBUCKET_CLOUD_USER`.
| Variable | Required for | Description |
|---|---|---|
| `BITBUCKET_KIND` | all commands | `cloud` or `datacenter`. Defaults to `cloud`. |
| `BITBUCKET_TOKEN` | authenticated API calls | API token or personal access token accepted by the selected backend. Read-only PR/repository commands should use minimum read scopes. Pull-request comment writes on Cloud or Data Center, plus Cloud approve/unapprove, request-changes/remove-request-changes, decline, and merge writes require credentials permitted to write pull requests. `repo restrictions` needs elevated repository-admin scope on Bitbucket Cloud and may require `REPO_ADMIN` on Data Center. |
| `BITBUCKET_TOKEN` | authenticated API calls | API token or personal access token accepted by the selected backend. Read-only PR/repository commands should use minimum read scopes. Pull-request comment, approve/unapprove, and request-changes/remove-request-changes writes on Cloud or Data Center, plus Cloud decline and merge writes require credentials permitted to write pull requests. `repo restrictions` needs elevated repository-admin scope on Bitbucket Cloud and may require `REPO_ADMIN` on Data Center. |
| `BITBUCKET_AUTH_SCHEME` | all commands | Authentication scheme. Defaults to `Basic` for Cloud and `Bearer` for Data Center. |
| `BITBUCKET_CLOUD_USER` | Cloud Basic auth | Atlassian account email/user used with `BITBUCKET_TOKEN`. |
| `BITBUCKET_WORKSPACE` | Cloud | Bitbucket Cloud workspace slug. |
Expand Down Expand Up @@ -304,16 +305,16 @@ The bridge currently supports these narrow mutations (native Cloud
issue writes were removed upstream and fail closed):

- top-level pull-request comment creation on Cloud and Data Center
- Cloud-only pull-request approval and approval withdrawal
- Cloud-only pull-request change-request creation and removal
- pull-request approval and approval withdrawal on Cloud and Data Center
- pull-request change-request creation and removal on Cloud and Data Center
- Cloud-only pull-request decline
- Cloud-only pull-request merge with source-commit pinning

For pull-request merge, the calling skill must run and inspect
`pr merge-checks <id>` before invoking `pr merge`; the merge command itself
does not independently enforce approval, build-status, or merge-check gates.

Bitbucket Data Center issue-comment, review-state, decline, and merge
Bitbucket Data Center issue-comment, post-review, decline, and merge
writes remain unsupported by these commands.

All other Bitbucket mutations remain out of scope for the current bridge and
Expand Down
82 changes: 66 additions & 16 deletions tools/bitbucket/src/magpie_bitbucket/datacenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
post_json,
quote_path,
require,
write_request,
)


Expand Down Expand Up @@ -357,47 +358,96 @@ def get_pull_request_status(config: BitbucketConfig, pull_request_id: str) -> di
return combined


def _current_user_slug(config: BitbucketConfig) -> str:
"""Return the authenticated Bitbucket Data Center user's URL-safe slug."""
user = get_json(f"{_api_base(config)}/users", config)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Bitbucket Data Center REST API v1.0, GET /rest/api/1.0/users is a paged user-directory search returning {"values": [...], "size": ...} rather than a single user object. Because there is no top-level slug field, user.get("slug") returns None on live instances and raises BitbucketError. Consider extracting the X-AUSERNAME response header or reading config.username.

slug = user.get("slug")

if not isinstance(slug, str) or not slug.strip():
raise BitbucketError("Bitbucket Data Center current-user response did not include a user slug")

return quote_path(slug)


def _set_pull_request_participant_status(
config: BitbucketConfig,
pull_request_id: str,
status: str,
) -> dict[str, Any]:
"""Set the authenticated user's pull-request participant status."""
project_key = quote_path(require(config.project_key, "BITBUCKET_PROJECT_KEY"))
repo_slug = quote_path(require(config.repo_slug, "BITBUCKET_REPO_SLUG"))
pr_id = quote_path(pull_request_id)
user_slug = _current_user_slug(config)

url = (
f"{_api_base(config)}/projects/{project_key}/repos/{repo_slug}/"
f"pull-requests/{pr_id}/participants/{user_slug}"
)

participant = write_request(
url,
config,
method="PUT",
payload={"status": status},
)

if participant is None:
raise BitbucketError(
"Bitbucket Data Center participant-status response did not include a participant"
)

return {
"pull_request_id": pull_request_id,
"participant": participant,
}


def approve_pull_request(
config: BitbucketConfig,
pull_request_id: str,
) -> dict[str, Any]:
"""Reject pull-request approval writes for Data Center for now."""
_ = (config, pull_request_id)
raise BitbucketError(
"Bitbucket Data Center pull request approval writes are not supported by this command yet"
"""Approve one Bitbucket Data Center pull request as the authenticated user."""
return _set_pull_request_participant_status(
config,
pull_request_id,
"APPROVED",
)


def unapprove_pull_request(
config: BitbucketConfig,
pull_request_id: str,
) -> dict[str, Any]:
"""Reject pull-request unapproval writes for Data Center for now."""
_ = (config, pull_request_id)
raise BitbucketError(
"Bitbucket Data Center pull request approval writes are not supported by this command yet"
"""Remove the authenticated user's approval from a Data Center pull request."""
return _set_pull_request_participant_status(
config,
pull_request_id,
"UNAPPROVED",
)


def request_pull_request_changes(
config: BitbucketConfig,
pull_request_id: str,
) -> dict[str, Any]:
"""Reject pull-request change-request writes for Data Center for now."""
_ = (config, pull_request_id)
raise BitbucketError(
"Bitbucket Data Center pull request change-request writes are not supported by this command yet"
"""Request changes on a Data Center pull request as the authenticated user."""
return _set_pull_request_participant_status(
config,
pull_request_id,
"NEEDS_WORK",
)


def remove_pull_request_changes_request(
config: BitbucketConfig,
pull_request_id: str,
) -> dict[str, Any]:
"""Reject pull-request change-request removal writes for Data Center for now."""
_ = (config, pull_request_id)
raise BitbucketError(
"Bitbucket Data Center pull request change-request writes are not supported by this command yet"
"""Remove the authenticated user's Data Center change request."""
return _set_pull_request_participant_status(
config,
pull_request_id,
"UNAPPROVED",
)


Expand Down
Loading
Loading