Uh oh!
There was an error while loading. Please reload this page.
fix(worker): include project key in Bitbucket repo identifiers - #904
Conversation
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>
WalkthroughBitbucket 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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
…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>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/backend/src/repoCompileUtils.ts (1)
457-461: Eliminate redundantfull_namesplit 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 inbitbucket.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.
Uh oh!
There was an error while loading. Please reload this page.
…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>
There was a problem hiding this comment.
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_workspaceuses lowercase snake_case, making it look like a real workspace slug rather than a placeholder — unlikePROJECT_KEY/SERVER_PROJECT_KEYwhich 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.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/backend/src/bitbucket.test.ts (1)
7-13:makeCloudRepoalways suppliesproject; no test exercises theundefinedproject pathEvery
cloudShouldExcludeRepotest usesproject: { type: 'project', key: 'PROJ' }. There is no test covering the case wherecloudRepo.projectis absent, which is the exact edge case that causes the silent"workspace/undefined/repo"naming bug inbitbucket.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',()=>{constrepoWithoutProject=makeCloudRepo({project: undefined});// Currently produces repoName "myworkspace/undefined/my-repo" – should not silently match patternsexpect(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.
Uh oh!
There was an error while loading. Please reload this page.
Summary
PROJECT/repo) instead of just the bare repo name, preventing collisions when multiple projects have repos with the same slugworkspace/PROJECT/repo) instead ofworkspace/repoBreaking Changes
Bitbucket Cloud users with
exclude.repospatterns will need to update them to include the project key:Bitbucket Server users are unaffected —
exclude.reposwas already usingPROJECT_KEY/repoformat.🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Documentation
workspace/PROJECT_KEY/repo).Migration Note
workspace/repotoworkspace/PROJECT_KEY/repoformat.