Skip to content

Use new action runs endpoints#41808

Merged
joshenlim merged 8 commits intomasterfrom
joshen/fe-2348-gitless-branch-merges-stuck-in-creating_project-status
Jan 23, 2026
Merged

Use new action runs endpoints#41808
joshenlim merged 8 commits intomasterfrom
joshen/fe-2348-gitless-branch-merges-stuck-in-creating_project-status

Conversation

@joshenlim
Copy link
Member

@joshenlim joshenlim commented Jan 9, 2026

Context

This is only for Gitless branching - merge attempts get stuck at "Creating project" in the logs. This is due to the wrong endpoint being used as we now need to use v1 endpoints as opposed to the platform endpoints.

Changes in this PR fixes that such that the workflow logs populate correctly.

Other changes involved

  • Remove workflow-runs react query -> Branching now uses the actions react query
    • Also refactored the queries in actions to be more consistent with how we write our RQs
  • (Unrelated) Unify usage of DiffEditor components to import from ui instead of monaco directly
    • DiffEditor in ui consolidates the options, rather than declaring the options in separate places whenever we render DiffEditor
    • Affects SQL Editor + AI Editor (Used in edge functions)
    • Also fixes the TextModel got disposed before DiffEditorWidget model got reset when switching between "Database" and "Edge Functions" in the branch merge page

To test

  • Try merging a gitless branch - logs should populate nicely, and not get stuck at "Creating project" (refer to demo video in Linear for reference)

Summary by CodeRabbit

  • Refactor

    • Clearer workflow status states and updated success/failure/running labels and icons for more consistent UI feedback.
    • Consolidated workflow run and logs fetching for more reliable and accurate run status and log display.
    • Diff views standardized to a consistent, read-only diff editor for SQL and function diffs.
  • Chores

    • Components updated to named exports for module consistency.

✏️ Tip: You can customize this high-level summary in your review settings.

@joshenlim joshenlim requested a review from a team as a code owner January 9, 2026 04:00
@vercel
Copy link

vercel bot commented Jan 9, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
studio-self-hosted Ready Ready Preview, Comment Jan 23, 2026 3:14am
studio-staging Ready Ready Preview, Comment Jan 23, 2026 3:14am
6 Skipped Deployments
Project Deployment Review Updated (UTC)
cms Ignored Ignored Jan 23, 2026 3:14am
studio Ignored Ignored Jan 23, 2026 3:14am
design-system Skipped Skipped Jan 23, 2026 3:14am
docs Skipped Skipped Jan 23, 2026 3:14am
ui-library Skipped Skipped Jan 23, 2026 3:14am
zone-www-dot-com Skipped Skipped Jan 23, 2026 3:14am

Request Review

@supabase
Copy link

supabase bot commented Jan 9, 2026

This pull request has been ignored for the connected project xguihxuzqibwxjnimxev because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@joshenlim joshenlim marked this pull request as draft January 9, 2026 04:00
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 9, 2026

Walkthrough

Replaces legacy workflow-runs modules with action-based APIs/hooks (ActionRun and action logs), removes workflow-runs query/keys, updates hooks and UI to use ActionRun shapes and keys, converts several components to named exports, and standardizes the DiffEditor API and usage. (34 words)

Changes

