mirror of
https://github.com/supabase/supabase.git
synced 2026-10-14 21:59:16 +03:00
failed merge
This commit is contained in:
1 parent
0eaf71a64f
commit
ab9f8e158d
2 files changed
+97
-92
No files matched your search
@@ -5,19 +5,13 @@ import { Card, CardContent, CardHeader, CardTitle, cn } from 'ui'
|
||||
import { Code, Wind } from 'lucide-react'
|
||||
import DiffViewer from 'components/ui/DiffViewer'
|
||||
import { Loading, EmptyState } from 'components/ui/AsyncState'
|
||||
import useEdgeFunctionsDiff, {
|
||||
type FileInfo,
|
||||
type FileStatus,
|
||||
} from 'hooks/misc/useEdgeFunctionsDiff'
|
||||
import type { EdgeFunctionsDiffResult, FileInfo, FileStatus } from 'hooks/misc/useEdgeFunctionsDiff'
|
||||
import Link from 'next/link'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { basename } from 'path'
|
||||
|
||||
interface EdgeFunctionsDiffPanelProps {
|
||||
currentBranchFunctions?: EdgeFunctionsData
|
||||
mainBranchFunctions?: EdgeFunctionsData
|
||||
isCurrentFunctionsLoading: boolean
|
||||
isMainFunctionsLoading: boolean
|
||||
diffResults: EdgeFunctionsDiffResult
|
||||
currentBranchRef?: string
|
||||
mainBranchRef?: string
|
||||
}
|
||||
@@ -143,36 +137,15 @@ const FunctionDiff = ({
|
||||
}
|
||||
|
||||
const EdgeFunctionsDiffPanel = ({
|
||||
currentBranchFunctions,
|
||||
mainBranchFunctions,
|
||||
isCurrentFunctionsLoading,
|
||||
isMainFunctionsLoading,
|
||||
diffResults,
|
||||
currentBranchRef,
|
||||
mainBranchRef,
|
||||
}: EdgeFunctionsDiffPanelProps) => {
|
||||
const {
|
||||
addedSlugs,
|
||||
removedSlugs,
|
||||
modifiedSlugs,
|
||||
addedBodiesMap,
|
||||
removedBodiesMap,
|
||||
currentBodiesMap,
|
||||
mainBodiesMap,
|
||||
functionFileInfo,
|
||||
isLoading,
|
||||
hasChanges,
|
||||
} = useEdgeFunctionsDiff({
|
||||
currentBranchFunctions,
|
||||
mainBranchFunctions,
|
||||
currentBranchRef,
|
||||
mainBranchRef,
|
||||
})
|
||||
|
||||
if (isCurrentFunctionsLoading || isMainFunctionsLoading || isLoading) {
|
||||
if (diffResults.isLoading) {
|
||||
return <Loading />
|
||||
}
|
||||
|
||||
if (!hasChanges) {
|
||||
if (!diffResults.hasChanges) {
|
||||
return (
|
||||
<EmptyState
|
||||
title="No changes detected between branches"
|
||||
@@ -184,50 +157,50 @@ const EdgeFunctionsDiffPanel = ({
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{addedSlugs.length > 0 && (
|
||||
{diffResults.addedSlugs.length > 0 && (
|
||||
<div>
|
||||
<div className="space-y-4">
|
||||
{addedSlugs.map((slug) => (
|
||||
{diffResults.addedSlugs.map((slug) => (
|
||||
<FunctionDiff
|
||||
key={slug}
|
||||
functionSlug={slug}
|
||||
currentBody={addedBodiesMap[slug]!}
|
||||
currentBody={diffResults.addedBodiesMap[slug]!}
|
||||
mainBody={[] as EdgeFunctionBodyData}
|
||||
currentBranchRef={currentBranchRef}
|
||||
fileInfos={functionFileInfo[slug] || []}
|
||||
fileInfos={diffResults.functionFileInfo[slug] || []}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{removedSlugs.length > 0 && (
|
||||
{diffResults.removedSlugs.length > 0 && (
|
||||
<div>
|
||||
<div className="space-y-4">
|
||||
{removedSlugs.map((slug) => (
|
||||
{diffResults.removedSlugs.map((slug) => (
|
||||
<FunctionDiff
|
||||
key={slug}
|
||||
functionSlug={slug}
|
||||
currentBody={[] as EdgeFunctionBodyData}
|
||||
mainBody={removedBodiesMap[slug]!}
|
||||
mainBody={diffResults.removedBodiesMap[slug]!}
|
||||
currentBranchRef={mainBranchRef}
|
||||
fileInfos={functionFileInfo[slug] || []}
|
||||
fileInfos={diffResults.functionFileInfo[slug] || []}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{modifiedSlugs.length > 0 && (
|
||||
{diffResults.modifiedSlugs.length > 0 && (
|
||||
<div className="space-y-4">
|
||||
{modifiedSlugs.map((slug) => (
|
||||
{diffResults.modifiedSlugs.map((slug) => (
|
||||
<FunctionDiff
|
||||
key={slug}
|
||||
functionSlug={slug}
|
||||
currentBody={currentBodiesMap[slug]!}
|
||||
mainBody={mainBodiesMap[slug]!}
|
||||
currentBody={diffResults.currentBodiesMap[slug]!}
|
||||
mainBody={diffResults.mainBodiesMap[slug]!}
|
||||
currentBranchRef={currentBranchRef}
|
||||
fileInfos={functionFileInfo[slug] || []}
|
||||
fileInfos={diffResults.functionFileInfo[slug] || []}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -14,6 +14,7 @@ import { useBranchDiffQuery } from 'data/branches/branch-diff-query'
|
||||
import { useBranchPushMutation } from 'data/branches/branch-push-mutation'
|
||||
import { useMigrationsQuery } from 'data/database/migrations-query'
|
||||
import { useEdgeFunctionsQuery } from 'data/edge-functions/edge-functions-query'
|
||||
import useEdgeFunctionsDiff from 'hooks/misc/useEdgeFunctionsDiff'
|
||||
import DatabaseDiffPanel from 'components/interfaces/BranchManagement/DatabaseDiffPanel'
|
||||
import EdgeFunctionsDiffPanel from 'components/interfaces/BranchManagement/EdgeFunctionsDiffPanel'
|
||||
import { Badge, Button, NavMenu, NavMenuItem, cn, Alert } from 'ui'
|
||||
@@ -41,6 +42,9 @@ const MergePage: NextPageWithLayout = () => {
|
||||
// State to track related workflow runs with their project refs
|
||||
const [relatedWorkflowRunIds, setRelatedWorkflowRunIds] = useState<Record<string, string>>({})
|
||||
|
||||
// State to track failed workflows
|
||||
const [failedWorkflowIds, setFailedWorkflowIds] = useState<Set<string>>(new Set())
|
||||
|
||||
const isBranch = project?.parent_project_ref !== undefined
|
||||
const parentProjectRef = project?.parent_project_ref
|
||||
|
||||
@@ -84,8 +88,6 @@ const MergePage: NextPageWithLayout = () => {
|
||||
}
|
||||
)
|
||||
|
||||
console.log('migrations:', currentBranchMigrations, mainBranchMigrations)
|
||||
|
||||
// Check if current branch is out of date with main branch
|
||||
const isBranchOutOfDate = useMemo(() => {
|
||||
if (!currentBranchMigrations || !mainBranchMigrations) return false
|
||||
@@ -143,16 +145,23 @@ const MergePage: NextPageWithLayout = () => {
|
||||
)
|
||||
|
||||
// Get edge functions for both branches
|
||||
const { data: currentBranchFunctions, isLoading: isCurrentFunctionsLoading } =
|
||||
useEdgeFunctionsQuery(
|
||||
{ projectRef: ref },
|
||||
{
|
||||
enabled: gitlessBranching && !!ref,
|
||||
staleTime: 30000, // 30 seconds
|
||||
}
|
||||
)
|
||||
const {
|
||||
data: currentBranchFunctions,
|
||||
isLoading: isCurrentFunctionsLoading,
|
||||
refetch: refetchCurrentBranchFunctions,
|
||||
} = useEdgeFunctionsQuery(
|
||||
{ projectRef: ref },
|
||||
{
|
||||
enabled: gitlessBranching && !!ref,
|
||||
staleTime: 30000, // 30 seconds
|
||||
}
|
||||
)
|
||||
|
||||
const { data: mainBranchFunctions, isLoading: isMainFunctionsLoading } = useEdgeFunctionsQuery(
|
||||
const {
|
||||
data: mainBranchFunctions,
|
||||
isLoading: isMainFunctionsLoading,
|
||||
refetch: refetchMainBranchFunctions,
|
||||
} = useEdgeFunctionsQuery(
|
||||
{ projectRef: parentProjectRef },
|
||||
{
|
||||
enabled: gitlessBranching && !!parentProjectRef,
|
||||
@@ -160,6 +169,14 @@ const MergePage: NextPageWithLayout = () => {
|
||||
}
|
||||
)
|
||||
|
||||
// Get edge functions diff
|
||||
const edgeFunctionsDiff = useEdgeFunctionsDiff({
|
||||
currentBranchFunctions,
|
||||
mainBranchFunctions,
|
||||
currentBranchRef: ref,
|
||||
mainBranchRef: parentProjectRef,
|
||||
})
|
||||
|
||||
// Handle workflow completion - refetch diff once when workflow completes or fails
|
||||
const handleWorkflowStatusChange = useCallback(
|
||||
(status: string, workflowRunId: string) => {
|
||||
@@ -168,12 +185,20 @@ const MergePage: NextPageWithLayout = () => {
|
||||
status === 'MIGRATIONS_FAILED' ||
|
||||
status === 'FUNCTIONS_FAILED'
|
||||
|
||||
const isFailed = status === 'MIGRATIONS_FAILED' || status === 'FUNCTIONS_FAILED'
|
||||
|
||||
if (isFailed) {
|
||||
setFailedWorkflowIds((prev) => new Set(prev).add(workflowRunId))
|
||||
}
|
||||
|
||||
if (isComplete) {
|
||||
// Refetch diff once when workflow completes
|
||||
// Refetch diff and edge functions once when workflow completes
|
||||
refetchDiff()
|
||||
refetchCurrentBranchFunctions()
|
||||
refetchMainBranchFunctions()
|
||||
}
|
||||
},
|
||||
[refetchDiff]
|
||||
[refetchDiff, refetchCurrentBranchFunctions, refetchMainBranchFunctions]
|
||||
)
|
||||
|
||||
// Check if there are any changes (database or edge functions)
|
||||
@@ -181,30 +206,8 @@ const MergePage: NextPageWithLayout = () => {
|
||||
// Check database changes
|
||||
const hasDatabaseChanges = diffContent && diffContent.trim() !== ''
|
||||
|
||||
// Check edge function changes
|
||||
const hasEdgeFunctionChanges = (() => {
|
||||
if (!currentBranchFunctions || !mainBranchFunctions) return false
|
||||
|
||||
const currentFuncs = currentBranchFunctions || []
|
||||
const mainFuncs = mainBranchFunctions || []
|
||||
|
||||
// Check for added functions
|
||||
const added = currentFuncs.filter(
|
||||
(currentFunc) => !mainFuncs.find((mainFunc) => mainFunc.slug === currentFunc.slug)
|
||||
)
|
||||
|
||||
// Check for removed functions
|
||||
const removed = mainFuncs.filter(
|
||||
(mainFunc) => !currentFuncs.find((currentFunc) => currentFunc.slug === mainFunc.slug)
|
||||
)
|
||||
|
||||
// Check for modified functions (functions present in both branches)
|
||||
const modified = currentFuncs.filter((currentFunc) =>
|
||||
mainFuncs.some((f) => f.slug === currentFunc.slug)
|
||||
)
|
||||
|
||||
return added.length > 0 || removed.length > 0 || modified.length > 0
|
||||
})()
|
||||
// Check edge function changes using the diff hook
|
||||
const hasEdgeFunctionChanges = edgeFunctionsDiff.hasChanges
|
||||
|
||||
return hasDatabaseChanges || hasEdgeFunctionChanges
|
||||
}
|
||||
@@ -289,10 +292,7 @@ const MergePage: NextPageWithLayout = () => {
|
||||
)
|
||||
|
||||
// `hasAnyChanges` should be true only when there are *no* pending changes
|
||||
const hasAnyChanges = useMemo(
|
||||
() => !hasChanges(),
|
||||
[diffContent, currentBranchFunctions, mainBranchFunctions]
|
||||
)
|
||||
const hasAnyChanges = useMemo(() => !hasChanges(), [diffContent, edgeFunctionsDiff.hasChanges])
|
||||
|
||||
// Determine current active tab via query param (defaults to 'database')
|
||||
const currentTab = (router.query.tab as string) || 'database'
|
||||
@@ -303,6 +303,10 @@ const MergePage: NextPageWithLayout = () => {
|
||||
// Check if we have any active workflow runs
|
||||
const hasActiveWorkflowRuns = Object.keys(relatedWorkflowRunIds).length > 0
|
||||
|
||||
// Check if current workflow run has failed
|
||||
const hasCurrentWorkflowFailed =
|
||||
currentWorkflowRunId && failedWorkflowIds.has(currentWorkflowRunId)
|
||||
|
||||
// Navigation items for PageLayout - updates the `tab` query param
|
||||
const navigationItems = useMemo(() => {
|
||||
const buildHref = (tab: string) => {
|
||||
@@ -375,7 +379,11 @@ const MergePage: NextPageWithLayout = () => {
|
||||
)
|
||||
}
|
||||
|
||||
const isDataLoaded = !isDiffLoading && !isCurrentFunctionsLoading && !isMainFunctionsLoading
|
||||
const isDataLoaded =
|
||||
!isDiffLoading &&
|
||||
!isCurrentFunctionsLoading &&
|
||||
!isMainFunctionsLoading &&
|
||||
!edgeFunctionsDiff.isLoading
|
||||
const isMergeDisabled = hasAnyChanges && isDataLoaded
|
||||
|
||||
// Update primary actions - remove push button if branch is out of date (it will be in the notice)
|
||||
@@ -465,6 +473,31 @@ const MergePage: NextPageWithLayout = () => {
|
||||
</Admonition>
|
||||
)
|
||||
|
||||
// Workflow failure notice component
|
||||
const WorkflowFailureNotice = () => (
|
||||
<Admonition type="danger" className="my-4">
|
||||
<div className="w-full flex items-center justify-between">
|
||||
<div>
|
||||
<h3 className="text-sm font-medium">Workflow failed</h3>
|
||||
<p className="text-sm text-foreground-light">
|
||||
The deployment workflow encountered an error. Consider creating a fresh branch from the
|
||||
latest production branch to resolve potential conflicts.
|
||||
</p>
|
||||
</div>
|
||||
<Button
|
||||
type="default"
|
||||
asChild
|
||||
icon={<GitBranchIcon size={16} strokeWidth={1.5} />}
|
||||
className="shrink-0"
|
||||
>
|
||||
<Link href={`/project/${parentProjectRef}/branches`}>Create new branch</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</Admonition>
|
||||
)
|
||||
|
||||
console.log('workflow:', currentWorkflowRunId)
|
||||
|
||||
return (
|
||||
<PageLayout
|
||||
title={pageTitle()}
|
||||
@@ -476,9 +509,11 @@ const MergePage: NextPageWithLayout = () => {
|
||||
>
|
||||
<div className="border-b">
|
||||
<ScaffoldContainer size="full">
|
||||
{/* Show out of date notice or workflow logs */}
|
||||
{/* Show out of date notice, workflow failure notice, or workflow logs */}
|
||||
{isBranchOutOfDate && !currentWorkflowRunId ? (
|
||||
<OutOfDateNotice />
|
||||
) : hasCurrentWorkflowFailed ? (
|
||||
<WorkflowFailureNotice />
|
||||
) : currentWorkflowRunId ? (
|
||||
<WorkflowLogsCard
|
||||
workflowRunId={currentWorkflowRunId}
|
||||
@@ -531,10 +566,7 @@ const MergePage: NextPageWithLayout = () => {
|
||||
/>
|
||||
) : (
|
||||
<EdgeFunctionsDiffPanel
|
||||
currentBranchFunctions={currentBranchFunctions}
|
||||
mainBranchFunctions={mainBranchFunctions}
|
||||
isCurrentFunctionsLoading={isCurrentFunctionsLoading}
|
||||
isMainFunctionsLoading={isMainFunctionsLoading}
|
||||
diffResults={edgeFunctionsDiff}
|
||||
currentBranchRef={ref}
|
||||
mainBranchRef={parentProjectRef}
|
||||
/>
|
||||
|
||||
Reference in new issue
Block a user