feat: configurable branch prefixes for v2 workspaces#4833
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (7)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughImplements v2 branch-prefixes: shared mode types, DB migration for host/project settings, prefix-resolution utilities (git/gh identity and collision guard), host-service routers, workspace integration applying prefixes to new branches, renderer global and per-project UI, tests, and docs. ChangesV2 Configurable Branch Prefixes
Sequence Diagram(s)sequenceDiagram
participant Renderer
participant HostService
participant DB
participant ExecGh as ExecGh/Git
Renderer->>HostService: GET settings.git.branchPrefix (branchPrefixRouter.get)
HostService->>DB: SELECT host_settings / projects
HostService->>ExecGh: resolveGitInfo (gh / git)
ExecGh-->>HostService: github username / author name
HostService-->>Renderer: branchPrefix mode + preview info
Renderer->>HostService: MUTATE settings.branchPrefix.set (persist)
HostService->>DB: UPSERT host_settings (id=1) or UPDATE project row
HostService-->>Renderer: success / error
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add 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 |
|
Capy auto-review is paused for this organization because the monthly auto-review limit has been reached. Increase the limit or turn it off in billing settings to resume automatic reviews. |
|
Ready to review this PR? Stage has broken it down into 7 individual chapters for you: Chapters generated by Stage for commit 2f78050 on May 24, 2026 5:50am UTC. |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/host-service/src/trpc/router/workspace-creation/utils/branch-prefix.test.ts (1)
56-140: ⚡ Quick winAdd
githubmode coverage (including fallback behavior).The suite currently exercises
none/custom/author, but not thegithubpath that depends onexecGhand fallback-to-author semantics. A focused test here would prevent regressions in the highest-risk branch of the resolver.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/host-service/src/trpc/router/workspace-creation/utils/branch-prefix.test.ts` around lines 56 - 140, Add tests in branch-prefix.test.ts exercising the "github" branchPrefixMode for resolveProjectBranchPrefix: (1) a test where execGh is stubbed to return a GitHub username and ensure resolveProjectBranchPrefix (called with project: makeProject({ branchPrefixMode: "github" }), ctx: makeCtx(createTestDb()), and git: gitWithAuthor(null)) returns the expected GH-based prefix; (2) a test where execGh is stubbed to throw or return null and ensure the code falls back to author semantics by passing git: gitWithAuthor("Jane Doe") and asserting the returned prefix equals the author-derived value; use the same helpers referenced in the suite (resolveProjectBranchPrefix, execGh stub, gitWithAuthor, makeProject, makeCtx, createTestDb, setGlobal where needed) to locate and implement the tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/host-service/drizzle/0005_branch_prefix_settings.sql`:
- Around line 1-5: The migration currently allows any id and any mode string;
change the host_settings table to enforce a single-row enum-backed record by
adding a CHECK constraint that id = 1 (to guarantee single-row semantics), make
branch_prefix_mode NOT NULL with a CHECK limiting values to the supported enum
(e.g., CHECK(branch_prefix_mode IN ('off','include','prefix'))) and set a
sensible DEFAULT (e.g., 'off'), and tighten branch_prefix_custom (NOT NULL
DEFAULT '' and optionally a conditional CHECK such as CHECK(branch_prefix_mode
<> 'prefix' OR (branch_prefix_custom IS NOT NULL AND branch_prefix_custom <>
'')) ) so invalid combinations are prevented; apply these changes to the CREATE
TABLE for host_settings and any related INSERT/UPDATE paths that assume those
defaults.
---
Nitpick comments:
In
`@packages/host-service/src/trpc/router/workspace-creation/utils/branch-prefix.test.ts`:
- Around line 56-140: Add tests in branch-prefix.test.ts exercising the "github"
branchPrefixMode for resolveProjectBranchPrefix: (1) a test where execGh is
stubbed to return a GitHub username and ensure resolveProjectBranchPrefix
(called with project: makeProject({ branchPrefixMode: "github" }), ctx:
makeCtx(createTestDb()), and git: gitWithAuthor(null)) returns the expected
GH-based prefix; (2) a test where execGh is stubbed to throw or return null and
ensure the code falls back to author semantics by passing git:
gitWithAuthor("Jane Doe") and asserting the returned prefix equals the
author-derived value; use the same helpers referenced in the suite
(resolveProjectBranchPrefix, execGh stub, gitWithAuthor, makeProject, makeCtx,
createTestDb, setGlobal where needed) to locate and implement the tests.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d39c5171-5b22-43c3-8e9b-dc01fc4af6ef
📒 Files selected for processing (19)
apps/desktop/src/renderer/routes/_authenticated/settings/git/components/V2GitSettings/V2GitSettings.tsxapps/desktop/src/renderer/routes/_authenticated/settings/git/components/V2GitSettings/index.tsapps/desktop/src/renderer/routes/_authenticated/settings/git/page.tsxapps/desktop/src/renderer/routes/_authenticated/settings/utils/settings-search/settings-search.tsapps/desktop/src/renderer/routes/_authenticated/settings/v2-project/$projectId/components/V2ProjectSettings/V2ProjectSettings.tsxapps/desktop/src/renderer/routes/_authenticated/settings/v2-project/$projectId/components/V2ProjectSettings/components/BranchPrefixSection/BranchPrefixSection.tsxapps/desktop/src/renderer/routes/_authenticated/settings/v2-project/$projectId/components/V2ProjectSettings/components/BranchPrefixSection/index.tspackages/host-service/drizzle/0005_branch_prefix_settings.sqlpackages/host-service/drizzle/meta/0005_snapshot.jsonpackages/host-service/drizzle/meta/_journal.jsonpackages/host-service/src/db/schema.tspackages/host-service/src/trpc/router/project/project.tspackages/host-service/src/trpc/router/settings/branch-prefix.tspackages/host-service/src/trpc/router/settings/index.tspackages/host-service/src/trpc/router/workspace-creation/utils/branch-prefix.test.tspackages/host-service/src/trpc/router/workspace-creation/utils/branch-prefix.tspackages/host-service/src/trpc/router/workspaces/workspaces.tspackages/shared/src/workspace-launch/branch.tsplans/v2-branch-prefixes.md
| CREATE TABLE `host_settings` ( | ||
| `id` integer PRIMARY KEY DEFAULT 1 NOT NULL, | ||
| `branch_prefix_mode` text, | ||
| `branch_prefix_custom` text | ||
| ); |
There was a problem hiding this comment.
Enforce host_settings invariants at the DB layer.
host_settings is modeled as a single-row enum-backed table, but this migration currently permits any id and any mode string. A stray insert/update can make settings reads nondeterministic or return unsupported mode values.
Suggested migration hardening
CREATE TABLE `host_settings` (
- `id` integer PRIMARY KEY DEFAULT 1 NOT NULL,
- `branch_prefix_mode` text,
+ `id` integer PRIMARY KEY DEFAULT 1 NOT NULL CHECK (`id` = 1),
+ `branch_prefix_mode` text CHECK (
+ `branch_prefix_mode` IN ('none', 'github', 'author', 'custom')
+ OR `branch_prefix_mode` IS NULL
+ ),
`branch_prefix_custom` text
);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| CREATE TABLE `host_settings` ( | |
| `id` integer PRIMARY KEY DEFAULT 1 NOT NULL, | |
| `branch_prefix_mode` text, | |
| `branch_prefix_custom` text | |
| ); | |
| CREATE TABLE `host_settings` ( | |
| `id` integer PRIMARY KEY DEFAULT 1 NOT NULL CHECK (`id` = 1), | |
| `branch_prefix_mode` text CHECK ( | |
| `branch_prefix_mode` IN ('none', 'github', 'author', 'custom') | |
| OR `branch_prefix_mode` IS NULL | |
| ), | |
| `branch_prefix_custom` text | |
| ); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/host-service/drizzle/0005_branch_prefix_settings.sql` around lines 1
- 5, The migration currently allows any id and any mode string; change the
host_settings table to enforce a single-row enum-backed record by adding a CHECK
constraint that id = 1 (to guarantee single-row semantics), make
branch_prefix_mode NOT NULL with a CHECK limiting values to the supported enum
(e.g., CHECK(branch_prefix_mode IN ('off','include','prefix'))) and set a
sensible DEFAULT (e.g., 'off'), and tighten branch_prefix_custom (NOT NULL
DEFAULT '' and optionally a conditional CHECK such as CHECK(branch_prefix_mode
<> 'prefix' OR (branch_prefix_custom IS NOT NULL AND branch_prefix_custom <>
'')) ) so invalid combinations are prevented; apply these changes to the CREATE
TABLE for host_settings and any related INSERT/UPDATE paths that assume those
defaults.
Greptile SummaryThis PR ports the v1 branch-prefix feature to the v2 (host-service) workspace flow, adding a two-tier configuration (host-wide default + per-project override) with four modes (
Confidence Score: 4/5Safe to merge — the core cascade and collision-guard logic is correct, the migration is additive, and the existing workspace creation path for PR checkouts and existing branches is unaffected. The new prefix resolution code is well-structured and the happy path is thoroughly covered. The two non-test findings (double-prefix on manually-typed names and misleading Custom UI state when the prefix is cleared) are edge cases that won't break any existing workspace creation flows. The github mode gap in the test suite is the main thing that could hide a regression silently. workspaces.ts around the typed-branch prefix block (double-prefix guard) and branch-prefix.test.ts (missing github mode coverage).
|
| Filename | Overview |
|---|---|
| packages/host-service/src/trpc/router/workspace-creation/utils/branch-prefix.ts | Core prefix resolution logic with cascade (project → host default) and collision guard; github mode correctly fetches authorName as fallback; module-level githubUsernameCache singleton is appropriate for single-user desktop use |
| packages/host-service/src/trpc/router/workspaces/workspaces.ts | Prefix applied in both typed-branch and auto-gen paths; typed-branch path correctly guards !plan.usedExistingBranch; listBranchNames added to the parallel fetch; plan spread keeps original startPoint which is correct since the branch was confirmed non-existent |
| packages/host-service/src/trpc/router/workspace-creation/utils/branch-prefix.test.ts | 7 tests covering cascade, collision, and author mode; github mode (with its caching and authorName fallback) is not covered at all |
| packages/host-service/src/trpc/router/settings/branch-prefix.ts | Host-wide default stored via upsert on id=1 singleton row; gitInfo query surfaces author/username for UI preview; synchronous Drizzle .run() / .get() API used consistently |
| apps/desktop/src/renderer/routes/_authenticated/settings/git/components/V2GitSettings/V2GitSettings.tsx | Host-wide default UI; handleCustomPrefixBlur can persist mode:custom with a null prefix when the input is cleared, leaving the select showing Custom while no prefix is actually applied |
| apps/desktop/src/renderer/routes/_authenticated/settings/v2-project/$projectId/components/V2ProjectSettings/components/BranchPrefixSection/BranchPrefixSection.tsx | Per-project override with use-global-default option; same handleCustomPrefixBlur pattern as V2GitSettings — clears prefix but keeps mode:custom |
Sequence Diagram
sequenceDiagram
participant UI as Renderer
participant PR as tRPC router
participant DB as host-service SQLite
participant WS as workspaces.create
participant BP as resolveProjectBranchPrefix
participant GH as gh CLI / git config
UI->>PR: settings.branchPrefix.set
PR->>DB: UPSERT host_settings
UI->>PR: project.setBranchPrefix
PR->>DB: UPDATE projects
WS->>DB: SELECT project
WS->>BP: resolveProjectBranchPrefix
BP->>DB: SELECT host_settings
alt "mode == github"
BP->>GH: gh api user (cached 5 min)
BP->>GH: git config user.name (fallback)
else "mode == author"
BP->>GH: git config user.name
end
BP->>BP: collision guard
BP-->>WS: prefix or undefined
alt typed branch and not usedExistingBranch
WS->>WS: deduplicateBranchName(prefix/branch)
else auto-gen branch
WS->>WS: deduplicateBranchName(prefix/candidate)
end
Comments Outside Diff (1)
-
packages/host-service/src/trpc/router/workspace-creation/utils/branch-prefix.test.ts, line 1290-1374 (link)githubmode has no test coverageThe suite exercises
none, host-default fallback, project override, null-mode inheritance,none-override, collision guard, andauthormode — butgithubmode is never tested.githubmode has two unique behaviours that are easy to regress: (1) it fetches the GitHub username via theghCLI and caches the result in a module-level singleton (githubUsernameCache), and (2) it falls back toauthorPrefixwhen the username is unavailable (githubUsername || authorPrefix || nullinresolveBranchPrefix). A test with a stubbedexecGhreturning a username, and another whereexecGhthrows (forcing theauthorNamefallback path), would cover both branches and the cache behaviour.Prompt To Fix With AI
This is a comment left during a code review. Path: packages/host-service/src/trpc/router/workspace-creation/utils/branch-prefix.test.ts Line: 1290-1374 Comment: **`github` mode has no test coverage** The suite exercises `none`, host-default fallback, project override, null-mode inheritance, `none`-override, collision guard, and `author` mode — but `github` mode is never tested. `github` mode has two unique behaviours that are easy to regress: (1) it fetches the GitHub username via the `gh` CLI and caches the result in a module-level singleton (`githubUsernameCache`), and (2) it falls back to `authorPrefix` when the username is unavailable (`githubUsername || authorPrefix || null` in `resolveBranchPrefix`). A test with a stubbed `execGh` returning a username, and another where `execGh` throws (forcing the `authorName` fallback path), would cover both branches and the cache behaviour. How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 3
packages/host-service/src/trpc/router/workspace-creation/utils/branch-prefix.test.ts:1290-1374
**`github` mode has no test coverage**
The suite exercises `none`, host-default fallback, project override, null-mode inheritance, `none`-override, collision guard, and `author` mode — but `github` mode is never tested. `github` mode has two unique behaviours that are easy to regress: (1) it fetches the GitHub username via the `gh` CLI and caches the result in a module-level singleton (`githubUsernameCache`), and (2) it falls back to `authorPrefix` when the username is unavailable (`githubUsername || authorPrefix || null` in `resolveBranchPrefix`). A test with a stubbed `execGh` returning a username, and another where `execGh` throws (forcing the `authorName` fallback path), would cover both branches and the cache behaviour.
### Issue 2 of 3
packages/host-service/src/trpc/router/workspaces/workspaces.ts:839-856
**Double-prefix when user types a name that already includes the prefix**
`planBranchSource` is called with the raw `typedBranch` (e.g. `censys/feature`) before the prefix is known. If that branch doesn't exist, `usedExistingBranch` is `false` and the prefix is unconditionally prepended, producing `censys/censys/feature`. A user who is aware of their prefix and manually namespaces their branch will silently end up on a double-nested ref. The PR description doesn't address this case. A simple guard — checking whether `typedBranch` already starts with `${prefix}/` before prepending — would prevent the double-prefix without changing any other behaviour.
### Issue 3 of 3
apps/desktop/src/renderer/routes/_authenticated/settings/git/components/V2GitSettings/V2GitSettings.tsx:113-117
**Clearing the custom prefix persists `mode:"custom"` with a null value**
When the user deletes the text in the custom-prefix input and blurs, `sanitizeSegment("")` returns `""`, which is then coerced to `null` by `sanitized || null`. The mutation saves `{ mode: "custom", customPrefix: null }`. `resolveBranchPrefix` returns `null` for this state (`customPrefix || null`), so no prefix is applied — but the Select still shows "Custom". A user who clears the field expecting "Custom" to stop applying a prefix will see the correct preview (just `branch-name`) but the mode label is misleading. The same pattern is present in `BranchPrefixSection.tsx`. Switching `mode` back to `"none"` when the sanitized value is empty would make the saved state match the user's intent.
Reviews (1): Last reviewed commit: "feat(host-service): configurable branch ..." | Re-trigger Greptile
| // Namespace newly-created branches under the configured | ||
| // prefix. A typed branch that resolves to an existing ref is | ||
| // checked out as-is and never re-prefixed. | ||
| if (!plan.usedExistingBranch) { | ||
| const prefix = await resolveProjectBranchPrefix({ | ||
| ctx, | ||
| project: localProject, | ||
| git, | ||
| existingBranches: existing, | ||
| }); | ||
| if (prefix) { | ||
| resolvedBranch = deduplicateBranchName( | ||
| `${prefix}/${resolvedBranch}`, | ||
| existing, | ||
| ); | ||
| plan = { ...plan, branch: resolvedBranch }; | ||
| } | ||
| } |
There was a problem hiding this comment.
Double-prefix when user types a name that already includes the prefix
planBranchSource is called with the raw typedBranch (e.g. censys/feature) before the prefix is known. If that branch doesn't exist, usedExistingBranch is false and the prefix is unconditionally prepended, producing censys/censys/feature. A user who is aware of their prefix and manually namespaces their branch will silently end up on a double-nested ref. The PR description doesn't address this case. A simple guard — checking whether typedBranch already starts with ${prefix}/ before prepending — would prevent the double-prefix without changing any other behaviour.
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/host-service/src/trpc/router/workspaces/workspaces.ts
Line: 839-856
Comment:
**Double-prefix when user types a name that already includes the prefix**
`planBranchSource` is called with the raw `typedBranch` (e.g. `censys/feature`) before the prefix is known. If that branch doesn't exist, `usedExistingBranch` is `false` and the prefix is unconditionally prepended, producing `censys/censys/feature`. A user who is aware of their prefix and manually namespaces their branch will silently end up on a double-nested ref. The PR description doesn't address this case. A simple guard — checking whether `typedBranch` already starts with `${prefix}/` before prepending — would prevent the double-prefix without changing any other behaviour.
How can I resolve this? If you propose a fix, please make it concise.| return ( | ||
| <div className="p-6 max-w-4xl w-full"> | ||
| <div className="mb-8"> | ||
| <h2 className="text-xl font-semibold">Git & worktrees</h2> | ||
| <p className="text-sm text-muted-foreground mt-1"> |
There was a problem hiding this comment.
Clearing the custom prefix persists
mode:"custom" with a null value
When the user deletes the text in the custom-prefix input and blurs, sanitizeSegment("") returns "", which is then coerced to null by sanitized || null. The mutation saves { mode: "custom", customPrefix: null }. resolveBranchPrefix returns null for this state (customPrefix || null), so no prefix is applied — but the Select still shows "Custom". A user who clears the field expecting "Custom" to stop applying a prefix will see the correct preview (just branch-name) but the mode label is misleading. The same pattern is present in BranchPrefixSection.tsx. Switching mode back to "none" when the sanitized value is empty would make the saved state match the user's intent.
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/routes/_authenticated/settings/git/components/V2GitSettings/V2GitSettings.tsx
Line: 113-117
Comment:
**Clearing the custom prefix persists `mode:"custom"` with a null value**
When the user deletes the text in the custom-prefix input and blurs, `sanitizeSegment("")` returns `""`, which is then coerced to `null` by `sanitized || null`. The mutation saves `{ mode: "custom", customPrefix: null }`. `resolveBranchPrefix` returns `null` for this state (`customPrefix || null`), so no prefix is applied — but the Select still shows "Custom". A user who clears the field expecting "Custom" to stop applying a prefix will see the correct preview (just `branch-name`) but the mode label is misleading. The same pattern is present in `BranchPrefixSection.tsx`. Switching `mode` back to `"none"` when the sanitized value is empty would make the saved state match the user's intent.
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
2 issues found across 19 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/host-service/src/trpc/router/workspaces/workspaces.ts">
<violation number="1" location="packages/host-service/src/trpc/router/workspaces/workspaces.ts:842">
P2: Typed branch creation can incorrectly create a suffixed new branch when the prefixed branch already exists, because existence is checked before applying the prefix.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| if (!plan.usedExistingBranch) { | ||
| const prefix = await resolveProjectBranchPrefix({ | ||
| ctx, | ||
| project: localProject, | ||
| git, | ||
| existingBranches: existing, | ||
| }); | ||
| if (prefix) { | ||
| resolvedBranch = deduplicateBranchName( | ||
| `${prefix}/${resolvedBranch}`, | ||
| existing, | ||
| ); | ||
| plan = { ...plan, branch: resolvedBranch }; | ||
| } | ||
| } |
There was a problem hiding this comment.
P2: Typed branch creation can incorrectly create a suffixed new branch when the prefixed branch already exists, because existence is checked before applying the prefix.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/host-service/src/trpc/router/workspaces/workspaces.ts, line 842:
<comment>Typed branch creation can incorrectly create a suffixed new branch when the prefixed branch already exists, because existence is checked before applying the prefix.</comment>
<file context>
@@ -828,12 +829,31 @@ export const workspacesRouter = router({
+ // Namespace newly-created branches under the configured
+ // prefix. A typed branch that resolves to an existing ref is
+ // checked out as-is and never re-prefixed.
+ if (!plan.usedExistingBranch) {
+ const prefix = await resolveProjectBranchPrefix({
+ ctx,
</file context>
| if (!plan.usedExistingBranch) { | |
| const prefix = await resolveProjectBranchPrefix({ | |
| ctx, | |
| project: localProject, | |
| git, | |
| existingBranches: existing, | |
| }); | |
| if (prefix) { | |
| resolvedBranch = deduplicateBranchName( | |
| `${prefix}/${resolvedBranch}`, | |
| existing, | |
| ); | |
| plan = { ...plan, branch: resolvedBranch }; | |
| } | |
| } | |
| if (!plan.usedExistingBranch) { | |
| const prefix = await resolveProjectBranchPrefix({ | |
| ctx, | |
| project: localProject, | |
| git, | |
| existingBranches: existing, | |
| }); | |
| if (prefix) { | |
| const prefixedBranch = `${prefix}/${resolvedBranch}`; | |
| const prefixedPlan = await planBranchSource( | |
| git, | |
| prefixedBranch, | |
| input.baseBranch, | |
| ); | |
| if (prefixedPlan.usedExistingBranch) { | |
| resolvedBranch = prefixedBranch; | |
| plan = prefixedPlan; | |
| } else { | |
| resolvedBranch = deduplicateBranchName(prefixedBranch, existing); | |
| plan = { ...plan, branch: resolvedBranch }; | |
| } | |
| } | |
| } |
🚀 Preview Deployment🔗 Preview Links
Preview updates automatically with new commits |
- Cut the 5-min GitHub-username cache in the host-service resolver. Workspace creates aren't a hot path and the cache was a stale-account footgun on `gh auth switch`. The renderer preview already has a 5-min `staleTime`. - Single source for `BranchPrefixMode` — `@superset/local-db` re-exports from `@superset/shared/workspace-launch`. No more drift risk between the two. - Extract `BranchPrefixControl` used by both `V2GitSettings` (host-wide) and `BranchPrefixSection` (per-project, `showDefault`). Empty custom-prefix on blur no longer fires a misleading `mode=custom, customPrefix=null` write.
Summary
Brings back v1's branch prefix feature for the v2 (host-service) workspace flow — requested by Censys (SUPER-835) for their org-wide v2 trial.
v1 stored prefixes in the desktop's local SQLite and applied them at workspace creation; v2 creates workspaces in
packages/host-service, which had no prefix support. This restores full v1 parity: host-local storage, a global default plus per-project overrides, and all four modes (none/github/author/custom).Behaviour
prefix/branch-name.Changes
@superset/shared— exportsBRANCH_PREFIX_MODES/BranchPrefixMode(host-service can't depend on@superset/local-db).projects.branchPrefixMode/branchPrefixCustomcolumns + single-rowhost_settingstable; migration0005(auto-applies on startup).resolveProjectBranchPrefixutil (cascade + collision guard),settings.branchPrefix.{get,set,gitInfo}router,project.get/setBranchPrefix, and prefix application inworkspaces.create.V2GitSettings(host-wide default on/settings/git) and a per-projectBranchPrefixSectioninV2ProjectSettings.Plan doc:
plans/v2-branch-prefixes.md.Test Plan
typecheck— host-service, shared, desktoplint— cleanbranch-prefix.test.ts— 7 tests for cascade + collision; mutation-testedSummary by cubic
Adds configurable branch prefixes to v2 workspaces, matching v1: host-wide default and per‑project overrides (
none,github,author,custom). Applied only to new branches with collision guards; includes an auto‑applied DB migration and delivers SUPER‑835 for Censys.New Features
host_settings; tRPCsettings.branchPrefix.{get,set,gitInfo}; per‑project override viaprojects.branchPrefixMode/branchPrefixCustomandproject.setBranchPrefix.workspaces.createusingresolveProjectBranchPrefix(reads gituser.name/ghforauthor/github, drops prefixes that collide with existing branches).V2GitSettingson/settings/git(global default) andBranchPrefixSectioninV2ProjectSettings(project override).BRANCH_PREFIX_MODES/BranchPrefixModelive in@superset/shared;@superset/local-dbre‑exports them to keep a single source of truth.Refactors
gh auth switch(the renderer preview still uses a 5‑minute stale time).BranchPrefixControlused by bothV2GitSettingsand the project settings section.Written for commit 2f78050. Summary will update on new commits. Review in cubic
Summary by CodeRabbit
New Features
Bug Fixes / Behavior