Documentation
¶
Overview ¶
Package workflow provides multi-step API workflow orchestration for CliForge.
The workflow package enables complex multi-step operations that go beyond simple HTTP requests, including sequential and parallel execution, conditional branching, loops, polling, and automatic rollback on failures.
Step Types ¶
- api-call: Execute HTTP API requests
- plugin: Invoke external tools or plugins
- conditional: Branch execution based on conditions
- loop: Iterate over collections
- wait: Delay or poll for status changes
- parallel: Execute multiple steps concurrently
Workflow Features ¶
- DAG-based dependency resolution
- Automatic retry with exponential backoff
- Rollback actions for failed steps
- Output mapping between steps
- Expression evaluation for conditions and data transformation
Example Workflow Definition ¶
workflow:
steps:
- id: create-resource
type: api-call
api-call:
method: POST
endpoint: /api/resources
- id: wait-ready
type: wait
depends-on: [create-resource]
wait:
polling:
endpoint: /api/resources/{id}/status
interval: 5
terminal-states: [ready, failed]
OpenAPI Integration ¶
Workflows are defined via x-cli-workflow extensions in OpenAPI specs and executed automatically when a command is invoked.
Index ¶
- type APICallStep
- type BackoffConfig
- type BackoffType
- type ConditionalStep
- type DAG
- type DAGNode
- type ErrorMatch
- type ExecutionContext
- func (c *ExecutionContext) AddRollbackAction(action *RollbackAction)
- func (c *ExecutionContext) Clone() *ExecutionContext
- func (c *ExecutionContext) GetRollbackActions() []*RollbackAction
- func (c *ExecutionContext) GetStepResult(stepID string) (*StepResult, bool)
- func (c *ExecutionContext) GetVariable(key string) (interface{}, bool)
- func (c *ExecutionContext) SetStepResult(stepID string, result *StepResult)
- func (c *ExecutionContext) SetVariable(key string, value interface{})
- type ExecutionState
- type ExecutionStatus
- type Executor
- type ExprEvaluator
- func (e *ExprEvaluator) EvaluateCondition(condition string) (bool, error)
- func (e *ExprEvaluator) EvaluateExpression(expression string) (interface{}, error)
- func (e *ExprEvaluator) InterpolateMap(m map[string]interface{}) (map[string]interface{}, error)
- func (e *ExprEvaluator) InterpolateString(template string) (string, error)
- func (e *ExprEvaluator) InterpolateStringMap(m map[string]string) (map[string]string, error)
- type LoopStep
- type ParallelStep
- type Parser
- type PluginStep
- type PollingConfig
- type RetryConfig
- type RollbackAction
- type RollbackManager
- type RollbackStatus
- type Settings
- type StateManager
- func (sm *StateManager) CleanupOldStates(maxAge int) error
- func (sm *StateManager) DeleteState(workflowID string) error
- func (sm *StateManager) GetStateFilePath(workflowID string) string
- func (sm *StateManager) ListStates() ([]*ExecutionState, error)
- func (sm *StateManager) LoadState(workflowID string) (*ExecutionState, error)
- func (sm *StateManager) SaveState(state *ExecutionState) error
- func (sm *StateManager) StateExists(workflowID string) bool
- type Step
- type StepExecutor
- type StepResult
- type StepType
- type WaitStep
- type Workflow
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type APICallStep ¶
type APICallStep struct {
Endpoint string `json:"endpoint"`
Method string `json:"method"`
Headers map[string]string `json:"headers,omitempty"`
Body map[string]interface{} `json:"body,omitempty"`
Query map[string]string `json:"query,omitempty"`
}
APICallStep defines an HTTP API call step.
type BackoffConfig ¶
type BackoffConfig struct {
Type BackoffType `json:"type,omitempty"`
InitialInterval int `json:"initial-interval,omitempty"` // seconds
Multiplier float64 `json:"multiplier,omitempty"`
MaxInterval int `json:"max-interval,omitempty"` // seconds
}
BackoffConfig defines exponential backoff settings.
type BackoffType ¶
type BackoffType string
BackoffType defines the type of backoff strategy.
const ( // BackoffFixed represents a fixed delay between retries. BackoffFixed BackoffType = "fixed" // BackoffLinear represents linearly increasing delay between retries. BackoffLinear BackoffType = "linear" // BackoffExponential represents exponentially increasing delay between retries. BackoffExponential BackoffType = "exponential" )
type ConditionalStep ¶
type ConditionalStep struct {
Condition string `json:"condition"`
Then []*Step `json:"then,omitempty"`
Else []*Step `json:"else,omitempty"`
}
ConditionalStep defines a conditional branching step.
type DAG ¶
type DAG struct {
Nodes map[string]*DAGNode
Edges map[string][]string // stepID -> []dependentStepIDs
}
DAG represents a Directed Acyclic Graph of workflow steps.
type DAGNode ¶
type DAGNode struct {
Step *Step
Dependencies []string
Dependents []string
Level int // Depth in the graph for topological ordering
}
DAGNode represents a node in the dependency graph.
type ErrorMatch ¶
type ErrorMatch struct {
HTTPStatus *int `json:"http-status,omitempty"`
ErrorType string `json:"error-type,omitempty"`
}
ErrorMatch defines criteria for matching errors.
type ExecutionContext ¶
type ExecutionContext struct {
// Flags from CLI arguments
Flags map[string]interface{}
// Variables for temporary storage
Variables map[string]interface{}
// Step results keyed by step ID
StepResults map[string]*StepResult
// Completed steps in order
CompletedSteps []*StepResult
// Rollback actions to execute if workflow fails
RollbackActions []*RollbackAction
// HTTP client for API calls
HTTPClient interface{} // Will be *http.Client
// Plugin executor interface
PluginExecutor interface{}
// contains filtered or unexported fields
}
ExecutionContext holds the state and data for workflow execution.
func NewExecutionContext ¶
func NewExecutionContext(flags map[string]interface{}) *ExecutionContext
NewExecutionContext creates a new execution context.
func (*ExecutionContext) AddRollbackAction ¶
func (c *ExecutionContext) AddRollbackAction(action *RollbackAction)
AddRollbackAction adds a rollback action to the stack.
func (*ExecutionContext) Clone ¶
func (c *ExecutionContext) Clone() *ExecutionContext
Clone creates a shallow copy of the context for nested execution.
func (*ExecutionContext) GetRollbackActions ¶
func (c *ExecutionContext) GetRollbackActions() []*RollbackAction
GetRollbackActions returns all rollback actions in reverse order.
func (*ExecutionContext) GetStepResult ¶
func (c *ExecutionContext) GetStepResult(stepID string) (*StepResult, bool)
GetStepResult retrieves the result of a step.
func (*ExecutionContext) GetVariable ¶
func (c *ExecutionContext) GetVariable(key string) (interface{}, bool)
GetVariable retrieves a context variable.
func (*ExecutionContext) SetStepResult ¶
func (c *ExecutionContext) SetStepResult(stepID string, result *StepResult)
SetStepResult stores the result of a step execution.
func (*ExecutionContext) SetVariable ¶
func (c *ExecutionContext) SetVariable(key string, value interface{})
SetVariable sets a context variable.
type ExecutionState ¶
type ExecutionState struct {
WorkflowID string
StartTime time.Time
Status ExecutionStatus
CompletedSteps []*StepResult
CurrentStep string
Error error
}
ExecutionState represents the state of workflow execution.
type ExecutionStatus ¶
type ExecutionStatus string
ExecutionStatus defines the status of workflow execution.
const ( // ExecutionStatusPending indicates the workflow is waiting to start. ExecutionStatusPending ExecutionStatus = "pending" // ExecutionStatusRunning indicates the workflow is currently executing. ExecutionStatusRunning ExecutionStatus = "running" // ExecutionStatusCompleted indicates the workflow completed successfully. ExecutionStatusCompleted ExecutionStatus = "completed" // ExecutionStatusFailed indicates the workflow failed. ExecutionStatusFailed ExecutionStatus = "failed" // ExecutionStatusRolledBack indicates the workflow was rolled back. ExecutionStatusRolledBack ExecutionStatus = "rolled-back" )
type Executor ¶
type Executor struct {
// contains filtered or unexported fields
}
Executor executes workflows.
func NewExecutor ¶
func NewExecutor(workflow *Workflow, httpClient *http.Client, pluginExecutor interface{}) (*Executor, error)
NewExecutor creates a new workflow executor.
func (*Executor) Execute ¶
func (e *Executor) Execute(ctx *ExecutionContext) (*ExecutionState, error)
Execute executes the workflow.
func (*Executor) Resume ¶
func (e *Executor) Resume(stateID string, ctx *ExecutionContext) (*ExecutionState, error)
Resume resumes a workflow from a saved state.
type ExprEvaluator ¶
type ExprEvaluator struct {
// contains filtered or unexported fields
}
ExprEvaluator evaluates expressions in the context of workflow execution.
func NewExprEvaluator ¶
func NewExprEvaluator(ctx *ExecutionContext) *ExprEvaluator
NewExprEvaluator creates a new expression evaluator.
func (*ExprEvaluator) EvaluateCondition ¶
func (e *ExprEvaluator) EvaluateCondition(condition string) (bool, error)
EvaluateCondition evaluates a boolean condition expression.
func (*ExprEvaluator) EvaluateExpression ¶
func (e *ExprEvaluator) EvaluateExpression(expression string) (interface{}, error)
EvaluateExpression evaluates an expression and returns the result.
func (*ExprEvaluator) InterpolateMap ¶
func (e *ExprEvaluator) InterpolateMap(m map[string]interface{}) (map[string]interface{}, error)
InterpolateMap interpolates all string values in a map.
func (*ExprEvaluator) InterpolateString ¶
func (e *ExprEvaluator) InterpolateString(template string) (string, error)
InterpolateString interpolates template strings like "{flags.name}" with actual values.
func (*ExprEvaluator) InterpolateStringMap ¶
InterpolateStringMap interpolates all values in a string map.
type LoopStep ¶
type LoopStep struct {
Iterator string `json:"iterator"`
Collection string `json:"collection"`
Steps []*Step `json:"steps"`
}
LoopStep defines an iteration step.
type ParallelStep ¶
type ParallelStep struct {
Steps []*Step `json:"steps"`
}
ParallelStep defines concurrent execution of multiple steps.
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
Parser parses workflow definitions and builds execution graphs.
func (*Parser) GetExecutionOrder ¶
GetExecutionOrder returns steps in the order they should be executed. Steps at the same level can be executed in parallel.
type PluginStep ¶
type PluginStep struct {
Plugin string `json:"plugin"`
Command string `json:"command"`
Input map[string]interface{} `json:"input,omitempty"`
}
PluginStep defines a plugin execution step.
type PollingConfig ¶
type PollingConfig struct {
Endpoint string `json:"endpoint"`
Interval int `json:"interval"` // seconds
Timeout int `json:"timeout"` // seconds
TerminalStates []string `json:"terminal-states,omitempty"`
StatusField string `json:"status-field,omitempty"`
}
PollingConfig defines polling behavior.
type RetryConfig ¶
type RetryConfig struct {
MaxAttempts int `json:"max-attempts,omitempty"`
Backoff *BackoffConfig `json:"backoff,omitempty"`
RetryableErrors []*ErrorMatch `json:"retryable-errors,omitempty"`
}
RetryConfig defines retry behavior for a step.
type RollbackAction ¶
type RollbackAction struct {
StepID string
Action *Step
Result *StepResult
}
RollbackAction represents a rollback action for a step.
type RollbackManager ¶
type RollbackManager struct {
// contains filtered or unexported fields
}
RollbackManager manages rollback execution.
func NewRollbackManager ¶
func NewRollbackManager() *RollbackManager
NewRollbackManager creates a new rollback manager.
func (*RollbackManager) ExecuteRollback ¶
func (rm *RollbackManager) ExecuteRollback(ctx *ExecutionContext, executor *StepExecutor) error
ExecuteRollback executes rollback actions in reverse order.
func (*RollbackManager) ExecuteRollbackWithStatus ¶
func (rm *RollbackManager) ExecuteRollbackWithStatus(ctx *ExecutionContext, executor *StepExecutor) (*RollbackStatus, error)
ExecuteRollbackWithStatus executes rollback and returns detailed status.
func (*RollbackManager) SetContinueOnError ¶
func (rm *RollbackManager) SetContinueOnError(continueOnError bool)
SetContinueOnError sets whether to continue rollback on errors.
type RollbackStatus ¶
type RollbackStatus struct {
TotalActions int
ExecutedActions int
SuccessfulActions int
FailedActions int
Errors []error
}
RollbackStatus represents the status of a rollback operation.
type Settings ¶
type Settings struct {
ParallelExecution bool `json:"parallel-execution,omitempty"`
FailFast bool `json:"fail-fast,omitempty"`
Timeout int `json:"timeout,omitempty"` // seconds
DryRunSupported bool `json:"dry-run-supported,omitempty"`
}
Settings contains workflow-level configuration.
type StateManager ¶
type StateManager struct {
// contains filtered or unexported fields
}
StateManager manages workflow execution state persistence.
func NewStateManager ¶
func NewStateManager() *StateManager
NewStateManager creates a new state manager.
func NewStateManagerWithDir ¶
func NewStateManagerWithDir(dir string) *StateManager
NewStateManagerWithDir creates a new state manager with a custom directory.
func (*StateManager) CleanupOldStates ¶
func (sm *StateManager) CleanupOldStates(maxAge int) error
CleanupOldStates removes states older than the specified duration.
func (*StateManager) DeleteState ¶
func (sm *StateManager) DeleteState(workflowID string) error
DeleteState deletes a saved workflow state.
func (*StateManager) GetStateFilePath ¶
func (sm *StateManager) GetStateFilePath(workflowID string) string
GetStateFilePath returns the path to a state file.
func (*StateManager) ListStates ¶
func (sm *StateManager) ListStates() ([]*ExecutionState, error)
ListStates lists all saved workflow states.
func (*StateManager) LoadState ¶
func (sm *StateManager) LoadState(workflowID string) (*ExecutionState, error)
LoadState loads workflow execution state from disk.
func (*StateManager) SaveState ¶
func (sm *StateManager) SaveState(state *ExecutionState) error
SaveState saves workflow execution state to disk.
func (*StateManager) StateExists ¶
func (sm *StateManager) StateExists(workflowID string) bool
StateExists checks if a state file exists.
type Step ¶
type Step struct {
// Common fields
ID string `json:"id"`
Type StepType `json:"type"`
Description string `json:"description,omitempty"`
DependsOn []string `json:"depends-on,omitempty"`
Condition string `json:"condition,omitempty"`
Required bool `json:"required,omitempty"`
// Retry configuration
Retry *RetryConfig `json:"retry,omitempty"`
// Rollback action
Rollback *Step `json:"rollback,omitempty"`
// Output mapping
Output map[string]string `json:"output,omitempty"`
// Type-specific fields
APICall *APICallStep `json:"api-call,omitempty"`
Plugin *PluginStep `json:"plugin,omitempty"`
Conditional *ConditionalStep `json:"conditional,omitempty"`
Loop *LoopStep `json:"loop,omitempty"`
Wait *WaitStep `json:"wait,omitempty"`
Parallel *ParallelStep `json:"parallel,omitempty"`
}
Step represents a single workflow step.
type StepExecutor ¶
type StepExecutor struct {
// contains filtered or unexported fields
}
StepExecutor coordinates execution of all step types.
func NewStepExecutor ¶
func NewStepExecutor(httpClient *http.Client, pluginExecutor interface{}) *StepExecutor
NewStepExecutor creates a new step executor.
func (*StepExecutor) ExecuteStep ¶
func (e *StepExecutor) ExecuteStep(step *Step, ctx *ExecutionContext) (*StepResult, error)
ExecuteStep executes a single step with retry logic.
type StepResult ¶
type StepResult struct {
StepID string
Success bool
Output map[string]interface{}
Error error
Retries int
StartTime time.Time
EndTime time.Time
Duration time.Duration
}
StepResult represents the result of executing a step.
type StepType ¶
type StepType string
StepType defines the type of workflow step.
const ( // StepTypeAPICall represents an API call step. StepTypeAPICall StepType = "api-call" // StepTypePlugin represents a plugin execution step. StepTypePlugin StepType = "plugin" // StepTypeConditional represents a conditional execution step. StepTypeConditional StepType = "conditional" // StepTypeLoop represents a loop execution step. StepTypeLoop StepType = "loop" // StepTypeWait represents a wait/delay step. StepTypeWait StepType = "wait" // StepTypeParallel represents parallel execution of sub-steps. StepTypeParallel StepType = "parallel" // StepTypeNoop represents a no-operation step. StepTypeNoop StepType = "noop" )
type WaitStep ¶
type WaitStep struct {
Condition string `json:"condition,omitempty"`
Duration int `json:"duration,omitempty"` // seconds
Polling *PollingConfig `json:"polling,omitempty"`
}
WaitStep defines a waiting/polling step.