From 16ee99ff9b47dfe8b661433cdd9e0fab8c930b06 Mon Sep 17 00:00:00 2001 From: Saxon Fletcher Date: Tue, 15 Jul 2025 20:24:47 +1000 Subject: [PATCH 01/10] Chore/branch feature preview (#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 * Update apps/studio/components/interfaces/App/FeaturePreview/Branching2Preview.tsx Co-authored-by: Han Qiao * Update apps/studio/components/interfaces/App/FeaturePreview/Branching2Preview.tsx Co-authored-by: Han Qiao * Update apps/studio/components/interfaces/App/FeaturePreview/Branching2Preview.tsx Co-authored-by: Han Qiao * Small tooltip fixes * Prettier --------- Co-authored-by: Han Qiao Co-authored-by: Joshen Lim --- .../App/FeaturePreview/Branching2Preview.tsx | 64 ++++++++++++++++++ .../FeaturePreview.constants.tsx | 7 ++ .../FeaturePreview/FeaturePreviewContext.tsx | 5 ++ .../FeaturePreview/FeaturePreviewModal.tsx | 8 ++- .../BranchManagement/BranchSelector.tsx | 8 ++- .../BranchManagement/CreateBranchModal.tsx | 18 +++-- .../BranchManagement/EditBranchModal.tsx | 4 +- .../interfaces/BranchManagement/Overview.tsx | 4 +- .../project/[ref]/branches/merge-requests.tsx | 6 +- apps/studio/pages/project/[ref]/merge.tsx | 42 +----------- .../public/img/previews/branching-preview.png | Bin 0 -> 55528 bytes packages/common/constants/local-storage.ts | 2 + 12 files changed, 112 insertions(+), 56 deletions(-) create mode 100644 apps/studio/components/interfaces/App/FeaturePreview/Branching2Preview.tsx create mode 100644 apps/studio/public/img/previews/branching-preview.png diff --git a/apps/studio/components/interfaces/App/FeaturePreview/Branching2Preview.tsx b/apps/studio/components/interfaces/App/FeaturePreview/Branching2Preview.tsx new file mode 100644 index 0000000000000..88911c2d4b027 --- /dev/null +++ b/apps/studio/components/interfaces/App/FeaturePreview/Branching2Preview.tsx @@ -0,0 +1,64 @@ +import Image from 'next/image' + +import { InlineLink } from 'components/ui/InlineLink' +import { BASE_PATH } from 'lib/constants' + +export const Branching2Preview = () => { + return ( +
+ api-docs-side-panel-preview +

+ Branching 2.0 introduces a new workflow for managing database branches without having to use + Git. Create branches, review changes and merge back into production all through the + dashboard. Read the below limitations and our{' '} + + branching documentation + {' '} + before opting in. +

+
+

Limitations:

+
    +
  • Custom roles created through the dashboard are not captured on branch creation.
  • +
  • + Only public schema changes are supported right now. +
  • +
  • Extensions are not included in the diff process
  • +
  • + Branches can only be merged to main; merging between preview branches is + not supported. +
  • +
  • + If your branch is out of date, you can pull in latest changes from main, + but keep in mind that all functions will be overwritten. +
  • +
  • + Deleting functions must be done manually on main. +
  • +
  • Migration conflicts must be manually resolved on the preview branch.
  • +
  • + If you have run migrations on main, new branches will be created from + existing migrations instead of a full schema dump. +
  • +
+
+ +
+

Enabling this preview will:

+
    +
  • Enable the new Branching 2.0 workflow for your project.
  • +
  • + Allow you to create, manage, and merge database branches with improved UI and features. +
  • +
  • Access new merge request and deployment management tools.
  • +
+
+
+ ) +} diff --git a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreview.constants.tsx b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreview.constants.tsx index 2db32d6c747a5..5c64c5747075b 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreview.constants.tsx +++ b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreview.constants.tsx @@ -1,6 +1,13 @@ import { LOCAL_STORAGE_KEYS } from 'common' export const FEATURE_PREVIEWS = [ + { + key: LOCAL_STORAGE_KEYS.UI_PREVIEW_BRANCHING_2_0, + name: 'Branching 2.0', + discussionsUrl: 'https://github.com/orgs/supabase/discussions/branching-2-0', + isNew: true, + isPlatformOnly: true, + }, { key: LOCAL_STORAGE_KEYS.UI_PREVIEW_REALTIME_SETTINGS, name: 'Realtime settings', diff --git a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx index 01ed929dc8639..c71a9beda01f0 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx +++ b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx @@ -84,3 +84,8 @@ export const useIsRealtimeSettingsEnabled = () => { const { flags } = useFeaturePreviewContext() return flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_REALTIME_SETTINGS] } + +export const useIsBranching2Enabled = () => { + const { flags } = useFeaturePreviewContext() + return flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_BRANCHING_2_0] +} diff --git a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx index 477392fa4f68a..906853d35f1e6 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx +++ b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx @@ -5,7 +5,7 @@ import { ReactNode } from 'react' import { LOCAL_STORAGE_KEYS, useParams } from 'common' import { useSendEventMutation } from 'data/telemetry/send-event-mutation' import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization' -import { useIsRealtimeSettingsFFEnabled } from 'hooks/ui/useFlag' +import { useIsRealtimeSettingsFFEnabled, useFlag } from 'hooks/ui/useFlag' import { IS_PLATFORM } from 'lib/constants' import { useAppStateSnapshot } from 'state/app-state' import { Badge, Button, Modal, ScrollArea, cn } from 'ui' @@ -15,10 +15,12 @@ import { FEATURE_PREVIEWS } from './FeaturePreview.constants' import { useFeaturePreviewContext } from './FeaturePreviewContext' import { InlineEditorPreview } from './InlineEditorPreview' import { RealtimeSettingsPreview } from './RealtimeSettingsPreview' +import { Branching2Preview } from './Branching2Preview' const FEATURE_PREVIEW_KEY_TO_CONTENT: { [key: string]: ReactNode } = { + [LOCAL_STORAGE_KEYS.UI_PREVIEW_BRANCHING_2_0]: , [LOCAL_STORAGE_KEYS.UI_PREVIEW_REALTIME_SETTINGS]: , [LOCAL_STORAGE_KEYS.UI_PREVIEW_INLINE_EDITOR]: , [LOCAL_STORAGE_KEYS.UI_PREVIEW_API_SIDE_PANEL]: , @@ -31,14 +33,16 @@ const FeaturePreviewModal = () => { const org = useSelectedOrganization() const featurePreviewContext = useFeaturePreviewContext() const { mutate: sendEvent } = useSendEventMutation() - const isRealtimeSettingsEnabled = useIsRealtimeSettingsFFEnabled() + const gitlessBranchingEnabled = useFlag('gitlessBranching') // [Joshen] Use this if we want to feature flag previews function isReleasedToPublic(feature: (typeof FEATURE_PREVIEWS)[number]) { switch (feature.key) { case 'supabase-ui-realtime-settings': return isRealtimeSettingsEnabled + case 'supabase-ui-branching-2-0': + return gitlessBranchingEnabled default: return true } diff --git a/apps/studio/components/interfaces/BranchManagement/BranchSelector.tsx b/apps/studio/components/interfaces/BranchManagement/BranchSelector.tsx index 51c2c5528e13f..9714d8e5e0680 100644 --- a/apps/studio/components/interfaces/BranchManagement/BranchSelector.tsx +++ b/apps/studio/components/interfaces/BranchManagement/BranchSelector.tsx @@ -56,9 +56,11 @@ export const BranchSelector = ({ content: { side: 'bottom', text: - availableBranches.length === 0 - ? 'All branches currently have merge requests' - : undefined, + branches.length === 0 + ? 'Create a branch first to start a merge request' + : availableBranches.length === 0 + ? 'All branches currently have merge requests' + : undefined, }, }} > diff --git a/apps/studio/components/interfaces/BranchManagement/CreateBranchModal.tsx b/apps/studio/components/interfaces/BranchManagement/CreateBranchModal.tsx index fca9784bed051..7f3074d126973 100644 --- a/apps/studio/components/interfaces/BranchManagement/CreateBranchModal.tsx +++ b/apps/studio/components/interfaces/BranchManagement/CreateBranchModal.tsx @@ -10,8 +10,10 @@ import { toast } from 'sonner' import * as z from 'zod' import { useParams } from 'common' +import { useIsBranching2Enabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { BranchingPITRNotice } from 'components/layouts/AppLayout/EnableBranchingButton/BranchingPITRNotice' import AlertError from 'components/ui/AlertError' +import { ButtonTooltip } from 'components/ui/ButtonTooltip' import { GenericSkeletonLoader } from 'components/ui/ShimmeringLoader' import UpgradeToPro from 'components/ui/UpgradeToPro' import { useBranchCreateMutation } from 'data/branches/branch-create-mutation' @@ -22,7 +24,6 @@ import { projectKeys } from 'data/projects/keys' import { useProjectAddonsQuery } from 'data/subscriptions/project-addons-query' import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization' import { useSelectedProject } from 'hooks/misc/useSelectedProject' -import { useFlag } from 'hooks/ui/useFlag' import { BASE_PATH, IS_PLATFORM } from 'lib/constants' import { useAppStateSnapshot } from 'state/app-state' import { @@ -50,7 +51,7 @@ export const CreateBranchModal = () => { const queryClient = useQueryClient() const projectDetails = useSelectedProject() const selectedOrg = useSelectedOrganization() - const gitlessBranching = useFlag('gitlessBranching') + const gitlessBranching = useIsBranching2Enabled() const { showCreateBranchModal, setShowCreateBranchModal } = useAppStateSnapshot() const organization = useSelectedOrganization() @@ -367,7 +368,7 @@ export const CreateBranchModal = () => { > Cancel - + diff --git a/apps/studio/components/interfaces/BranchManagement/EditBranchModal.tsx b/apps/studio/components/interfaces/BranchManagement/EditBranchModal.tsx index 7161c91db3170..bed088dd52826 100644 --- a/apps/studio/components/interfaces/BranchManagement/EditBranchModal.tsx +++ b/apps/studio/components/interfaces/BranchManagement/EditBranchModal.tsx @@ -16,7 +16,7 @@ import { useCheckGithubBranchValidity } from 'data/integrations/github-branch-ch import { useGitHubConnectionsQuery } from 'data/integrations/github-connections-query' import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization' import { useSelectedProject } from 'hooks/misc/useSelectedProject' -import { useFlag } from 'hooks/ui/useFlag' +import { useIsBranching2Enabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { BASE_PATH } from 'lib/constants' import { useRouter } from 'next/router' import { @@ -50,7 +50,7 @@ export const EditBranchModal = ({ branch, visible, onClose }: EditBranchModalPro const router = useRouter() const projectDetails = useSelectedProject() const selectedOrg = useSelectedOrganization() - const gitlessBranching = useFlag('gitlessBranching') + const gitlessBranching = useIsBranching2Enabled() const [isGitBranchValid, setIsGitBranchValid] = useState(false) diff --git a/apps/studio/components/interfaces/BranchManagement/Overview.tsx b/apps/studio/components/interfaces/BranchManagement/Overview.tsx index e631c4d394ed1..c4c2be7670cc0 100644 --- a/apps/studio/components/interfaces/BranchManagement/Overview.tsx +++ b/apps/studio/components/interfaces/BranchManagement/Overview.tsx @@ -23,7 +23,7 @@ import { useBranchUpdateMutation } from 'data/branches/branch-update-mutation' import type { Branch } from 'data/branches/branches-query' import { branchKeys } from 'data/branches/keys' import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' -import { useFlag } from 'hooks/ui/useFlag' +import { useIsBranching2Enabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { Button, DropdownMenu, @@ -163,7 +163,7 @@ const PreviewBranchActions = ({ onSelectDeleteBranch: () => void generateCreatePullRequestURL: (branchName?: string) => string }) => { - const gitlessBranching = useFlag('gitlessBranching') + const gitlessBranching = useIsBranching2Enabled() const queryClient = useQueryClient() const projectRef = branch.parent_project_ref ?? branch.project_ref diff --git a/apps/studio/pages/project/[ref]/branches/merge-requests.tsx b/apps/studio/pages/project/[ref]/branches/merge-requests.tsx index 7aed9e003b4e4..fa7ae63947dcf 100644 --- a/apps/studio/pages/project/[ref]/branches/merge-requests.tsx +++ b/apps/studio/pages/project/[ref]/branches/merge-requests.tsx @@ -25,7 +25,7 @@ import { useGitHubConnectionsQuery } from 'data/integrations/github-connections- import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization' import { useSelectedProject } from 'hooks/misc/useSelectedProject' -import { useFlag } from 'hooks/ui/useFlag' +import { useIsBranching2Enabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import type { NextPageWithLayout } from 'types' import { Button, @@ -42,7 +42,7 @@ const MergeRequestsPage: NextPageWithLayout = () => { const { ref } = useParams() const project = useSelectedProject() const selectedOrg = useSelectedOrganization() - const gitlessBranching = useFlag('gitlessBranching') + const gitlessBranching = useIsBranching2Enabled() const isBranch = project?.parent_project_ref !== undefined const projectRef = @@ -282,7 +282,7 @@ const MergeRequestsPageWrapper = ({ children }: PropsWithChildren<{}>) => { const router = useRouter() const { ref } = useParams() const project = useSelectedProject() - const gitlessBranching = useFlag('gitlessBranching') + const gitlessBranching = useIsBranching2Enabled() const isBranch = project?.parent_project_ref !== undefined const projectRef = diff --git a/apps/studio/pages/project/[ref]/merge.tsx b/apps/studio/pages/project/[ref]/merge.tsx index 2f8d10228cf9b..9cd7be109287b 100644 --- a/apps/studio/pages/project/[ref]/merge.tsx +++ b/apps/studio/pages/project/[ref]/merge.tsx @@ -1,13 +1,5 @@ import dayjs from 'dayjs' -import { - AlertTriangle, - ExternalLink, - GitBranchIcon, - GitMerge, - MoreVertical, - Shield, - X, -} from 'lucide-react' +import { AlertTriangle, GitBranchIcon, GitMerge, MoreVertical, Shield, X } from 'lucide-react' import Link from 'next/link' import { useRouter } from 'next/router' import { useCallback, useEffect, useMemo, useState } from 'react' @@ -33,7 +25,6 @@ import { useBranchesQuery } from 'data/branches/branches-query' import { useBranchMergeDiff } from 'hooks/branches/useBranchMergeDiff' import { useWorkflowManagement } from 'hooks/branches/useWorkflowManagement' import { useProjectByRef, useSelectedProject } from 'hooks/misc/useSelectedProject' -import { useFlag } from 'hooks/ui/useFlag' import type { NextPageWithLayout } from 'types' import { Badge, @@ -53,8 +44,6 @@ const MergePage: NextPageWithLayout = () => { const { ref } = useParams() const project = useSelectedProject() - const gitlessBranching = useFlag('gitlessBranching') - const [isSubmitting, setIsSubmitting] = useState(false) const [workflowFinalStatus, setWorkflowFinalStatus] = useState(null) const [showConfirmDialog, setShowConfirmDialog] = useState(false) @@ -314,33 +303,6 @@ const MergePage: NextPageWithLayout = () => { setWorkflowFinalStatus(null) }, [currentWorkflowRunId]) - if (!gitlessBranching) { - return ( - - -
- -

- The branch merge feature is currently in development and will be available soon. -

-
- -
-
-
-
-
- ) - } - // If not on a preview branch or branch info unavailable, show notice if (!isBranch || !currentBranch) { return ( @@ -349,7 +311,7 @@ const MergePage: NextPageWithLayout = () => {

- This page is only available for preview branches. + You can only review changes when on a preview branch

diff --git a/apps/studio/public/img/previews/branching-preview.png b/apps/studio/public/img/previews/branching-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..91b5435f1117a1f5c5ab14198825323b6a75af66 GIT binary patch literal 55528 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
HP=zcNccl~L8ueXK5D$)i_xJ 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