Files
supabase/apps/studio/data/branches/branch-merge-mutation.ts
T
Han Qiao c32c74e34c fix: diff all schemas on branch merge (#37754)
* fix: diff all schemas on branch merge

* chore: remove branching limitation on schema and extensions

* chore: remove limitation from blog post

* chore: remove limitation from docs
2025-08-12 21:18:24 +08:00

93 lines
2.6 KiB
TypeScript

import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'
import { handleError, post } from 'data/fetchers'
import type { ResponseError } from 'types'
import { branchKeys } from './keys'
import { getBranchDiff } from './branch-diff-query'
import { upsertMigration } from '../database/migration-upsert-mutation'
export type BranchMergeVariables = {
id: string
branchProjectRef: string
baseProjectRef: string
migration_version?: string
}
export async function mergeBranch({
id,
branchProjectRef,
baseProjectRef,
migration_version,
}: BranchMergeVariables) {
// Step 1: Get the diff output from the branch
const diffContent = await getBranchDiff({ branchId: id })
let migrationCreated = false
// Step 2: If there are changes, create a migration before merging
if (diffContent && diffContent.trim() !== '') {
// Generate a descriptive migration name based on current timestamp
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5)
const migrationName = `branch_merge_${timestamp}`
await upsertMigration({
projectRef: branchProjectRef,
query: diffContent,
name: migrationName,
})
migrationCreated = true
}
// Step 3: Call POST /v1/branches/id/merge to merge the branch
const { data, error } = await post('/v1/branches/{branch_id}/merge', {
params: { path: { branch_id: id } },
body: { migration_version },
})
if (error) {
handleError(error)
}
return {
data,
migrationCreated,
hadChanges: diffContent && diffContent.trim() !== '',
workflowRunId: data?.workflow_run_id,
}
}
type BranchMergeData = Awaited<ReturnType<typeof mergeBranch>>
export const useBranchMergeMutation = ({
onSuccess,
onError,
...options
}: Omit<
UseMutationOptions<BranchMergeData, ResponseError, BranchMergeVariables>,
'mutationFn'
> = {}) => {
const queryClient = useQueryClient()
return useMutation<BranchMergeData, ResponseError, BranchMergeVariables>(
(vars) => mergeBranch(vars),
{
async onSuccess(data, variables, context) {
const { baseProjectRef } = variables
await queryClient.invalidateQueries(branchKeys.list(baseProjectRef))
await onSuccess?.(data, variables, context)
},
async onError(data, variables, context) {
if (onError === undefined) {
let errorMessage = data.message || 'Unknown error occurred'
toast.error(`Failed to merge branch: ${errorMessage}`)
} else {
onError(data, variables, context)
}
},
...options,
}
)
}