Skip to content

feat: Bitbucket Cloud pull requests (watch, run, wait, checks, MCP) - #24

Merged
devblac merged 1 commit into
mainfrom
feat/bitbucket-cloud
Oct 29, 2026
Merged

devblac merged 1 commit into
mainfrom
feat/bitbucket-cloud

Conversation

@devblac

@devblac devblac commented Oct 25, 2026

Copy link
Copy Markdown
Owner

prw now works with Bitbucket Cloud PRs (bitbucket.org/<workspace>/<repo>/pull-requests/<N>) wherever it takes a PR URL.

$ prw checks https://bitbucket.org/atlassian/atlassian-connect-express/pull-requests/560
atlassian/atlassian-connect-express#560 — [Renovate] Update Node.js to v24
87efa3e · failure · 1 fail, 2 pass · merge: blocked

❌ fail  Pipeline - default                            8m23s   https://bitbucket.org/…/pipelines/results/3045
✅ pass  Pipeline - custom: trust-greenlight-pipeline  11m02s  https://bitbucket.org/…/pipelines/results/3046

Design

Rather than rewriting the GitHub code paths, a Bitbucket client answers in the github package's types, so the watcher, wait, checks, broadcast and the MCP tools work unchanged; the only new concept is a host on each PR.

Bitbucket becomes
PR source commit; OPEN / MERGED / DECLINED·SUPERSEDED head SHA; open / merged / closed
commit build statuses (Pipelines, Jenkins, …) check runs with link + duration (STOPPED = cancelled)
participants who approved / requested changes reviews
PR merge checks (git conflict, failing blocking checks) merge state conflict / blocked / ready
  • internal/forge: GitHub + Bitbucket PR URL parsing and links. Watch-list entries gain host (empty = GitHub, so existing configs are unchanged); the same owner/repo#N on both services is two PRs.
  • internal/bitbucket: reuses the GitHub client as transport (auth header, ETag cache, rate-limit errors, ctx cancellation); never follows a next link to another host with credentials; merge checks reused for 2 min while the PR is unchanged.
  • Auth: Atlassian API token + email (Basic) or access token (Bearer), via bitbucket_token / bitbucket_email or BITBUCKET_TOKEN / BITBUCKET_EMAIL; anonymous for public repos; 401/403/404 errors explain how to set it up. No GitHub token needed for Bitbucket-only watch lists.
  • Rate limits: Bitbucket allows 1,000 req/h, so prw run checks a Bitbucket PR at most once a minute; rate-limit pauses are per host.
  • prw config set no longer echoes token values.
  • Not yet for Bitbucket: auto-watch, --logs, prw flaky (clear errors / messages).

Test plan

  • go test ./... -race, go vet ./...
  • Unit: URL parsing, state / merge-check / build-status / participant mapping, merge-check caching, pagination, auth headers, error naming, no cross-host next
  • Watcher: per-host clients, per-host rate-limit pause, Bitbucket min interval, no client for a host keeps its PRs
  • Commands against a fake Bitbucket API: watch / list / unwatch (GitHub and Bitbucket PR with the same number are distinct), wait --json, checks, run --once without a GitHub token, private-repo hint
  • Live with the real binary on public atlassian/atlassian-connect-express PRs: watch, run --once, list, checks, wait --json

🤖 Generated with Claude Code

prw now works with bitbucket.org/<workspace>/<repo>/pull-requests/<N> URLs
wherever it takes a PR URL.

- internal/forge: parses GitHub and Bitbucket PR URLs and builds their links.
  Watch-list entries gain a host (empty for GitHub, so existing config files
  keep their meaning), and the same owner/repo#N on both is two different PRs.
- internal/bitbucket: a Bitbucket Cloud client that answers in the github
  package's types, so the watcher, wait, checks, broadcast and the MCP tools
  work unchanged: source commit = head; OPEN/MERGED/DECLINED/SUPERSEDED map to
  open/merged/closed; build statuses (Pipelines, Jenkins, ...) become check runs
  with link and duration (STOPPED = cancelled); participants' approvals and
  change requests become reviews; the PR's merge checks become the merge state
  (git conflict -> conflict, failing blocking check -> blocked, else ready),
  reused for 2 minutes while the PR is unchanged. It reuses the GitHub client
  as transport (auth header, ETag cache, rate-limit errors, cancellation) and
  never follows a "next" link to another host with the credentials.
- Auth: Atlassian API token + email (Basic) or an access token (Bearer), from
  bitbucket_token / bitbucket_email or BITBUCKET_TOKEN / BITBUCKET_EMAIL;
  anonymous for public repositories. A 404/401/403 explains how to set it up.
  No GitHub token is needed for Bitbucket-only watch lists.
- Watcher: one client per host; rate-limit pauses are per host; a Bitbucket PR
  is checked at most once a minute (Bitbucket allows 1,000 requests/hour).
- Notifications, generic webhooks, list (bitbucket:workspace/repo), --json
  outputs and MCP results carry the host and Bitbucket links.
- `prw config set` no longer echoes token values.

Auto-watch, --logs and `prw flaky` stay GitHub-only for now.

Verified live with the real binary on public atlassian/atlassian-connect-express
PRs: watch, run --once, list, checks (failed Pipeline with link and duration,
merge blocked by a missing approval), wait --json.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-25T06:26:48.981627Z 1236b2d PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1236b2d5d4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +234 to +238
name := s.Name
if name == "" {
name = s.Key
}
run := github.CheckRun{ID: s.UpdatedOn.UnixNano(), Name: name, HTMLURL: s.URL, StartedAt: s.CreatedOn}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve build-status keys when mapping Bitbucket checks

When two build statuses have different keys but the same display name, this mapping discards their distinct identities: both have App.ID == 0, so github.LatestCheckRuns treats them as reruns of one check and drops whichever has the earlier update timestamp. A newer successful status can therefore hide an independent failed or still-running build, causing wait, checks, and MCP to report success incorrectly. Bitbucket identifies statuses by key, not name, as documented in its build-status API. Preserve that identity through aggregation rather than deduplicating distinct keys by display name.

Useful? React with 👍 / 👎.

@devblac
devblac merged commit 51178f8 into main Oct 29, 2026
2 checks passed
@devblac devblac mentioned this pull request Oct 31, 2026
@devblac
devblac deleted the feat/bitbucket-cloud branch November 1, 2026 04:58
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