Skip to Content
Upcoming action-learning journey: Accra, Ghana @ May 18, 2025

Deployment Workflow Framework (Vercel/Next.js)

Overview

A client-coordinated deployment system that executes multi-step workflows for provisioning client applications using third-party APIs (e.g., GitHub, Vercel). Workflows are defined statically but executed dynamically with user-provided inputs. The system is serverless-compatible, modular, and supports asynchronous step execution.


Architecture Summary

LayerRole
ClientTriggers and polls actions for each app using a workflow ID
API/api/deploy handles triggering and polling per action
RuntimeActions execute with isolated context (args/config/env)
StoreInputs, secrets, config, and per-app state cached or persisted externally

Execution Flow

Client-Side

await triggerAndPollAction(workflowId, appId, actionId);
  • Sends a trigger request to start action execution.
  • Polls every 2 seconds until the action is done or error.

Server-Side (/api/deploy.ts)

if (mode === 'trigger') { const resolvedAction = resolveActionFromWorkflow(workflow, actionId, req.body); updateAppState(appId, actionId, 'running'); runAction(appId, resolvedAction, config, envVars) .then(() => updateAppState(appId, actionId, 'done')) .catch(() => updateAppState(appId, actionId, 'error')); }

Workflow System Design

WorkflowDefinition

type WorkflowDefinition = WorkflowDefinitionStep[]; interface WorkflowDefinitionStep<TArgs = any> { id: string; definition: ActionDefinition<TArgs>; inputKey: string; }

Defined in: /lib/workflows/definitions/*.ts


ActionDefinition

interface ActionDefinition<TArgs = any> { id: string; run: (args: TArgs) => Promise<void>; validate?: (args: TArgs) => void; }

Defined in: /lib/workflows/actions/*.ts


ResolvedAction

interface ResolvedAction<TArgs = any> { id: string; args: TArgs; run: (args: TArgs) => Promise<void>; }

Created at runtime using user input and workflow metadata.

Features and Considerations

  • No central action registry; actions are statically imported and passed directly to the runner.
  • Status tracking handled via getAppActionStatus() and updateAppState().
  • Supports parallel deployments across multiple apps (appId scoped).
  • Secrets, config, and env vars injected via cached payloads (design finalization pending).
  • Compatible with Vercel’s serverless execution model; actions execute asynchronously and non-blocking.
Last updated on