Skip to content

Plan for Bitbucket support#108

Draft
jacquev6 wants to merge 18 commits into
mainfrom
jacquev6/document-for-bitbucket
Draft

Plan for Bitbucket support#108
jacquev6 wants to merge 18 commits into
mainfrom
jacquev6/document-for-bitbucket

Conversation

@jacquev6

Copy link
Copy Markdown
Contributor

Before implementing Bitbucket, it's worth checking if it will be actually usable. The Bitbucket API seems to have some serious gaps when compared to GitHub and GitLab.

@jacquev6 jacquev6 force-pushed the jacquev6/document-for-bitbucket branch 2 times, most recently from 7d8b168 to b50b89a Compare July 7, 2026 10:25
jacquev6 and others added 13 commits July 8, 2026 17:27
Implement the pull-request-related actions for the Bitbucket Cloud provider:
get_pull_request, get_pull_requests, create_pull_request, and
update_pull_request, each exposed through bin/bitbucket-client.

get_pull_requests introduces the provider's paginated-result helper, which
reads Bitbucket's in-body 'values' list and derives the next cursor from the
'next' URL (Bitbucket paginates in the body, not via headers).

update_pull_request handles state changes through the separate /decline
endpoint, since Bitbucket's PUT body has no state field; reopening is not
supported by the API and is rejected. This and other divergences are captured
in the new bitbucket-quirks.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Implement get_commits and get_commits_by_path for the Bitbucket Cloud
provider, both exposed through bin/bitbucket-client.

get_commits maps 'ref' to Bitbucket's 'include' filter (defaulting to the main
branch). get_commits_by_path uses the file-history endpoint, whose {commit}
segment is required, so it falls back to the repository's default branch when
no ref is given; since file-history entries embed only an abbreviated commit,
it hydrates each with a concurrent GET .../commit/{hash} fan-out.

Neither Bitbucket endpoint supports date filtering, so since/until raise
ResourceBadRequest rather than silently returning unfiltered commits. These
divergences are recorded in bitbucket-quirks.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Implement get_pull_request_comments, create_pull_request_comment, and
delete_pull_request_comment for the Bitbucket Cloud provider, each exposed
through bin/bitbucket-client.

get_pull_request_comments filters out inline (review) comments and deleted
tombstones so its output matches GitHub's conversation-only 'list issue
comments' semantics.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Implement get_branch, create_branch, and delete_branch for the Bitbucket Cloud
provider, each exposed through bin/bitbucket-client, using the refs/branches
endpoints.

update_branch stays unimplemented: Bitbucket's refs API exposes no PUT/PATCH to
move a branch pointer, and emulating it via delete+recreate would be
non-atomic and unable to honor the fast-forward-only (force=False) contract.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fetch file contents via Bitbucket's /src endpoint, exposed through
bin/bitbucket-client.

The /src endpoint returns raw bytes with no JSON metadata, so we base64-encode
the response, derive size from its byte length, and compute the git blob SHA
locally (sha1 of "blob <len>\0" + content) so FileContent.sha matches the blob
SHA GitHub and GitLab report. Recorded in bitbucket-quirks.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Compare two commits by combining Bitbucket's commits and diffstat endpoints,
exposed through bin/bitbucket-client.

Bitbucket has no single compare endpoint, so we list the commits reachable from
end_sha but not start_sha (paginated) and walk the diffstat in full for the
changed-file list. Bitbucket's diffstat spec orders commits opposite to git, so
we pass end..start to obtain git's start..end diff. Recorded in
bitbucket-quirks.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fetch a single commit via Bitbucket's commit endpoint, exposed through
bin/bitbucket-client. The endpoint returns commit metadata without the file
diff, so files is None (use get_commit_changes for changed files).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
List a pull request's changed files via Bitbucket's diffstat endpoint, exposed
through bin/bitbucket-client. Diffstat reports per-file line counts but no patch
text, so patch is None and sha is empty. Recorded in bitbucket-quirks.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
List a pull request's commits via Bitbucket's commits endpoint, exposed through
bin/bitbucket-client. Bitbucket returns them newest-first, so the page is
reversed to match GitHub/GitLab's oldest-first order.

Also factor the shared commit-author parsing into a _commit_author helper used
by the commit mappers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Implement the review-creation actions for the Bitbucket Cloud provider, exposed
through bin/bitbucket-client:

- create_review_comment_file: inline comment anchored to a file (inline.path)
- create_review_comment_line: inline comment on a single diff line (inline
  from/to keyed by side)
- create_review_comment_reply: reply referencing the parent comment's id
- create_review: fan-out of inline comments, review body, and approve, since
  Bitbucket has no atomic review endpoint

create_review_comment_multiline is left unsupported: Bitbucket's inline anchor
addresses a single line per side with no line range. Divergences are recorded
in bitbucket-quirks.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Implement create_check_run, get_check_run, and update_check_run for the
Bitbucket Cloud provider, exposed through bin/bitbucket-client, mapping check
runs to commit build statuses (check_run_id is "{sha}:{key}", key derived from
external_id or name).

Bitbucket build statuses are lower-fidelity than GitHub checks: states collapse
to INPROGRESS/SUCCESSFUL/FAILED/STOPPED, timestamps are ignored, only the output
title is forwarded as the description, url defaults to the commit page, and the
key is capped at 40 chars. Recorded in bitbucket-quirks.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The end-to-end test previously required three bin/*-server proxies, live
repositories on GitHub/GitLab/Bitbucket in a specific state, and personal
credentials -- so it could only run on one machine.

Replace that with an in-process client (SourceCodeManager.make_client) whose
provider talks to the real service directly through requests, and record every
interaction once with vcrpy. On replay the suite needs no servers, no live
repos, and no credentials; the first run records live from .credentials.

Provider thread-pool fan-out is run inline during tests (vcrpy's cassette is
not thread-safe), a fixed 'now' keeps generated values deterministic across
record and replay, and secrets (auth headers, installation tokens, the App
installation id) are scrubbed or normalized so cassettes are safe to commit
and replay is credential-free.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jacquev6 jacquev6 force-pushed the jacquev6/document-for-bitbucket branch from b50b89a to 71841ab Compare July 8, 2026 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant