Skip to content

fix(worker): include project key in Bitbucket repo identifiers#904

Merged
brendan-kellam merged 9 commits intomainfrom
brendan/fix-bitbucket-repo-name-project-key-SOU-513
Feb 18, 2026
Merged

fix(worker): include project key in Bitbucket repo identifiers#904
brendan-kellam merged 9 commits intomainfrom
brendan/fix-bitbucket-repo-name-project-key-SOU-513

Conversation

@brendan-kellam
Copy link
Contributor

@brendan-kellam brendan-kellam commented Feb 18, 2026

Summary

  • For Bitbucket Server, repo identifiers now include the project key (PROJECT/repo) instead of just the bare repo name, preventing collisions when multiple projects have repos with the same slug
  • For Bitbucket Cloud, repo identifiers now include the project key (workspace/PROJECT/repo) instead of workspace/repo

Breaking Changes

Bitbucket Cloud users with exclude.repos patterns will need to update them to include the project key:

# Before
"exclude": { "repos": ["myworkspace/my-repo"] }

# After
"exclude": { "repos": ["myworkspace/PROJECT_KEY/my-repo"] }

Bitbucket Server users are unaffected — exclude.repos was already using PROJECT_KEY/repo format.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Fixed Bitbucket Server and Cloud repository identifier collision issue by including project key in identifiers.
  • Documentation

    • Updated exclude.repos configuration examples to reflect new required format: include project key in repository paths (e.g., workspace/PROJECT_KEY/repo).
  • Migration Note

    • Bitbucket Cloud users must update exclude.repos patterns from workspace/repo to workspace/PROJECT_KEY/repo format.

brendan-kellam and others added 2 commits February 18, 2026 14:32
For Bitbucket Server, repo names now include the project key (PROJECT/repo)
instead of just the repo name, preventing collisions across projects.
For Bitbucket Cloud, repo names now include the project key (workspace/PROJECT/repo)
instead of just workspace/repo.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 18, 2026

Walkthrough

Bitbucket repository identifiers and displayName construction now include project keys: Server repos use "PROJECT_KEY/repoSlug"; Cloud repos use "workspace/PROJECT_KEY/repoSlug". Documentation, schemas, tests, and a changelog entry were updated accordingly.

Changes

