Skip to content

fix(bitbucket): migrate off cross-workspace APIs removed by CHANGE-2770#8916

Open
KennethWKZ wants to merge 4 commits into
apache:mainfrom
KennethWKZ:feature/fix-bitbucket-change-2770
Open

fix(bitbucket): migrate off cross-workspace APIs removed by CHANGE-2770#8916
KennethWKZ wants to merge 4 commits into
apache:mainfrom
KennethWKZ:feature/fix-bitbucket-change-2770

Conversation

@KennethWKZ

@KennethWKZ KennethWKZ commented Jun 10, 2026

Copy link
Copy Markdown

⚠️ Pre Checklist

Please complete ALL items in this checklist, and remove before submitting

  • I have read through the Contributing Documentation.
  • I have added relevant tests.
  • I have added relevant documentation.
  • I will add labels to the PR, such as pr-type/bug-fix, pr-type/feature-development, etc.

Summary

What does this PR do?

Bitbucket Cloud removed its cross-workspace REST APIs as part of CHANGE-2770. The Bitbucket plugin still called these endpoints, so listing/searching remote scopes failed with HTTP 410 CHANGE-2770 - Functionality has been deprecated:

(410) {"type":"error","error":{"message":"CHANGE-2770 - Functionality has been deprecated"}}
github.com/apache/incubator-devlake/plugins/bitbucket/api.listBitbucketWorkspaces
/app/plugins/bitbucket/api/remote_api.go:89

This PR migrates the plugin onto the supported workspace-scoped endpoints:

  • listBitbucketWorkspaces: replace GET /user/permissions/workspaces with the supported GET /workspaces (lists the current user's workspaces). Workspace slug/name now parsed from the top level of each value instead of a nested "workspace" object.
  • searchBitbucketRepos: replace cross-workspace GET /repositories?role=member with per-workspace GET /repositories/{workspace}, enumerating the user's workspaces first and aggregating up to PageSize matches.
  • models: flatten GroupResponse to match the /workspaces response shape.

The public remote-scopes / search-remote-scopes API contract is unchanged, so config-ui and Grafana need no changes.

Does this close any open issues?

N/A

Screenshots

N/A, no UI changes.

Other Information

Atlassian will not ship a cross-workspace /repositories replacement, so search now issues one request per workspace and collapses pagination to the first PageSize matches — the only path the new API surface allows.

Verified: go build ./plugins/bitbucket/... passes; manual smoke test against a Bitbucket Cloud connection (browse workspaces → repos, search remote scopes).

@KennethWKZ KennethWKZ marked this pull request as draft June 10, 2026 08:31
@KennethWKZ KennethWKZ marked this pull request as ready for review June 10, 2026 08:32
@klesh

klesh commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Nice. Did you test it locally?

- listBitbucketWorkspaces: replace GET /user/permissions/workspaces with the supported GET /workspaces (lists the current user's workspaces). Workspace slug/name now parsed from the top level of each value instead of a nested "workspace" object.
- searchBitbucketRepos: replace cross-workspace GET /repositories?role=member with per-workspace GET /repositories/{workspace}, enumerating the user's workspaces first and aggregating up to PageSize matches.
- models: flatten GroupResponse to match the /workspaces response shape.
@KennethWKZ KennethWKZ force-pushed the feature/fix-bitbucket-change-2770 branch from 4ac7d66 to a2a7abd Compare July 10, 2026 19:44
…E-2770)

GET /2.0/workspaces is also deprecated, not just /user/permissions/workspaces.
The supported replacement for enumerating the current user's workspaces is
GET /2.0/user/workspaces, which nests slug/name under a workspace object.

- remote_api.go: listBitbucketWorkspaces / listAllBitbucketWorkspaces now call
  /user/workspaces with workspace.* fields and read via GroupId()/GroupName().
- models/repo.go: re-nest GroupResponse under WorkspaceItem to match the
  /user/workspaces response shape.

Repo listing stays on the supported GET /2.0/repositories/{workspace}.
…ld name)

GET /2.0/user/workspaces rejects sort=workspace.slug with HTTP 400 'Invalid
field name'. The bare paginated call returns the nested workspace objects we
parse, so drop the sort/fields query params in both listBitbucketWorkspaces
and listAllBitbucketWorkspaces.
@KennethWKZ

Copy link
Copy Markdown
Author

Nice. Did you test it locally?

yes i testing in EC2 + self build docker image with pointing to our bitbucket cloud, working fine

Bitbucket has sunset the issue tracker/wiki API; the issues endpoint now
returns 410 Gone instead of 404. ignoreHTTPStatus404 only mapped 404 to
ErrIgnoreAndContinue, so a 410 fell through to nil, DoAsync retried 3x and
failed the whole pipeline ("Collect Issues ended unexpectedly").

Treat 410 like 404 (ignore and continue). Shared helper also covers issue
comments and pr commits. Adds a table test for the status-code mapping.
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.

2 participants