Cohort / File(s) Summary
Removed workflow-runs modules
apps/studio/data/workflow-runs/workflow-runs-query.ts, apps/studio/data/workflow-runs/workflow-run-query.ts, apps/studio/data/workflow-runs/workflow-run-logs-query.ts, apps/studio/data/workflow-runs/keys.ts
Entire workflow-runs query modules and workflowRunKeys export deleted; list/detail/logs hooks, types, and query functions removed.
New action-run APIs & logs
apps/studio/data/actions/action-detail-query.ts, apps/studio/data/actions/action-logs-query.ts, apps/studio/data/actions/keys.ts
Introduced exported ActionRun type with derived status; getActionRun/useActionRunQuery and getActionRunLogs/useActionRunLogsQuery now accept { projectRef, runId }; added actionKeys.logs(...); logs return joined string; input validation added.
Hook changes (workflow management)
apps/studio/hooks/branches/useWorkflowManagement.ts
Hook now consumes ActionRun APIs, returns run and logs (renamed from currentWorkflowRun/workflowRunLogs), narrows onWorkflowComplete to `'SUCCESS'
Workflow logs UI / props & exports
apps/studio/components/interfaces/BranchManagement/WorkflowLogsCard.tsx, apps/studio/components/interfaces/BranchManagement/WorkflowLogs.tsx
Replaced local WorkflowRun with imported ActionRun; props updated to `ActionRun
DiffEditor API & consumers
apps/studio/components/ui/DiffEditor.tsx, apps/studio/components/ui/AIEditor/index.tsx, apps/studio/components/interfaces/BranchManagement/DatabaseDiffPanel.tsx, apps/studio/components/interfaces/BranchManagement/EdgeFunctionsDiffPanel.tsx, apps/studio/components/interfaces/SQLEditor/SQLEditor.tsx
Renamed/refactored DiffViewer → DiffEditor (language optional, removed sideBySide, added options and onMount); consumers switched to local DiffEditor, removed some theme/options props; several components converted to named exports and EdgeFunctionsDiffPanel prop mainBranchRef removed.
Page consumer updates
apps/studio/pages/project/[ref]/merge.tsx
Updated imports to named exports, adjusted hook destructuring to { run, logs }, tightened workflowFinalStatus typing to `'SUCCESS'

Sequence Diagram(s)

mermaid
sequenceDiagram
participant UI as Browser UI
participant Hook as useWorkflowManagement
participant Query as useActionRunQuery / useActionRunLogsQuery
participant API as Platform API
UI->>Hook: request run & logs (projectRef, runId)
Hook->>Query: start run query
Query->>API: GET /projects/{ref}/actions/{runId}
API-->>Query: ActionRun JSON (includes run_steps)
Query->>Hook: return ActionRun (status derived: RUNNING/SUCCESS/FAILED)
Hook->>Query: start logs query (enabled when runId present)
Query->>API: GET /projects/{ref}/actions/{runId}/logs
API-->>Query: raw logs text
Query->>Hook: return logs string
Hook->>UI: provide run and logs; emit onWorkflowComplete when status != RUNNING

Possibly related PRs

Suggested reviewers

  • alaister
  • ivasilov
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: migrating from platform endpoints to new v1 action runs endpoints for workflow logs.
Description check ✅ Passed The description covers context, main changes, unrelated improvements, and testing instructions, but lacks explicit confirmation of CONTRIBUTING.md review.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no longer used

@coveralls
Copy link

coveralls commented Jan 9, 2026

Coverage Status

coverage: 66.134% (+0.02%) from 66.113%
when pulling da08f46 on joshen/fe-2348-gitless-branch-merges-stuck-in-creating_project-status
into f293036 on master.

Comment on lines 8 to 17
// interface WorkflowRun {
// id: string
// status: string
// branch_id?: string
// check_run_id?: number | null
// created_at?: string
// updated_at?: string
// workdir?: string | null
// git_config?: unknown
// }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be obtained from API generated types, now exported in workflow-run-query

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @apps/studio/components/interfaces/BranchManagement/WorkflowLogsCard.tsx:
- Around line 50-54: The failure detection is inconsistent and empty run_steps
makes .every() return true; update the boolean logic for showSuccessIcon,
isFailed and isPolling to match workflow-run-query.ts: use .some() for isFailed
(so any DEAD marks failure), keep isPolling logic but guard all checks with a
run_steps length check (e.g., workflowRun?.run_steps?.length > 0) to avoid true
on empty arrays, and ensure showSuccessIcon requires length > 0 and all steps
EXITED; adjust the expressions named showSuccessIcon, isFailed, and isPolling
accordingly.

In @apps/studio/data/workflow-runs/workflow-run-query.ts:
- Around line 35-39: The status computation uses data?.run_steps
(isSuccess/isFailed) before checking for an API error, which can yield undefined
results; move the error handling so that the error is checked and handled
(handleError(error)) before computing isSuccess and isFailed, then compute
status from data.run_steps (or return early if data is undefined) and finally
return the WorkflowRun object; update references in this block including data,
error, isSuccess, isFailed, run_steps and the final return to reflect the
reordered/guarded logic.

In @apps/studio/pages/project/[ref]/merge.tsx:
- Around line 161-163: The isWorkflowRunning check only inspects
currentBranchWorkflow; update its definition to account for both workflows by
using the combined currentWorkflowRun status or explicitly checking both branch
workflows (e.g., replace currentBranchWorkflow?.status === 'RUNNING' with
currentWorkflowRun?.status === 'RUNNING' or currentBranchWorkflow?.status ===
'RUNNING' || parentBranchWorkflow?.status === 'RUNNING') so the merge button is
disabled when either workflow is running.
🧹 Nitpick comments (2)
apps/studio/hooks/branches/useWorkflowManagement.ts (1)

29-36: Missing enabled condition on logs query.

useWorkflowRunLogsQuery lacks an enabled condition, unlike useWorkflowRunQuery on line 22. While the underlying query has its own enabled check, adding an explicit enabled: Boolean(workflowRunId) here maintains consistency and makes the intent clearer.

Suggested fix
   const { data: workflowRunLogs } = useWorkflowRunLogsQuery(
     { projectRef, workflowRunId },
     {
+      enabled: Boolean(workflowRunId),
       refetchInterval: 2000,
       refetchOnMount: 'always',
       staleTime: 0,
     }
   )
apps/studio/components/interfaces/BranchManagement/WorkflowLogsCard.tsx (1)

8-17: Remove commented-out code.

Dead code should be removed rather than commented out. Version control preserves history if needed later.

Remove commented code
-// interface WorkflowRun {
-//   id: string
-//   status: string
-//   branch_id?: string
-//   check_run_id?: number | null
-//   created_at?: string
-//   updated_at?: string
-//   workdir?: string | null
-//   git_config?: unknown
-// }
-
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bd96fd7 and 55513b4.

📒 Files selected for processing (7)
  • apps/studio/components/interfaces/BranchManagement/WorkflowLogsCard.tsx
  • apps/studio/data/workflow-runs/keys.ts
  • apps/studio/data/workflow-runs/workflow-run-logs-query.ts
  • apps/studio/data/workflow-runs/workflow-run-query.ts
  • apps/studio/data/workflow-runs/workflow-runs-query.ts
  • apps/studio/hooks/branches/useWorkflowManagement.ts
  • apps/studio/pages/project/[ref]/merge.tsx
💤 Files with no reviewable changes (1)
  • apps/studio/data/workflow-runs/workflow-runs-query.ts
🧰 Additional context used
📓 Path-based instructions (2)
apps/studio/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/studio-best-practices.mdc)

apps/studio/**/*.{ts,tsx}: Assign complex conditions to descriptive variables instead of using multiple conditions in a single expression
Use consistent naming conventions for boolean variables: is prefix for state/identity, has prefix for possession, can prefix for capability/permission, should prefix for conditional behavior
Derive boolean state from existing state instead of storing it separately
Use early returns for guard clauses instead of deeply nested conditionals
Extract complex logic into custom hooks when logic becomes reusable or complex
Return objects from custom hooks instead of arrays for better extensibility and clearer API
Use discriminated unions for complex state management instead of multiple independent state fields
Avoid type casting (e.g., as any, as Type); instead validate values at runtime using zod schemas

Files:

  • apps/studio/data/workflow-runs/keys.ts
  • apps/studio/hooks/branches/useWorkflowManagement.ts
  • apps/studio/pages/project/[ref]/merge.tsx
  • apps/studio/components/interfaces/BranchManagement/WorkflowLogsCard.tsx
  • apps/studio/data/workflow-runs/workflow-run-logs-query.ts
  • apps/studio/data/workflow-runs/workflow-run-query.ts
apps/studio/**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/studio-best-practices.mdc)

apps/studio/**/*.tsx: Components should ideally be under 200-300 lines; break down large components with multiple distinct UI sections, complex conditional rendering, or multiple unrelated useState hooks
Extract repeated JSX patterns into reusable components instead of copying similar JSX blocks
Use consistent loading/error/success pattern: handle loading state first with early returns, then error state, then empty state, then render success state
Keep state as local as possible and only lift up when needed
Group related state using objects or reducers instead of multiple useState calls, preferring react-hook-form for form state management
Name event handlers consistently: use on prefix for prop callbacks and handle prefix for internal handlers
Avoid inline arrow functions for expensive operations; use useCallback to maintain stable function references
Use appropriate conditional rendering patterns: && for simple show/hide, ternary for binary choice, early returns or extracted components for multiple conditions
Avoid nested ternaries in JSX; use separate conditions or early returns instead
Use useMemo for expensive computations when the computation is genuinely expensive and the value is passed to memoized children
Define prop interfaces explicitly for React components with proper typing of props and callback handlers

Files:

  • apps/studio/pages/project/[ref]/merge.tsx
  • apps/studio/components/interfaces/BranchManagement/WorkflowLogsCard.tsx
🧠 Learnings (5)
📚 Learning: 2025-12-12T05:20:17.409Z
Learnt from: joshenlim
Repo: supabase/supabase PR: 41258
File: apps/studio/pages/project/[ref]/storage/vectors/buckets/[bucketId].tsx:9-9
Timestamp: 2025-12-12T05:20:17.409Z
Learning: In apps/studio/**/*.{ts,tsx}, use named imports for DefaultLayout: import { DefaultLayout } from 'components/layouts/DefaultLayout' instead of default import. This is the new practice being adopted across the studio app.

Applied to files:

  • apps/studio/data/workflow-runs/keys.ts
  • apps/studio/hooks/branches/useWorkflowManagement.ts
  • apps/studio/pages/project/[ref]/merge.tsx
  • apps/studio/components/interfaces/BranchManagement/WorkflowLogsCard.tsx
  • apps/studio/data/workflow-runs/workflow-run-logs-query.ts
  • apps/studio/data/workflow-runs/workflow-run-query.ts
📚 Learning: 2026-01-02T05:58:55.226Z
Learnt from: meGauravJain
Repo: supabase/supabase PR: 41658
File: apps/studio/components/interfaces/Connect/content/prisma/content.tsx:70-85
Timestamp: 2026-01-02T05:58:55.226Z
Learning: In Prisma configuration or related connection setup code, prefer the environment variable name DIRECT_URL for direct/non-pooled database connections instead of DATABASE_URL_UNPOOLED, per Prisma documentation. Update code that reads database connection strings to use DIRECT_URL where applicable, and document why this is preferred (explicit, documented behavior). Ensure your environment provides DIRECT_URL when using direct connections and fallback handling if needed.

Applied to files:

  • apps/studio/data/workflow-runs/keys.ts
  • apps/studio/hooks/branches/useWorkflowManagement.ts
  • apps/studio/pages/project/[ref]/merge.tsx
  • apps/studio/components/interfaces/BranchManagement/WorkflowLogsCard.tsx
  • apps/studio/data/workflow-runs/workflow-run-logs-query.ts
  • apps/studio/data/workflow-runs/workflow-run-query.ts
📚 Learning: 2025-12-11T16:46:18.701Z
Learnt from: CR
Repo: supabase/supabase PR: 0
File: .cursor/rules/studio-best-practices.mdc:0-0
Timestamp: 2025-12-11T16:46:18.701Z
Learning: Applies to apps/studio/**/*.{ts,tsx} : Return objects from custom hooks instead of arrays for better extensibility and clearer API

Applied to files:

  • apps/studio/hooks/branches/useWorkflowManagement.ts
📚 Learning: 2025-12-11T16:46:18.701Z
Learnt from: CR
Repo: supabase/supabase PR: 0
File: .cursor/rules/studio-best-practices.mdc:0-0
Timestamp: 2025-12-11T16:46:18.701Z
Learning: Applies to apps/studio/**/*.tsx : Define prop interfaces explicitly for React components with proper typing of props and callback handlers

Applied to files:

  • apps/studio/components/interfaces/BranchManagement/WorkflowLogsCard.tsx
📚 Learning: 2025-12-11T17:04:40.037Z
Learnt from: CR
Repo: supabase/supabase PR: 0
File: .cursor/rules/studio-ui.mdc:0-0
Timestamp: 2025-12-11T17:04:40.037Z
Learning: Applies to apps/studio/components/**/*.{ts,tsx} : Use CardContent for card sections, and CardFooter for actions within cards

Applied to files:

  • apps/studio/components/interfaces/BranchManagement/WorkflowLogsCard.tsx
🧬 Code graph analysis (4)
apps/studio/hooks/branches/useWorkflowManagement.ts (2)
apps/studio/data/workflow-runs/workflow-run-query.ts (1)
  • useWorkflowRunQuery (45-58)
apps/studio/data/workflow-runs/workflow-run-logs-query.ts (1)
  • useWorkflowRunLogsQuery (42-55)
apps/studio/pages/project/[ref]/merge.tsx (1)
apps/studio/hooks/branches/useWorkflowManagement.ts (1)
  • useWorkflowManagement (12-58)
apps/studio/data/workflow-runs/workflow-run-logs-query.ts (3)
apps/studio/data/graphql/graphql.ts (1)
  • Error (49-59)
apps/studio/data/fetchers.ts (1)
  • handleError (146-184)
apps/studio/data/workflow-runs/keys.ts (1)
  • workflowRunKeys (1-7)
apps/studio/data/workflow-runs/workflow-run-query.ts (2)
apps/studio/data/fetchers.ts (1)
  • handleError (146-184)
apps/studio/data/workflow-runs/keys.ts (1)
  • workflowRunKeys (1-7)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: typecheck
  • GitHub Check: test (1)
  • GitHub Check: test
🔇 Additional comments (6)
apps/studio/data/workflow-runs/keys.ts (1)

5-6: LGTM!

The new status key follows the existing pattern and provides proper namespacing for status-specific queries, differentiating from the detail key used for logs.

apps/studio/hooks/branches/useWorkflowManagement.ts (1)

39-47: LGTM!

The effect correctly guards against calling onWorkflowComplete until the workflow has finished (status !== 'RUNNING'), ensuring the callback only receives 'SUCCESS' or 'FAILED'. The hasRefetched flag prevents duplicate calls.

apps/studio/pages/project/[ref]/merge.tsx (1)

144-159: LGTM!

Good refactoring to align with the updated hook return shape. The fallback logic (currentBranchWorkflow || parentBranchWorkflow) correctly handles both workflow sources, and the renamed destructured variables improve clarity.

apps/studio/data/workflow-runs/workflow-run-query.ts (1)

45-58: LGTM!

The hook correctly uses the new status key, passes both projectRef and workflowRunId, and has proper enabled conditions checking both parameters are defined.

apps/studio/data/workflow-runs/workflow-run-logs-query.ts (2)

12-37: LGTM!

The function correctly validates required parameters, uses the new v1 endpoint, handles errors before returning, and returns a properly typed object. The parseAs: 'text' option justifies the type assertion on line 36.


42-55: LGTM!

The hook correctly uses workflowRunKeys.detail (differentiating from the status key used by useWorkflowRunQuery) and has proper enabled conditions requiring both projectRef and workflowRunId.

Comment on lines 35 to 39
const isSuccess = data?.run_steps.every((x) => ['EXITED', 'PAUSED'].includes(x.status))
const isFailed = data?.run_steps.some((x) => x.status === 'DEAD')

// Return an object with the logs and we'll extract status from headers if needed
return { logs: data as string, workflowRunId }
if (error) handleError(error)
return { ...data, status: isSuccess ? 'SUCCESS' : isFailed ? 'FAILED' : 'RUNNING' } as WorkflowRun
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Error handling occurs after accessing potentially undefined data.

Lines 35-36 access data?.run_steps before error handling on line 38. If the API returns an error, data may be undefined, and while optional chaining prevents a crash, isSuccess and isFailed will be undefined, leading to incorrect status derivation. Move error handling before data processing.

Reorder error handling
   const { data, error } = await get('/v1/projects/{ref}/actions/{run_id}', {
     params: {
       path: {
         ref: projectRef,
         run_id: workflowRunId,
       },
     },
     signal,
   })

+  if (error) handleError(error)
+
   const isSuccess = data?.run_steps.every((x) => ['EXITED', 'PAUSED'].includes(x.status))
   const isFailed = data?.run_steps.some((x) => x.status === 'DEAD')

-  if (error) handleError(error)
   return { ...data, status: isSuccess ? 'SUCCESS' : isFailed ? 'FAILED' : 'RUNNING' } as WorkflowRun

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In @apps/studio/data/workflow-runs/workflow-run-query.ts around lines 35 - 39,
The status computation uses data?.run_steps (isSuccess/isFailed) before checking
for an API error, which can yield undefined results; move the error handling so
that the error is checked and handled (handleError(error)) before computing
isSuccess and isFailed, then compute status from data.run_steps (or return early
if data is undefined) and finally return the WorkflowRun object; update
references in this block including data, error, isSuccess, isFailed, run_steps
and the final return to reflect the reordered/guarded logic.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 9, 2026

🎭 Playwright Test Results

passed  83 passed
flaky  1 flaky
skipped  4 skipped

Details

stats  88 tests across 14 suites
duration  8 minutes, 56 seconds
commit  da08f46

Flaky tests

Features › sql-editor.spec.ts › SQL Editor › should check if SQL editor is working as expected

Skipped tests

Features › sql-editor.spec.ts › SQL Editor › snippet favourite works as expected
Features › sql-editor.spec.ts › SQL Editor › share with team works as expected
Features › sql-editor.spec.ts › SQL Editor › folders works as expected
Features › sql-editor.spec.ts › SQL Editor › other SQL snippets actions work as expected

@joshenlim joshenlim marked this pull request as ready for review January 22, 2026 08:37
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@apps/studio/data/actions/action-detail-query.ts`:
- Around line 45-52: The query is being enabled for empty strings because
enabled only checks for undefined; fix by extracting descriptive booleans (e.g.,
hasValidProjectRef = typeof projectRef !== 'undefined' && projectRef !== '' and
hasValidRunId = typeof runId !== 'undefined' && runId !== '') and then use a
combined shouldEnable (enabled && hasValidProjectRef && hasValidRunId) in the
useQuery call (reference actionKeys.detail, getActionRun and the query's enabled
option) so empty strings won't trigger getActionRun; keep the new variables
local to the function for clarity.