Cohort / File(s) Summary
Changelog
CHANGELOG.md
Added an unreleased entry documenting the fix to include project keys in Bitbucket repo identifiers to prevent cross-project collisions.
Backend: displayName & exclusion logic
packages/backend/src/repoCompileUtils.ts, packages/backend/src/bitbucket.ts, packages/backend/src/bitbucket.test.ts
DisplayName generation for Bitbucket changed: server repos use project.key/slug; cloud repos use workspace/project.key/slug. Two exclusion helpers (cloudShouldExcludeRepo, serverShouldExcludeRepo) are exported and tests added/updated to cover new repoName derivation and exclusion scenarios.
Schemas & docs (examples)
packages/schemas/src/v3/bitbucket.schema.ts, packages/schemas/src/v3/connection.schema.ts, packages/schemas/src/v3/index.schema.ts, schemas/v3/bitbucket.json, docs/snippets/schemas/v3/*.mdx
Updated example values for exclude.repos to include PROJECT_KEY/SERVER_PROJECT_KEY placeholders (e.g., cloud_workspace/PROJECT_KEY/repo1, SERVER_PROJECT_KEY/repo2). No validation or type changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Display name improvements #259 — Modifies repository displayName construction and related backend handling; likely related to these displayName/exclude changes.

Suggested reviewers

  • msukkari
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main functional change: including project keys in Bitbucket repo identifiers to fix cross-project collision issues.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch brendan/fix-bitbucket-repo-name-project-key-SOU-513

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

brendan-kellam and others added 2 commits February 18, 2026 14:34
…format

Update cloudShouldExcludeRepo to match against workspace/PROJECT_KEY/repo
instead of full_name (workspace/repo), consistent with the new displayName
format. Also update schema examples to reflect the correct formats.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/backend/src/repoCompileUtils.ts (1)

457-461: Eliminate redundant full_name split by extracting both parts at once

full_name!.split('/') is called twice to extract workspace and repo slug. A single split with destructuring is cleaner and more efficient. This pattern is already used correctly in bitbucket.ts:

Suggested fix
-            `${(repo as BitbucketCloudRepository).full_name!.split('/')[0]}/${(repo as BitbucketCloudRepository).project?.key}/${(repo as BitbucketCloudRepository).full_name!.split('/')[1]}`;
+            (() => {
+                const [workspace, repoSlug] = (repo as BitbucketCloudRepository).full_name!.split('/');
+                return `${workspace}/${(repo as BitbucketCloudRepository).project?.key}/${repoSlug}`;
+            })();

Or extract the variables before the ternary for clarity.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/backend/src/repoCompileUtils.ts` around lines 457 - 461, The
displayName construction redundantly calls (repo as
BitbucketCloudRepository).full_name!.split('/') twice; modify the logic so you
split full_name once (e.g., const [workspace, repoSlug] = (repo as
BitbucketCloudRepository).full_name!.split('/')) and use those variables in the
ternary that builds displayName (the branch that handles
BitbucketCloudRepository), keeping the existing BitbucketServerRepository branch
unchanged; you can perform the split immediately before the ternary or extract
workspace/repoSlug above the displayName assignment, similar to the pattern used
in bitbucket.ts.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/backend/src/repoCompileUtils.ts`:
- Line 461: The template literal that constructs displayName currently uses
(repo as BitbucketCloudRepository).project?.key which serializes undefined into
the string "undefined" and corrupts repo identifiers (propagating to repoName,
zoekt.name, and zoekt.display-name); update the code that builds displayName
(and any upstream uses) to explicitly validate that (repo as
BitbucketCloudRepository).project?.key is present and non-empty, and fail loudly
(throw an Error or return early) with a clear message referencing the missing
project key instead of interpolating undefined; ensure the same validation logic
mirrors the server branch behavior (project!.key) semantics so missing project
keys are detected rather than embedded.

---

Nitpick comments:
In `@packages/backend/src/repoCompileUtils.ts`:
- Around line 457-461: The displayName construction redundantly calls (repo as
BitbucketCloudRepository).full_name!.split('/') twice; modify the logic so you
split full_name once (e.g., const [workspace, repoSlug] = (repo as
BitbucketCloudRepository).full_name!.split('/')) and use those variables in the
ternary that builds displayName (the branch that handles
BitbucketCloudRepository), keeping the existing BitbucketServerRepository branch
unchanged; you can perform the split immediately before the ternary or extract
workspace/repoSlug above the displayName assignment, similar to the pattern used
in bitbucket.ts.

brendan-kellam and others added 5 commits February 18, 2026 14:42
…format

Update cloudShouldExcludeRepo to match against workspace/PROJECT_KEY/repo
instead of full_name (workspace/repo), consistent with the new displayName
format. Also update schema examples to reflect the correct formats.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…displayName

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/schemas/src/v3/bitbucket.schema.ts (1)

106-107: Optional: align placeholder casing for the Cloud workspace segment.

cloud_workspace uses lowercase snake_case, making it look like a real workspace slug rather than a placeholder — unlike PROJECT_KEY / SERVER_PROJECT_KEY which are clearly uppercase tokens. Capitalizing it improves clarity for users reading the examples.

✨ Suggested clarification
-              "cloud_workspace/PROJECT_KEY/repo1",
-              "SERVER_PROJECT_KEY/repo2"
+              "WORKSPACE/PROJECT_KEY/repo1",
+              "SERVER_PROJECT_KEY/repo2"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/schemas/src/v3/bitbucket.schema.ts` around lines 106 - 107, Update
the example placeholder in the Bitbucket schema so the Cloud workspace segment
uses an uppercase token to match the style of PROJECT_KEY/SERVER_PROJECT_KEY:
replace the string "cloud_workspace/PROJECT_KEY/repo1" with a tokenized
placeholder like "CLOUD_WORKSPACE/PROJECT_KEY/repo1" in the bitbucket.schema
(the example array that currently contains "cloud_workspace/PROJECT_KEY/repo1",
"SERVER_PROJECT_KEY/repo2") so the workspace placeholder is clearly a token
rather than a real slug.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/backend/src/bitbucket.ts`:
- Around line 351-352: The code builds repoName using cloudRepo.project?.key
which yields "undefined" when project is missing; make this consistent with
other code that assumes a project exists or provide a safe fallback: either
assert the project key is present (use cloudRepo.project?.key! when you have
validated project earlier) or replace the expression with a fallback such as
const projectKey = cloudRepo.project?.key ?? '<no-project>' and then construct
repoName = `${workspace}/${projectKey}/${repoSlug}`; ensure the chosen approach
matches the assumption in functions like repoCompileUtils
(cloudRepo.project?.key!) and avoid emitting the literal "undefined".

---

Nitpick comments:
In `@packages/schemas/src/v3/bitbucket.schema.ts`:
- Around line 106-107: Update the example placeholder in the Bitbucket schema so
the Cloud workspace segment uses an uppercase token to match the style of
PROJECT_KEY/SERVER_PROJECT_KEY: replace the string
"cloud_workspace/PROJECT_KEY/repo1" with a tokenized placeholder like
"CLOUD_WORKSPACE/PROJECT_KEY/repo1" in the bitbucket.schema (the example array
that currently contains "cloud_workspace/PROJECT_KEY/repo1",
"SERVER_PROJECT_KEY/repo2") so the workspace placeholder is clearly a token
rather than a real slug.

@brendan-kellam brendan-kellam changed the title fix(backend): include project key in Bitbucket repo identifiers fix(worker): include project key in Bitbucket repo identifiers Feb 18, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/backend/src/bitbucket.test.ts (1)

7-13: makeCloudRepo always supplies project; no test exercises the undefined project path

Every cloudShouldExcludeRepo test uses project: { type: 'project', key: 'PROJ' }. There is no test covering the case where cloudRepo.project is absent, which is the exact edge case that causes the silent "workspace/undefined/repo" naming bug in bitbucket.ts. Adding such a test now would either document the current broken behaviour or catch a fix:

test('returns false (or throws) when project is undefined', () => {
    const repoWithoutProject = makeCloudRepo({ project: undefined });
    // Currently produces repoName "myworkspace/undefined/my-repo" – should not silently match patterns
    expect(cloudShouldExcludeRepo(repoWithoutProject, {
        ...baseConfig,
        exclude: { repos: ['myworkspace/PROJ/my-repo'] },
    })).toBe(false);
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/backend/src/bitbucket.test.ts` around lines 7 - 13, The factory
makeCloudRepo currently always injects project into the returned
CloudRepository, so tests never exercise the code path where project is
undefined; update makeCloudRepo to allow omitting project by not providing a
default project property (i.e., accept overrides and only spread project when
provided) and then add a unit test that calls makeCloudRepo({ project: undefined
}) and asserts cloudShouldExcludeRepo(repoWithoutProject, { ...baseConfig,
exclude: { repos: ['myworkspace/PROJ/my-repo'] } }) behaves correctly; reference
makeCloudRepo, CloudRepository/BitbucketRepository and cloudShouldExcludeRepo
when locating the factory and the test to modify.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@packages/backend/src/bitbucket.ts`:
- Around line 351-352: The repoName construction silently embeds the string
"undefined" because `${cloudRepo.project?.key}` coerces undefined; change the
logic that builds repoName (where cloudRepo.full_name is split into workspace
and repoSlug and repoName is set) to explicitly check cloudRepo.project?.key: if
project.key exists use `${workspace}/${cloudRepo.project.key}/${repoSlug}`,
otherwise fall back to `${workspace}/${repoSlug}` (or another explicit sentinel)
so you never interpolate an undefined into the identifier; alternatively, if you
want failures surfaced, consistently use a non-null assertion
(`cloudRepo.project!.key`) across code (e.g., match repoCompileUtils.ts) so a
missing project throws early—pick one approach and apply it to the repoName
assignment and any related debug/log outputs.

---

Nitpick comments:
In `@packages/backend/src/bitbucket.test.ts`:
- Around line 7-13: The factory makeCloudRepo currently always injects project
into the returned CloudRepository, so tests never exercise the code path where
project is undefined; update makeCloudRepo to allow omitting project by not
providing a default project property (i.e., accept overrides and only spread
project when provided) and then add a unit test that calls makeCloudRepo({
project: undefined }) and asserts cloudShouldExcludeRepo(repoWithoutProject, {
...baseConfig, exclude: { repos: ['myworkspace/PROJ/my-repo'] } }) behaves
correctly; reference makeCloudRepo, CloudRepository/BitbucketRepository and
cloudShouldExcludeRepo when locating the factory and the test to modify.

@brendan-kellam brendan-kellam merged commit 5f3c173 into main Feb 18, 2026
14 checks passed
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

Comments