Skip to content

Commit 16ee99f

Browse files
SaxonFsweatybridgejoshenlim
authored
Chore/branch feature preview (supabase#37135)
* add default main branch if none exists * replace feature flag with feature preview * add image * add behind feature flag * Update apps/studio/components/interfaces/App/FeaturePreview/Branching2Preview.tsx Co-authored-by: Han Qiao <[email protected]> * Update apps/studio/components/interfaces/App/FeaturePreview/Branching2Preview.tsx Co-authored-by: Han Qiao <[email protected]> * Update apps/studio/components/interfaces/App/FeaturePreview/Branching2Preview.tsx Co-authored-by: Han Qiao <[email protected]> * Update apps/studio/components/interfaces/App/FeaturePreview/Branching2Preview.tsx Co-authored-by: Han Qiao <[email protected]> * Small tooltip fixes * Prettier --------- Co-authored-by: Han Qiao <[email protected]> Co-authored-by: Joshen Lim <[email protected]>
1 parent e3b646f commit 16ee99f

File tree

12 files changed

+112
-56
lines changed

12 files changed

+112
-56
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import Image from 'next/image'
2+
3+
import { InlineLink } from 'components/ui/InlineLink'
4+
import { BASE_PATH } from 'lib/constants'
5+
6+
export const Branching2Preview = () => {
7+
return (
8+
<div>
9+
<Image
10+
src={`${BASE_PATH}/img/previews/branching-preview.png`}
11+
width={1296}
12+
height={900}
13+
alt="api-docs-side-panel-preview"
14+
className="rounded border mb-4"
15+
/>
16+
<p className="text-sm text-foreground-light mb-4">
17+
Branching 2.0 introduces a new workflow for managing database branches without having to use
18+
Git. Create branches, review changes and merge back into production all through the
19+
dashboard. Read the below limitations and our{' '}
20+
<InlineLink href="https://supabase.com/docs/guides/platform/branching">
21+
branching documentation
22+
</InlineLink>{' '}
23+
before opting in.
24+
</p>
25+
<div className="my-6">
26+
<p className="text-sm text-foreground mb-2 font-medium">Limitations:</p>
27+
<ul className="list-disc pl-6 text-sm text-foreground-light space-y-1">
28+
<li>Custom roles created through the dashboard are not captured on branch creation.</li>
29+
<li>
30+
Only <code>public</code> schema changes are supported right now.
31+
</li>
32+
<li>Extensions are not included in the diff process</li>
33+
<li>
34+
Branches can only be merged to <code>main</code>; merging between preview branches is
35+
not supported.
36+
</li>
37+
<li>
38+
If your branch is out of date, you can pull in latest changes from <code>main</code>,
39+
but keep in mind that all functions will be overwritten.
40+
</li>
41+
<li>
42+
Deleting functions must be done manually on <code>main</code>.
43+
</li>
44+
<li>Migration conflicts must be manually resolved on the preview branch.</li>
45+
<li>
46+
If you have run migrations on <code>main</code>, new branches will be created from
47+
existing migrations instead of a full schema dump.
48+
</li>
49+
</ul>
50+
</div>
51+
52+
<div className="space-y-2 !mt-4">
53+
<p className="text-sm">Enabling this preview will:</p>
54+
<ul className="list-disc pl-6 text-sm text-foreground-light space-y-1">
55+
<li>Enable the new Branching 2.0 workflow for your project.</li>
56+
<li>
57+
Allow you to create, manage, and merge database branches with improved UI and features.
58+
</li>
59+
<li>Access new merge request and deployment management tools.</li>
60+
</ul>
61+
</div>
62+
</div>
63+
)
64+
}

apps/studio/components/interfaces/App/FeaturePreview/FeaturePreview.constants.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import { LOCAL_STORAGE_KEYS } from 'common'
22

33
export const FEATURE_PREVIEWS = [
4+
{
5+
key: LOCAL_STORAGE_KEYS.UI_PREVIEW_BRANCHING_2_0,
6+
name: 'Branching 2.0',
7+
discussionsUrl: 'https://github.com/orgs/supabase/discussions/branching-2-0',
8+
isNew: true,
9+
isPlatformOnly: true,
10+
},
411
{
512
key: LOCAL_STORAGE_KEYS.UI_PREVIEW_REALTIME_SETTINGS,
613
name: 'Realtime settings',

apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,8 @@ export const useIsRealtimeSettingsEnabled = () => {
8484
const { flags } = useFeaturePreviewContext()
8585
return flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_REALTIME_SETTINGS]
8686
}
87+
88+
export const useIsBranching2Enabled = () => {
89+
const { flags } = useFeaturePreviewContext()
90+
return flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_BRANCHING_2_0]
91+
}

apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { ReactNode } from 'react'
55
import { LOCAL_STORAGE_KEYS, useParams } from 'common'
66
import { useSendEventMutation } from 'data/telemetry/send-event-mutation'
77
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
8-
import { useIsRealtimeSettingsFFEnabled } from 'hooks/ui/useFlag'
8+
import { useIsRealtimeSettingsFFEnabled, useFlag } from 'hooks/ui/useFlag'
99
import { IS_PLATFORM } from 'lib/constants'
1010
import { useAppStateSnapshot } from 'state/app-state'
1111
import { Badge, Button, Modal, ScrollArea, cn } from 'ui'
@@ -15,10 +15,12 @@ import { FEATURE_PREVIEWS } from './FeaturePreview.constants'
1515
import { useFeaturePreviewContext } from './FeaturePreviewContext'
1616
import { InlineEditorPreview } from './InlineEditorPreview'
1717
import { RealtimeSettingsPreview } from './RealtimeSettingsPreview'
18+
import { Branching2Preview } from './Branching2Preview'
1819

1920
const FEATURE_PREVIEW_KEY_TO_CONTENT: {
2021
[key: string]: ReactNode
2122
} = {
23+
[LOCAL_STORAGE_KEYS.UI_PREVIEW_BRANCHING_2_0]: <Branching2Preview />,
2224
[LOCAL_STORAGE_KEYS.UI_PREVIEW_REALTIME_SETTINGS]: <RealtimeSettingsPreview />,
2325
[LOCAL_STORAGE_KEYS.UI_PREVIEW_INLINE_EDITOR]: <InlineEditorPreview />,
2426
[LOCAL_STORAGE_KEYS.UI_PREVIEW_API_SIDE_PANEL]: <APISidePanelPreview />,
@@ -31,14 +33,16 @@ const FeaturePreviewModal = () => {
3133
const org = useSelectedOrganization()
3234
const featurePreviewContext = useFeaturePreviewContext()
3335
const { mutate: sendEvent } = useSendEventMutation()
34-
3536
const isRealtimeSettingsEnabled = useIsRealtimeSettingsFFEnabled()
37+
const gitlessBranchingEnabled = useFlag('gitlessBranching')
3638

3739
// [Joshen] Use this if we want to feature flag previews
3840
function isReleasedToPublic(feature: (typeof FEATURE_PREVIEWS)[number]) {
3941
switch (feature.key) {
4042
case 'supabase-ui-realtime-settings':
4143
return isRealtimeSettingsEnabled
44+
case 'supabase-ui-branching-2-0':
45+
return gitlessBranchingEnabled
4246
default:
4347
return true
4448
}

apps/studio/components/interfaces/BranchManagement/BranchSelector.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,11 @@ export const BranchSelector = ({
5656
content: {
5757
side: 'bottom',
5858
text:
59-
availableBranches.length === 0
60-
? 'All branches currently have merge requests'
61-
: undefined,
59+
branches.length === 0
60+
? 'Create a branch first to start a merge request'
61+
: availableBranches.length === 0
62+
? 'All branches currently have merge requests'
63+
: undefined,
6264
},
6365
}}
6466
>

apps/studio/components/interfaces/BranchManagement/CreateBranchModal.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ import { toast } from 'sonner'
1010
import * as z from 'zod'
1111

1212
import { useParams } from 'common'
13+
import { useIsBranching2Enabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
1314
import { BranchingPITRNotice } from 'components/layouts/AppLayout/EnableBranchingButton/BranchingPITRNotice'
1415
import AlertError from 'components/ui/AlertError'
16+
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
1517
import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader'
1618
import UpgradeToPro from 'components/ui/UpgradeToPro'
1719
import { useBranchCreateMutation } from 'data/branches/branch-create-mutation'
@@ -22,7 +24,6 @@ import { projectKeys } from 'data/projects/keys'
2224
import { useProjectAddonsQuery } from 'data/subscriptions/project-addons-query'
2325
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
2426
import { useSelectedProject } from 'hooks/misc/useSelectedProject'
25-
import { useFlag } from 'hooks/ui/useFlag'
2627
import { BASE_PATH, IS_PLATFORM } from 'lib/constants'
2728
import { useAppStateSnapshot } from 'state/app-state'
2829
import {
@@ -50,7 +51,7 @@ export const CreateBranchModal = () => {
5051
const queryClient = useQueryClient()
5152
const projectDetails = useSelectedProject()
5253
const selectedOrg = useSelectedOrganization()
53-
const gitlessBranching = useFlag('gitlessBranching')
54+
const gitlessBranching = useIsBranching2Enabled()
5455
const { showCreateBranchModal, setShowCreateBranchModal } = useAppStateSnapshot()
5556

5657
const organization = useSelectedOrganization()
@@ -367,7 +368,7 @@ export const CreateBranchModal = () => {
367368
>
368369
Cancel
369370
</Button>
370-
<Button
371+
<ButtonTooltip
371372
form={formId}
372373
disabled={
373374
!isSuccessConnections ||
@@ -380,9 +381,18 @@ export const CreateBranchModal = () => {
380381
loading={isCreating}
381382
type="primary"
382383
htmlType="submit"
384+
tooltip={{
385+
content: {
386+
side: 'bottom',
387+
text:
388+
!gitlessBranching && !githubConnection
389+
? 'Set up a GitHub connection first to create branches'
390+
: undefined,
391+
},
392+
}}
383393
>
384394
Create branch
385-
</Button>
395+
</ButtonTooltip>
386396
</DialogFooter>
387397
</form>
388398
</Form_Shadcn_>

apps/studio/components/interfaces/BranchManagement/EditBranchModal.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { useCheckGithubBranchValidity } from 'data/integrations/github-branch-ch
1616
import { useGitHubConnectionsQuery } from 'data/integrations/github-connections-query'
1717
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
1818
import { useSelectedProject } from 'hooks/misc/useSelectedProject'
19-
import { useFlag } from 'hooks/ui/useFlag'
19+
import { useIsBranching2Enabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
2020
import { BASE_PATH } from 'lib/constants'
2121
import { useRouter } from 'next/router'
2222
import {
@@ -50,7 +50,7 @@ export const EditBranchModal = ({ branch, visible, onClose }: EditBranchModalPro
5050
const router = useRouter()
5151
const projectDetails = useSelectedProject()
5252
const selectedOrg = useSelectedOrganization()
53-
const gitlessBranching = useFlag('gitlessBranching')
53+
const gitlessBranching = useIsBranching2Enabled()
5454

5555
const [isGitBranchValid, setIsGitBranchValid] = useState(false)
5656

apps/studio/components/interfaces/BranchManagement/Overview.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import { useBranchUpdateMutation } from 'data/branches/branch-update-mutation'
2323
import type { Branch } from 'data/branches/branches-query'
2424
import { branchKeys } from 'data/branches/keys'
2525
import { useCheckPermissions } from 'hooks/misc/useCheckPermissions'
26-
import { useFlag } from 'hooks/ui/useFlag'
26+
import { useIsBranching2Enabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
2727
import {
2828
Button,
2929
DropdownMenu,
@@ -163,7 +163,7 @@ const PreviewBranchActions = ({
163163
onSelectDeleteBranch: () => void
164164
generateCreatePullRequestURL: (branchName?: string) => string
165165
}) => {
166-
const gitlessBranching = useFlag('gitlessBranching')
166+
const gitlessBranching = useIsBranching2Enabled()
167167
const queryClient = useQueryClient()
168168
const projectRef = branch.parent_project_ref ?? branch.project_ref
169169

apps/studio/pages/project/[ref]/branches/merge-requests.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { useGitHubConnectionsQuery } from 'data/integrations/github-connections-
2525
import { useCheckPermissions } from 'hooks/misc/useCheckPermissions'
2626
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
2727
import { useSelectedProject } from 'hooks/misc/useSelectedProject'
28-
import { useFlag } from 'hooks/ui/useFlag'
28+
import { useIsBranching2Enabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
2929
import type { NextPageWithLayout } from 'types'
3030
import {
3131
Button,
@@ -42,7 +42,7 @@ const MergeRequestsPage: NextPageWithLayout = () => {
4242
const { ref } = useParams()
4343
const project = useSelectedProject()
4444
const selectedOrg = useSelectedOrganization()
45-
const gitlessBranching = useFlag('gitlessBranching')
45+
const gitlessBranching = useIsBranching2Enabled()
4646

4747
const isBranch = project?.parent_project_ref !== undefined
4848
const projectRef =
@@ -282,7 +282,7 @@ const MergeRequestsPageWrapper = ({ children }: PropsWithChildren<{}>) => {
282282
const router = useRouter()
283283
const { ref } = useParams()
284284
const project = useSelectedProject()
285-
const gitlessBranching = useFlag('gitlessBranching')
285+
const gitlessBranching = useIsBranching2Enabled()
286286

287287
const isBranch = project?.parent_project_ref !== undefined
288288
const projectRef =

apps/studio/pages/project/[ref]/merge.tsx

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
11
import dayjs from 'dayjs'
2-
import {
3-
AlertTriangle,
4-
ExternalLink,
5-
GitBranchIcon,
6-
GitMerge,
7-
MoreVertical,
8-
Shield,
9-
X,
10-
} from 'lucide-react'
2+
import { AlertTriangle, GitBranchIcon, GitMerge, MoreVertical, Shield, X } from 'lucide-react'
113
import Link from 'next/link'
124
import { useRouter } from 'next/router'
135
import { useCallback, useEffect, useMemo, useState } from 'react'
@@ -33,7 +25,6 @@ import { useBranchesQuery } from 'data/branches/branches-query'
3325
import { useBranchMergeDiff } from 'hooks/branches/useBranchMergeDiff'
3426
import { useWorkflowManagement } from 'hooks/branches/useWorkflowManagement'
3527
import { useProjectByRef, useSelectedProject } from 'hooks/misc/useSelectedProject'
36-
import { useFlag } from 'hooks/ui/useFlag'
3728
import type { NextPageWithLayout } from 'types'
3829
import {
3930
Badge,
@@ -53,8 +44,6 @@ const MergePage: NextPageWithLayout = () => {
5344
const { ref } = useParams()
5445
const project = useSelectedProject()
5546

56-
const gitlessBranching = useFlag('gitlessBranching')
57-
5847
const [isSubmitting, setIsSubmitting] = useState(false)
5948
const [workflowFinalStatus, setWorkflowFinalStatus] = useState<string | null>(null)
6049
const [showConfirmDialog, setShowConfirmDialog] = useState(false)
@@ -314,33 +303,6 @@ const MergePage: NextPageWithLayout = () => {
314303
setWorkflowFinalStatus(null)
315304
}, [currentWorkflowRunId])
316305

317-
if (!gitlessBranching) {
318-
return (
319-
<PageLayout>
320-
<ScaffoldContainer size="full">
321-
<div className="flex items-center flex-col justify-center w-full py-16">
322-
<ProductEmptyState title="Branch Merge - Coming Soon">
323-
<p className="text-sm text-foreground-light">
324-
The branch merge feature is currently in development and will be available soon.
325-
</p>
326-
<div className="flex items-center space-x-2 !mt-4">
327-
<Button type="default" icon={<ExternalLink strokeWidth={1.5} />} asChild>
328-
<a
329-
target="_blank"
330-
rel="noreferrer"
331-
href="https://supabase.com/docs/guides/platform/branching"
332-
>
333-
View the docs
334-
</a>
335-
</Button>
336-
</div>
337-
</ProductEmptyState>
338-
</div>
339-
</ScaffoldContainer>
340-
</PageLayout>
341-
)
342-
}
343-
344306
// If not on a preview branch or branch info unavailable, show notice
345307
if (!isBranch || !currentBranch) {
346308
return (
@@ -349,7 +311,7 @@ const MergePage: NextPageWithLayout = () => {
349311
<div className="flex items-center flex-col justify-center w-full py-16">
350312
<ProductEmptyState title="Merge Request">
351313
<p className="text-sm text-foreground-light">
352-
This page is only available for preview branches.
314+
You can only review changes when on a preview branch
353315
</p>
354316
</ProductEmptyState>
355317
</div>

0 commit comments

Comments
 (0)