mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
How to test: 1. Connect a project to GH repo 2. Deploy the `config.toml` once 3. Change some setting in Auth 4. You should see a change in `/dashboard/project/_/settings/code-configuration` <img width="1271" height="1186" alt="Screenshot 2026-09-16 at 16 26 39" src="https://github.com/user-attachments/assets/dfc135a4-e495-489e-88fd-b760383793b4" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Configuration drift comparisons now use a consistent project configuration schema. - Drift details display complete current-environment and `config.toml` values, grouped by section. - Matching and unmanaged settings are organized into dedicated sections. - Configuration fields link directly to relevant Studio settings. - Added a warning that GitHub deployments overwrite local changes. - **Bug Fixes** - Configuration updates now refresh project configuration data automatically. - Improved labels and formatting for boolean and redirect URL values. - Drift errors identify invalid configuration paths and provide corrective guidance. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
137 lines
5.0 KiB
TypeScript
137 lines
5.0 KiB
TypeScript
import { useQuery } from '@tanstack/react-query'
|
|
import { useParams } from 'common'
|
|
import { useCallback, useMemo } from 'react'
|
|
|
|
import {
|
|
formatGitHubConfigDecodeMessage,
|
|
fromDashboardProjectConfig,
|
|
getConfigDriftSummary,
|
|
type GitHubConfigDriftSummary,
|
|
} from '@/components/interfaces/ConfigDrift/github-config-drift'
|
|
import type { Branch } from '@/data/branches/branches-query'
|
|
import { useBranchesQuery } from '@/data/branches/branches-query'
|
|
import { useGitHubConfigQuery } from '@/data/config/github-config-query'
|
|
import { projectConfigV2QueryOptions } from '@/data/config/project-config-query'
|
|
import { useProjectGitHubConnectionQuery } from '@/data/integrations/github-connections-query'
|
|
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
|
import { IS_PLATFORM } from '@/lib/constants'
|
|
|
|
const EMPTY_SUMMARY: GitHubConfigDriftSummary = {
|
|
driftedFields: [],
|
|
matchedFields: [],
|
|
unmanagedFields: [],
|
|
}
|
|
|
|
type ConfigDriftMemoResult =
|
|
| { status: 'success'; summary: GitHubConfigDriftSummary }
|
|
| { status: 'error'; source: 'project-config' | 'config-toml'; error: Error }
|
|
|
|
export function getGitBranchName(branch?: Branch): string | undefined {
|
|
return branch?.git_branch?.trim() || (branch?.is_default ? undefined : branch?.name?.trim())
|
|
}
|
|
|
|
export function useSelectedGitHubConfigDrift() {
|
|
const { ref: projectRef } = useParams()
|
|
const projectQuery = useSelectedProjectQuery()
|
|
const project = projectQuery.data
|
|
const parentProjectRef = project?.parentRef ?? projectRef
|
|
const shouldLoad = IS_PLATFORM && Boolean(projectRef) && Boolean(project)
|
|
|
|
const branchesQuery = useBranchesQuery({ projectRef: parentProjectRef }, { enabled: shouldLoad })
|
|
const connectionQuery = useProjectGitHubConnectionQuery({ ref: parentProjectRef })
|
|
const connection = connectionQuery.data
|
|
const hasConnection = connection !== undefined
|
|
const branches = branchesQuery.data ?? []
|
|
const selectedBranch = branches.find((branch) => branch.project_ref === projectRef)
|
|
const gitBranch = getGitBranchName(selectedBranch)
|
|
const queriesEnabled =
|
|
shouldLoad && branchesQuery.isSuccess && connectionQuery.isSuccess && hasConnection
|
|
|
|
const projectConfigQuery = useQuery({
|
|
...projectConfigV2QueryOptions({ projectRef }),
|
|
enabled: queriesEnabled,
|
|
staleTime: 30_000,
|
|
})
|
|
const githubConfigQuery = useGitHubConfigQuery(
|
|
{ connectionId: connection?.id, branch: gitBranch },
|
|
{ enabled: queriesEnabled }
|
|
)
|
|
|
|
const { refetch: branchesRefetch } = branchesQuery
|
|
const { refetch: connectionRefetch } = connectionQuery
|
|
const { refetch: projectConfigRefetch } = projectConfigQuery
|
|
const { refetch: githubConfigRefetch } = githubConfigQuery
|
|
|
|
const refetch = useCallback(
|
|
() =>
|
|
Promise.all([
|
|
branchesRefetch(),
|
|
connectionRefetch(),
|
|
projectConfigRefetch(),
|
|
githubConfigRefetch(),
|
|
]),
|
|
[branchesRefetch, connectionRefetch, projectConfigRefetch, githubConfigRefetch]
|
|
)
|
|
|
|
const driftResult = useMemo((): ConfigDriftMemoResult => {
|
|
let dashboardConfig
|
|
try {
|
|
dashboardConfig = fromDashboardProjectConfig(projectConfigQuery.data?.attributes)
|
|
} catch (error) {
|
|
console.error('Failed to read project configuration:', error)
|
|
return {
|
|
status: 'error',
|
|
source: 'project-config',
|
|
error: new Error('Could not read the project configuration returned by the API.'),
|
|
}
|
|
}
|
|
|
|
const result = getConfigDriftSummary({
|
|
dashboardConfig,
|
|
githubConfig: githubConfigQuery.data?.config,
|
|
})
|
|
if (result.status === 'invalid-config') {
|
|
return {
|
|
status: 'error',
|
|
source: 'config-toml',
|
|
error: new Error(formatGitHubConfigDecodeMessage(result.issues)),
|
|
}
|
|
}
|
|
|
|
return { status: 'success', summary: result.summary }
|
|
}, [projectConfigQuery.data?.attributes, githubConfigQuery.data?.config])
|
|
|
|
const summary = driftResult.status === 'success' ? driftResult.summary : EMPTY_SUMMARY
|
|
const conversionError = driftResult.status === 'error' ? driftResult.error : undefined
|
|
|
|
const activeQueries = [
|
|
projectQuery,
|
|
...(shouldLoad ? [branchesQuery, connectionQuery] : []),
|
|
...(shouldLoad && hasConnection ? [projectConfigQuery, githubConfigQuery] : []),
|
|
]
|
|
|
|
const isReady =
|
|
shouldLoad && hasConnection && projectConfigQuery.isSuccess && githubConfigQuery.isSuccess
|
|
const issueCount = summary.driftedFields.length
|
|
const queryError = activeQueries.find((query) => query.error)?.error
|
|
let errorSource: 'query' | 'project-config' | 'config-toml' | undefined = undefined
|
|
if (queryError) {
|
|
errorSource = 'query'
|
|
} else if (driftResult.status === 'error') {
|
|
errorSource = driftResult.source
|
|
}
|
|
|
|
return {
|
|
requestedGitBranch: gitBranch,
|
|
isReady,
|
|
isPending: activeQueries.some((query) => query.isPending),
|
|
isFetching: activeQueries.some((query) => query.isFetching),
|
|
isError: activeQueries.some((query) => query.isError) || conversionError !== undefined,
|
|
error: queryError ?? conversionError,
|
|
errorSource,
|
|
hasConfigurationIssues: isReady && issueCount > 0,
|
|
summary,
|
|
refetch,
|
|
}
|
|
}
|