failed merge

This commit is contained in:
Saxon Fletcher committed 2025-06-26 15:57:09 +10:00
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>
+79 -47
View File
@@ -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}
/>