feat(bitbucket): add Bitbucket Cloud as a git provider (v2/AgentCore)#342
feat(bitbucket): add Bitbucket Cloud as a git provider (v2/AgentCore)#342smoell wants to merge 14 commits into
Conversation
End-to-end Bitbucket Cloud support across provider, Lambda, Terraform and frontend: OAuth connect, repo listing (/user/workspaces, CHANGE-2770), recursive getTree, just-in-time token refresh (both dispatch paths), SSM Intelligent-Tiering for JWT tokens, and automated PR creation at fan-in. Validated live: multi-unit intent -> 3 units/3 waves merged -> automated Bitbucket PR.
- trackers.test: stub BITBUCKET_OAUTH_SECRET_NAME so the 'all providers configured' assertion covers bitbucket-issues - projects.test: use 'subversion' as the invalid-provider example now that bitbucket is a valid provider - PlatformAdmin.test: expect the Bitbucket source-control card (2 badges) - terraform fmt -recursive alignment on main.tf
…fmt/terraform fmt - gitProvider.ts: reduce bitbucketService to the GitProviderService interface (getAuthUrl/getStatus/listRepos/disconnect) — branch/tree/contents/PR now go through the v2 sourceControlService (PR aws-samples#333); removes the undefined splitOwnerRepo reference that broke tsc - oxfmt + terraform fmt alignment after the upstream/main merge
…tion layer PR aws-samples#333 replaced the orchestrator-owned git-token resolution with the credential-broker. The merge kept HEAD's now-orphaned defaultResolveToken/ defaultMintFreshToken/defaultTokenIo/resolveAuthor/toRepoSlug, which referenced getGitHubAuthMode/getInstallationTokenFromConfig — both removed from github-auth-config.js in aws-samples#333. Removed the dead layer, its two test describe blocks, and the orphaned github_auth_mode_param terraform wiring (the var was never declared -> terraform validate failure). Bitbucket token refresh remains via source-control-credentials.js -> ensureFreshGitToken.
|
|
|
|
|
|
There was a problem hiding this comment.
https://support.atlassian.com/bitbucket-cloud/docs/understand-bitbucket-issues/ => bitbucket issues will be removed from bitbucket cloud in August 2026 and users are encouraged to move to Jira. We can also remove the tracker in collaborative aidlc.
Also see https://github.com/aws-samples/sample-collaborative-ai-dlc/tree/pr-342 for this (460c5f7) .
There was a problem hiding this comment.
Splitting this into its own follow-up PR rather than folding it into this one. Removing the bitbucket-issues tracker also requires a replacement admin surface for the Bitbucket OAuth-app credentials (new GET/PUT /bitbucket/oauth-config endpoint) and rewiring the Connect-button config gating, which currently keys off the tracker-provider status (/trackers/providers). That's a focused, self-contained change set that deserves its own review — I'll link it here.
|
Bitbucket Git-over-HTTPS requires |
| // Trackers that piggyback on a source-control OAuth app instead of having | ||
| // credentials of their own. | ||
| const GIT_BACKED_TRACKERS = new Set(['github-issues', 'gitlab-issues']); | ||
| const GIT_BACKED_TRACKERS = new Set(['github-issues', 'gitlab-issues', 'bitbucket-issues']); |
There was a problem hiding this comment.
https://support.atlassian.com/bitbucket-cloud/docs/understand-bitbucket-issues/ => bitbucket issues will be removed from bitbucket cloud in August 2026 and users are encouraged to move to Jira. We can also remove the tracker in collaborative aidlc.
Also see https://github.com/aws-samples/sample-collaborative-ai-dlc/tree/pr-342 for this (460c5f7) .
| } | ||
|
|
||
| const gitlabConfigured = isConfigured(providers, 'gitlab-issues'); | ||
| const bitbucketConfigured = isConfigured(providers, 'bitbucket-issues'); |
There was a problem hiding this comment.
If we remove issues, we should have another way to configure bitbucket oauth. (gitlab is using the tracker config, which is not a good idea, we should have a dedicated endpoint, see a2f11d5)
JWThewes
left a comment
There was a problem hiding this comment.
A few additional findings on top of Jerome's review — mostly in the provider module. Details inline.
| # were wired from day one but these env vars were MISSING — getGitConnection | ||
| # threw on TableName undefined, resolveToken degraded to an empty token, and | ||
| # a private-repo clone silently fell back to `git init` (see init-ws). | ||
| GIT_CONNECTIONS_TABLE = var.git_connections_table_name |
There was a problem hiding this comment.
These env-var additions (GIT_CONNECTIONS_TABLE, the GitLab secret, GitHub App params) fix a real pre-existing GitLab/GitHub App bug per the comments — but that makes them an unrelated fix riding in a 2,200-line Bitbucket PR, same as the kiro_model change Jerome flagged. Could you split the GitLab/GitHub-App orchestrator fix into its own PR? It deserves review on its own terms, and it shouldn't get reverted if this PR needs rework.
| // Bitbucket access/refresh tokens are JWTs (~2800+ chars) that | ||
| // exceed the SSM Standard-tier 4096-char cap. Intelligent-Tiering | ||
| // promotes to Advanced only when needed (no-op for short tokens). | ||
| Tier: 'Intelligent-Tiering', |
There was a problem hiding this comment.
Heads-up that this now applies to GitHub/GitLab token writes too, not just Bitbucket. Behaviorally it's a no-op under 4KB, but Intelligent-Tiering promotions to Advanced carry a per-parameter monthly cost — probably worth a one-line note in the PR description so operators aren't surprised.
…THUB_APP env - revert kiro_model to upstream 'claude-opus-4.6' (env-specific, out of scope for this PR) - remove GITHUB_APP_CONFIG_PARAM / GITHUB_APP_PRIVATE_KEY_SECRET_NAME from the trackers lambda: the trackers handler never reads them and the role has no matching grant (dead env vars from the merge)
- getFileContents: per-segment path encoding so nested files don't 404 - listBranches + listConstructionTaskBranches: follow pagination (data.next) so task branches beyond page 1 aren't missed by the fan-in merge check - isCommitAncestor: use the merge-base endpoint (1 call) instead of walking the full commit history (O(history) -> O(1), no 30s Lambda timeout) - listPRComments: single paginated pass partitioned by c.inline (was fetching the list twice) - mergeBranch: decline the temporary auto-merge PR on conflict/error so failed engine merges don't leave open PRs behind - comment/author mapping: nickname || display_name (username is GDPR-removed since 2019) and bot:false (type==='team' mislabeled workspace accounts)
…il scope (A3, B6) - getAuthenticatedUser: /user (login via nickname/display_name — username is GDPR-removed) + /user/emails (primary/confirmed) for commit attribution; falls back to a noreply email so attribution never blocks a run - getRepositoryAccess: repo object (default branch + visibility) + /user/permissions/repositories probe (admin/write/read); degrades to read-only if the probe fails rather than failing the bind - oauth: request the 'email' scope (required for getAuthenticatedUser email) - both methods now exported so the source-control binding contract can call them
…A1/A2, A4, B5, C14) - source-control-bindings: add bitbucket-oauth to AUTH_TYPES/AUTH_TYPE_PROVIDER and accept bitbucket in canonicalRepo (workspace/repo, same shape as github) - source-control-credentials: x-token-auth clone user for bitbucket + include bitbucket in the 401 refresh-and-retry callback (was gitlab-only) - frontend: add bitbucket-oauth to SourceControlAuthType; introduce SOURCE_CONTROL_AUTH_OPTIONS + defaultAuthTypeFor as the single source of truth, consumed by CreateProjectModal + SourceControlBindingSection instead of hard-coded provider ternaries - bitbucket adapter: use the native draft boolean (payload + PUT) instead of the fragile 'Draft:' title emulation; findPullRequest now names the draft field so draft PRs aren't hidden by the List-PR endpoint (BCLOUD-23659)
…b follow-up) - oxfmt formatting on sourceControl.ts + SourceControlBindingSection.tsx (CI format:check was failing on the committed sourceControl.ts) - RepositoriesTab.test: mock @/services/sourceControl via importOriginal so the new SOURCE_CONTROL_AUTH_OPTIONS + defaultAuthTypeFor exports resolve while only sourceControlService stays mocked
…lback (2b follow-up) - oxfmt formatting on sourceControl.ts + SourceControlBindingSection.tsx (CI format:check was failing on the committed sourceControl.ts) - defaultAuthTypeFor: accept a not-yet-selected provider (empty string in the create-project modal before a provider is picked) and fall back to github-app, matching the previous behaviour - CreateProjectModal.test + RepositoriesTab.test: mock @/services/sourceControl via importOriginal so the new SOURCE_CONTROL_AUTH_OPTIONS + defaultAuthTypeFor exports resolve (components read them on mount) while only sourceControlService stays mocked
… (B7) Mirror the gitlab_connector role so git-handler can invalidate bindings on disconnect / missing-scope / refresh failure: - add dynamodb:UpdateItem + dynamodb:Query and the source_control_bindings_table ARN (+ /index/*) to the bitbucket_connector role policy - add SOURCE_CONTROL_BINDINGS_TABLE env var to the bitbucket lambda
End-to-end Bitbucket Cloud support across provider, Lambda, Terraform and frontend: OAuth connect, repo listing (/user/workspaces, CHANGE-2770), recursive getTree, just-in-time token refresh (both dispatch paths), SSM Intelligent-Tiering for JWT tokens, and automated PR creation at fan-in. Validated live: multi-unit intent -> 3 units/3 waves merged -> automated Bitbucket PR.
Issue #, if available:
Description of changes:
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.