From 375cbcf4a20d4e1b9e7697b5c845489b319ce63f Mon Sep 17 00:00:00 2001 From: Gildas Garcia <1122076+djhi@users.noreply.github.com> Date: Thu, 4 Jun 2026 15:34:59 +0200 Subject: [PATCH 1/4] feat: add a dashboard button to retrigger a branch workflow (#46626) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Problem When workflow runs for branches fail due to stuck tasks, they can sit idle indefinitely. Users are unaware that they need to make a new commit to retrigger the workflow — leading to confusion, wasted time, and silent failures going unnoticed. ## Solution Provide a button that allows users to retrigger a workflow when it is not being removed. ## How to test - Create a branch - Wait for its row to appear on the branch management page - Click the _View logs_ button - You should see a _Retrigger_ button - Clicking it should make a new row appear in those logs ## Summary by CodeRabbit * **New Features** * Retrigger previously executed workflows directly from branch preview actions. * Confirmation dialog added for retrigger actions. * **Improvements** * Toast-style error notifications when retriggering fails. * Workflow run list layout updated for a more flexible horizontal display. * After retriggering, workflow and action lists refresh so updates appear promptly. --- .../interfaces/BranchManagement/Overview.tsx | 105 ++++++++++++++---- .../BranchManagement/WorkflowLogs.tsx | 2 +- .../data/branches/branch-push-mutation.ts | 2 + 3 files changed, 85 insertions(+), 24 deletions(-) diff --git a/apps/studio/components/interfaces/BranchManagement/Overview.tsx b/apps/studio/components/interfaces/BranchManagement/Overview.tsx index af133208449d1..bec2163e23bee 100644 --- a/apps/studio/components/interfaces/BranchManagement/Overview.tsx +++ b/apps/studio/components/interfaces/BranchManagement/Overview.tsx @@ -8,6 +8,7 @@ import { Infinity, MoreVertical, Pencil, + Redo, RefreshCw, Shield, Trash2, @@ -30,6 +31,7 @@ import { EditBranchModal } from './EditBranchModal' import { PreviewBranchesEmptyState } from './EmptyStates' import { DropdownMenuItemTooltip } from '@/components/ui/DropdownMenuItemTooltip' import { TextConfirmModal } from '@/components/ui/TextConfirmModalWrapper' +import { useBranchPushMutation } from '@/data/branches/branch-push-mutation' import { useBranchQuery } from '@/data/branches/branch-query' import { useBranchResetMutation } from '@/data/branches/branch-reset-mutation' import { useBranchRestoreMutation } from '@/data/branches/branch-restore-mutation' @@ -262,6 +264,7 @@ const PreviewBranchActions = ({ setShowPersistentBranchDeleteConfirmationModal, ] = useState(false) const [showEditBranchModal, setShowEditBranchModal] = useState(false) + const [showConfirmRetriggersModal, setShowConfirmRetriggersModal] = useState(false) const { mutate: resetBranch, isPending: isResetting } = useBranchResetMutation({ onSuccess() { @@ -286,6 +289,20 @@ const PreviewBranchActions = ({ }, }) + const { mutate: branchPushMutate, isPending: isRetriggering } = useBranchPushMutation({ + onSuccess() { + toast.success('Success! Please allow a few minutes for the branch to update.') + setShowConfirmRetriggersModal(false) + }, + onError: (data) => { + toast.error(`Failed to trigger workflow: ${data.message}`) + }, + }) + + const onRetriggerBranch = () => { + branchPushMutate({ branchRef, projectRef }) + } + const onRestoreBranch = () => { restoreBranch({ branchRef, projectRef }) } @@ -345,28 +362,54 @@ const PreviewBranchActions = ({ {!branch.deletion_scheduled_at && ( - { - e.stopPropagation() - setShowConfirmResetModal(true) - }} - onClick={(e) => { - e.stopPropagation() - setShowConfirmResetModal(true) - }} - tooltip={{ - content: { - side: 'left', - text: !isBranchActiveHealthy - ? 'Branch is still initializing. Please wait for it to become healthy before resetting.' - : undefined, - }, - }} - > - Reset branch - + <> + { + e.stopPropagation() + setShowConfirmRetriggersModal(true) + }} + onClick={(e) => { + e.stopPropagation() + setShowConfirmRetriggersModal(true) + }} + tooltip={{ + content: { + side: 'left', + text: !canUpdateBranches + ? `You need additional permissions to ${branch.git_branch ? 'resync' : 'rebase'} branches` + : !isBranchActiveHealthy + ? `Branch is still initializing. Please wait for it to become healthy before ${branch.git_branch ? 'resyncing' : 'rebasing'}.` + : undefined, + }, + }} + > + {branch.git_branch ? 'Resync branch' : 'Rebase branch'} + + { + e.stopPropagation() + setShowConfirmResetModal(true) + }} + onClick={(e) => { + e.stopPropagation() + setShowConfirmResetModal(true) + }} + tooltip={{ + content: { + side: 'left', + text: !isBranchActiveHealthy + ? 'Branch is still initializing. Please wait for it to become healthy before resetting.' + : undefined, + }, + }} + > + Reset branch + + )} {!branch.deletion_scheduled_at && ( @@ -497,10 +540,26 @@ const PreviewBranchActions = ({

+ setShowConfirmRetriggersModal(false)} + onConfirm={onRetriggerBranch} + > +

+ {branch.git_branch + ? 'This will re-run all steps of the workflow based on the latest git branch state.' + : 'This will re-run all steps of the workflow based on the latest dashboard state.'} +

+
+ setShowPersistentBranchDeleteConfirmationModal(false)} diff --git a/apps/studio/components/interfaces/BranchManagement/WorkflowLogs.tsx b/apps/studio/components/interfaces/BranchManagement/WorkflowLogs.tsx index f5967e6d7be7f..307289013f2f0 100644 --- a/apps/studio/components/interfaces/BranchManagement/WorkflowLogs.tsx +++ b/apps/studio/components/interfaces/BranchManagement/WorkflowLogs.tsx @@ -111,7 +111,7 @@ export const WorkflowLogs = ({ branch }: WorkflowLogsProps) => { (workflowRuns.length > 0 ? (