In `@apps/studio/data/actions/action-logs-query.ts`:
- Around line 38-47: The query enablement currently only checks for undefined
but getActionRunLogs throws on empty strings; update the enabled condition used
in the useQuery call (queryKey: actionKeys.logs, queryFn: getActionRunLogs) to
validate runtime inputs by verifying projectRef and runId are non-empty (e.g.,
typeof !== 'undefined' && projectRef !== '' && runId !== ''), and extract that
multi-part validation into a descriptive boolean variable (e.g.,
hasValidIdentifiers) declared above the useQuery so the enabled flag uses that
variable instead of the current check; ensure you reference projectRef, runId,
getActionRunLogs, and actionKeys.logs when making the change.
🧹 Nitpick comments (4)
apps/studio/components/ui/DiffEditor.tsx (1)

4-16: Consider renaming interface to match exported component name.

The interface is named DiffViewerProps but the component is now exported as DiffEditor. For consistency and clarity, consider renaming to DiffEditorProps.

Suggested rename
-interface DiffViewerProps {
+interface DiffEditorProps {
   /** Original/left hand side content (optional) */
   original?: string
   /** Modified/right hand side content */
   modified: string | undefined
   /** Language identifier understood by Monaco */
   language?: string
   /** Height for the editor container */
   height?: string | number
   /** Diff Editor Options */
   options?: monacoEditor.IStandaloneDiffEditorConstructionOptions
   onMount?: (editor: monacoEditor.IStandaloneDiffEditor) => void
 }

And update the component signature:

 export const DiffEditor = ({
   ...
-}: DiffViewerProps) => (
+}: DiffEditorProps) => (
apps/studio/components/interfaces/BranchManagement/DatabaseDiffPanel.tsx (1)

8-14: Unused prop showRefreshButton in interface.

The showRefreshButton prop is defined in DatabaseDiffPanelProps but is not destructured or used in the component implementation. Consider removing it if it's no longer needed, or implement its functionality if it was intended.

If unused, remove from interface
 interface DatabaseDiffPanelProps {
   diffContent?: string
   isLoading: boolean
   error?: any
-  showRefreshButton?: boolean
   currentBranchRef?: string
 }
apps/studio/components/interfaces/BranchManagement/EdgeFunctionsDiffPanel.tsx (1)

207-223: Commented code references removed prop mainBranchRef.

The commented-out code for removed functions (line 217) still references mainBranchRef, which has been removed from the component's props interface. If this feature is to be implemented later, the prop would need to be re-added. Consider either updating the comment to reflect the current API or removing the dead code entirely.

Option 1: Remove the commented code entirely
       ))}
     </div>
   )}
