Workflow action to run another workflow (RUN_WORKFLOW) #25896
Replies: 3 comments
|
This is a feature request, not a bug. Restated: The request is to add a workflow action that can trigger another workflow ( Severity: UNDEFINED, as this is a feature request (the current behavior is as designed; no defect or regression). Root-cause: Not applicable; this would require new features in both server ( The report is clear and complete for a feature proposal; no missing info. |
|
@thomtrp I recall similar issue in core-team-issues but can't find it at all |
|
A PR implementing this is up: #26032 — adds the |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Scope & Context
Workflows cannot call other workflows. Every workflow is a self-contained graph, so shared logic (notify the owner, post to Slack, enrich a company, log an activity) has to be rebuilt step by step in each workflow that needs it, and kept in sync by hand when it changes.
This ticket proposes a
RUN_WORKFLOWaction that starts a run of another workflow, in fire-and-forget mode only. Waiting for the child run and reading its result back is deliberately out of scope (see "Not in this change").Current behavior
There are 20 action types in
WorkflowActionType(packages/twenty-shared/src/workflow/types/WorkflowActionType.ts); none starts another workflow.The closest workarounds are:
HTTP_REQUESTto the workspace's own webhook trigger URL. This works but requires the callee to expose a webhook trigger (a public, unauthenticated URL), and pays an HTTP round trip through the public endpoint for an in-process operation.Expected behavior
A
RUN_WORKFLOWaction available in the action picker ("Run workflow"), with settings:workflowId: the workflow to run, picked from the workspace's workflows.input: an object mapped by the user from the parent's variables, passed to the child as its trigger payload.At execution time the action:
WorkflowRunnerWorkspaceService.run({ workflowVersionId, payload, source }), withsourcebuilt withFieldActorSource.WORKFLOWand the parent workflow's name, the same wayWorkflowTriggerJobdoes today.{ workflowRunId }as the step result so downstream steps can reference the child run.The child run is a normal
workflowRunrecord: it shows up in the callee's run list, throttling applies, retry and stop work as for any other run.The parent run does not wait for the child.
Guards
WorkflowStepExecutorException, and the step editor should warn when the selected workflow is not active.runDepthin the trigger payload metadata alongside the existingWORKFLOW_TRIGGER_METADATA_KEYand fail the step above a fixed depth (for example 5). Open to a different mechanism if the team prefers.Not in this change
parentWorkflowRunId/parentStepId) and a completion hook inendWorkflowRun, which thependingEvent+ resume-job pattern used byDELAYcould support later. Since the run entity's relations are still being rewired for the core workflow tables (feat(workflow): read and dispatch workflow versions from core everywhere #24830, feat(workflow): dispatch workflow triggers on core ids #25104, feat(workflow): add workspaceWorkflowId to core workflows #25723), I'd keep the initial PR free of entity changes.Implementation notes
Server:
WorkflowActionType.RUN_WORKFLOWintwenty-shared.workflow-executor/workflow-actions/run-workflow/with the action, guard, settings type and module, followingdelay/.workflow-action.factory.ts,workflow-action.type.ts, and defaults inworkflow-version-step-operations.workspace-service.ts.Front:
RunWorkflowAction.tsinworkflow-actions/constants/actions/, added toFlowActions.ts.WorkflowEditActionRunWorkflow.tsxwith a workflow picker and the input mapping form.getActionIcon.ts,getActionIconColorOrThrow.ts,WorkflowDiagramStepNodeIcon.tsx,WorkflowStepDetail.tsx,WorkflowRunStepNodeDetail.tsx,computeStepOutputSchema.ts(output:workflowRunId).Size should be comparable to the DELAY action (#14915).
Happy to take this on if the scope above works for you. The main thing I'd like a call on before writing code is the recursion guard.
All reactions