-  {/* TODO: Removing functions is not supported yet */}
-  {/* {diffResults.removedSlugs.length > 0 && (
-    <div>
-      <div className="space-y-4">
-        {diffResults.removedSlugs.map((slug) => (
-          <FunctionDiff
-            key={slug}
-            functionSlug={slug}
-            currentBody={EMPTY_ARR}
-            mainBody={diffResults.removedBodiesMap[slug]!}
-            currentBranchRef={mainBranchRef}
-            fileInfos={diffResults.functionFileInfo[slug] || EMPTY_ARR}
-          />
-        ))}
-      </div>
-    </div>
-  )} */}

   {diffResults.modifiedSlugs.length > 0 && (
Option 2: Add a note about the missing prop
-  {/* TODO: Removing functions is not supported yet */}
+  {/* TODO: Removing functions is not supported yet. Note: mainBranchRef prop was removed and would need to be re-added. */}
apps/studio/data/actions/action-detail-query.ts (1)

35-38: Avoid the as ActionRun assertion.
Prefer returning a typed value directly to avoid type casting.

♻️ Suggested update
-export async function getActionRun(
-  { projectRef, runId }: ActionRunVariables,
-  signal?: AbortSignal
-) {
+export async function getActionRun(
+  { projectRef, runId }: ActionRunVariables,
+  signal?: AbortSignal
+): Promise<ActionRun> {
@@
-  return {
-    ...data,
-    status: isRunning ? 'RUNNING' : isSuccess ? 'SUCCESS' : isFailed ? 'FAILED' : 'RUNNING',
-  } as ActionRun
+  const status = isRunning ? 'RUNNING' : isSuccess ? 'SUCCESS' : isFailed ? 'FAILED' : 'RUNNING'
+  return { ...data, status }
 }
As per coding guidelines, avoid type casting in favor of runtime-safe typing.

Comment on lines +45 to 52
{ projectRef, runId }: ActionRunVariables,
{ enabled = true, ...options }: UseCustomQueryOptions<ActionRunData, ActionRunError, TData> = {}
) =>
useQuery<ActionRunData, ActionRunError, TData>({
queryKey: actionKeys.detail(ref, run_id),
queryFn: ({ signal }) => getActionRun({ ref, run_id }, signal),
enabled: enabled && Boolean(ref) && Boolean(run_id),
queryKey: actionKeys.detail(projectRef, runId),
queryFn: ({ signal }) => getActionRun({ projectRef, runId }, signal),
enabled: enabled && typeof projectRef !== 'undefined' && typeof runId !== 'undefined',
staleTime: 0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Align query enablement with runtime validation.
getActionRun throws on empty strings, but enabled only checks for undefined, so empty strings still trigger the query and error.

✅ Suggested fix
-export const useActionRunQuery = <TData = ActionRunData>(
-  { projectRef, runId }: ActionRunVariables,
-  { enabled = true, ...options }: UseCustomQueryOptions<ActionRunData, ActionRunError, TData> = {}
-) =>
-  useQuery<ActionRunData, ActionRunError, TData>({
+export const useActionRunQuery = <TData = ActionRunData>(
+  { projectRef, runId }: ActionRunVariables,
+  { enabled = true, ...options }: UseCustomQueryOptions<ActionRunData, ActionRunError, TData> = {}
+) => {
+  const hasActionRunParams = Boolean(projectRef && runId)
+  return useQuery<ActionRunData, ActionRunError, TData>({
     queryKey: actionKeys.detail(projectRef, runId),
     queryFn: ({ signal }) => getActionRun({ projectRef, runId }, signal),
-    enabled: enabled && typeof projectRef !== 'undefined' && typeof runId !== 'undefined',
+    enabled: enabled && hasActionRunParams,
     staleTime: 0,
     ...options,
   })
+}
As per coding guidelines, extract multi-part conditions into descriptive variables.
🤖 Prompt for AI Agents
In `@apps/studio/data/actions/action-detail-query.ts` around lines 45 - 52, The
query is being enabled for empty strings because enabled only checks for
undefined; fix by extracting descriptive booleans (e.g., hasValidProjectRef =
typeof projectRef !== 'undefined' && projectRef !== '' and hasValidRunId =
typeof runId !== 'undefined' && runId !== '') and then use a combined
shouldEnable (enabled && hasValidProjectRef && hasValidRunId) in the useQuery
call (reference actionKeys.detail, getActionRun and the query's enabled option)
so empty strings won't trigger getActionRun; keep the new variables local to the
function for clarity.

Comment on lines +38 to +47
{ projectRef, runId }: ActionLogsVariables,
{
enabled = true,
...options
}: UseCustomQueryOptions<ActionLogsData, WorkflowRunLogsError, TData> = {}
) =>
useQuery<ActionLogsData, WorkflowRunLogsError, TData>({
queryKey: actionKeys.detail(ref, run_id),
queryFn: ({ signal }) => getActionRunLogs({ ref, run_id }, signal),
enabled: enabled && Boolean(ref) && Boolean(run_id),
queryKey: actionKeys.logs(projectRef, runId),
queryFn: ({ signal }) => getActionRunLogs({ projectRef, runId }, signal),
enabled: enabled && typeof projectRef !== 'undefined' && typeof runId !== 'undefined',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Align query enablement with runtime validation.
getActionRunLogs throws on empty strings, but enabled only guards undefined.

✅ Suggested fix
-export const useActionRunLogsQuery = <TData = ActionLogsData>(
-  { projectRef, runId }: ActionLogsVariables,
-  {
-    enabled = true,
-    ...options
-  }: UseCustomQueryOptions<ActionLogsData, WorkflowRunLogsError, TData> = {}
-) =>
-  useQuery<ActionLogsData, WorkflowRunLogsError, TData>({
+export const useActionRunLogsQuery = <TData = ActionLogsData>(
+  { projectRef, runId }: ActionLogsVariables,
+  {
+    enabled = true,
+    ...options
+  }: UseCustomQueryOptions<ActionLogsData, WorkflowRunLogsError, TData> = {}
+) => {
+  const hasActionRunParams = Boolean(projectRef && runId)
+  return useQuery<ActionLogsData, WorkflowRunLogsError, TData>({
     queryKey: actionKeys.logs(projectRef, runId),
     queryFn: ({ signal }) => getActionRunLogs({ projectRef, runId }, signal),
-    enabled: enabled && typeof projectRef !== 'undefined' && typeof runId !== 'undefined',
+    enabled: enabled && hasActionRunParams,
     staleTime: 0,
     ...options,
   })
+}
As per coding guidelines, extract multi-part conditions into descriptive variables.
🤖 Prompt for AI Agents
In `@apps/studio/data/actions/action-logs-query.ts` around lines 38 - 47, The
query enablement currently only checks for undefined but getActionRunLogs throws
on empty strings; update the enabled condition used in the useQuery call
(queryKey: actionKeys.logs, queryFn: getActionRunLogs) to validate runtime
inputs by verifying projectRef and runId are non-empty (e.g., typeof !==
'undefined' && projectRef !== '' && runId !== ''), and extract that multi-part
validation into a descriptive boolean variable (e.g., hasValidIdentifiers)
declared above the useQuery so the enabled flag uses that variable instead of
the current check; ensure you reference projectRef, runId, getActionRunLogs, and
actionKeys.logs when making the change.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/studio/components/interfaces/BranchManagement/EdgeFunctionsDiffPanel.tsx (1)

3-34: Use a lightweight basename implementation to avoid importing Node path in client-side components.

The codebase already has path-browserify as a transitive dependency and Next.js handles Node module polyfills automatically, but the related hook useEdgeFunctionsDiff.ts explicitly acknowledges this concern with a comment: "avoids importing the full Node path lib for the browser bundle". For consistency and to follow the pattern already established in the codebase, replace the Node path import with a simple inline helper:

-import { basename } from 'path'
-
-const fileKey = (fullPath: string) => basename(fullPath)
+const fileKey = (fullPath: string) => {
+  const normalized = fullPath.replace(/\\/g, '/')
+  return normalized.slice(normalized.lastIndexOf('/') + 1)
+}

This aligns with the approach already used in useEdgeFunctionsDiff.ts and removes an unnecessary dependency from the client bundle.

apps/studio/components/interfaces/BranchManagement/WorkflowLogs.tsx (1)

7-7: Fix build-breaking selectedWorkflowRun type mismatch.

TS2345 at Line 112 is caused by setSelectedWorkflowRun(workflowRun) feeding a list item without status into a state typed as ActionRunData. Align the state type with the list item (or derive status) to unblock the build.

🐛 Proposed fix (align state with list item type)
-import { ActionRunData } from 'data/actions/action-detail-query'
+// ActionRunData no longer needed once state aligns with list items

-const [selectedWorkflowRun, setSelectedWorkflowRun] = useState<ActionRunData | undefined>(
-  undefined
-)
+const [selectedWorkflowRun, setSelectedWorkflowRun] = useState<
+  NonNullable<typeof workflowRuns>[number] | undefined
+>(undefined)

Also applies to: 53-55, 109-113

🧹 Nitpick comments (2)
apps/studio/data/actions/action-detail-query.ts (1)

17-38: Avoid as ActionRun cast; return a typed object instead.

Prefer a typed return + explicit status variable to avoid casting. As per coding guidelines, avoid as Type where possible.

♻️ Proposed refactor
 export async function getActionRun(
   { projectRef, runId }: ActionRunVariables,
   signal?: AbortSignal
-) {
+): Promise<ActionRun> {
@@
-  return {
-    ...data,
-    status: isRunning ? 'RUNNING' : isSuccess ? 'SUCCESS' : isFailed ? 'FAILED' : 'RUNNING',
-  } as ActionRun
+  const status: ActionRun['status'] =
+    isRunning ? 'RUNNING' : isSuccess ? 'SUCCESS' : isFailed ? 'FAILED' : 'RUNNING'
+
+  return { ...data, status }
 }
apps/studio/components/interfaces/BranchManagement/WorkflowLogsCard.tsx (1)

6-6: Move nested ternary out of JSX for readability.

Assign the class to a descriptive variable to avoid nested ternaries in JSX, as per coding guidelines.

♻️ Proposed refactor
-import { Button, Card, CardContent, CardHeader, CardTitle } from 'ui'
+import { Button, Card, CardContent, CardHeader, CardTitle, cn } from 'ui'
@@
-  return (
+  const headerClassName = cn({
+    'text-brand': isSuccess,
+    'text-destructive': isFailed,
+  })
+
+  return (
     <Card className="bg-background overflow-hidden h-64 flex flex-col">
-      <CardHeader className={isSuccess ? 'text-brand' : isFailed ? 'text-destructive' : ''}>
+      <CardHeader className={headerClassName}>

Also applies to: 69-69

Copy link
Contributor

@awaseem awaseem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put some comments in the slack thread, Just need to test to make sure this is working correctly

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/studio/pages/project/[ref]/merge.tsx (1)

114-131: Gate review request reset on successful workflow completion.

updateBranch({ requestReview: false }) currently fires for both SUCCESS and FAILED statuses. This should only execute on status === 'SUCCESS' — clearing the review request when a workflow fails removes the review flag that developers need to address failures and re-request review.

✅ Suggested fix
-      if (ref && parentProjectRef && currentBranch?.review_requested_at) {
+      if (status === 'SUCCESS' && ref && parentProjectRef && currentBranch?.review_requested_at) {
         updateBranch(
           {
             branchRef: ref,
             projectRef: parentProjectRef,
             requestReview: false,
           },

Copy link
Contributor

@awaseem awaseem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@joshenlim joshenlim merged commit bddd04b into master Jan 23, 2026
25 checks passed
@joshenlim joshenlim deleted the joshen/fe-2348-gitless-branch-merges-stuck-in-creating_project-status branch January 23, 2026 07:29
@github-actions
Copy link
Contributor

github-actions bot commented Jan 23, 2026

Braintrust eval report

Assistant (master-1769153448)

Score Average Improvements Regressions
Completeness 100% (+0pp) - -
Conciseness 0% (+0pp) - -
Docs Faithfulness 62.5% (+13pp) 1 🟢 -
Goal Completion 87.5% (+0pp) - -
Tool Usage 75% (+0pp) - -
Correctness 100% (+0pp) - -
SQL Validity 100% (+0pp) - -
Time_to_first_token 0.23tok (-0.01tok) 3 🟢 5 🔴
Llm_calls 7.75 (+0) 1 🟢 1 🔴
Tool_calls 2.38 (+0) 1 🟢 1 🔴
Errors 0 (+0) - -
Llm_errors 0 (+0) - -
Tool_errors 0 (+0) - -
Prompt_tokens 65525.5tok (-24565.25tok) 6 🟢 2 🔴
Prompt_cached_tokens 31648tok (-23328tok) 2 🟢 3 🔴
Prompt_cache_creation_tokens 0tok (+0tok) - -
Completion_tokens 4562.75tok (-420.5tok) 5 🟢 3 🔴
Completion_reasoning_tokens 3200tok (-416tok) 5 🟢 3 🔴
Completion_accepted_prediction_tokens 0tok (+0tok) - -
Completion_rejected_prediction_tokens 0tok (+0tok) - -
Completion_audio_tokens 0tok (+0tok) - -
Total_tokens 70088.25tok (-24985.75tok) 5 🟢 3 🔴
Estimated_cost 0.02$ (0$) 5 🟢 3 🔴
Duration 36.67s (-14.65s) 8 🟢 -
Llm_duration 72.54s (-29.12s) 8 🟢 -

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants