@hyperfrontend/versioning/flow/executor

executor

Flow execution engine: runs a VersionFlow end-to-end with dry-run, validation, and structured result reporting.

executeFlow walks the steps of a flow in declared order, invoking each step's executor with the current FlowContext, threading state through FlowStepResult[], and short-circuiting on the first failed step (or on the first step whose skipIf opts out). dryRun performs the same traversal but instructs each step to report what it would do without performing side effects. This is useful for validating release plans before publishing. validateFlow walks the flow definition only (not the runtime context) and surfaces structural problems such as duplicate step IDs, missing dependencies, or invalid configuration.

API Reference§

ƒ Functions

§function

dryRun(flow: VersionFlow, projectName: string, workspaceRoot: string, options: Omit<ExecuteOptions, "dryRun">): Promise<FlowResult>

Executes a flow in dry-run mode.
Convenience wrapper that sets dryRun: true.
Parameters
NameTypeDescription
§flow
VersionFlowThe version flow to execute
§projectName
stringName of the project to version
§workspaceRoot
stringAbsolute path to workspace root
§options
Omit<ExecuteOptions, "dryRun">Execution options (dryRun forced to true)(default: {})
Returns
Promise<FlowResult>
Flow execution result (no actual changes made)
Example

Previewing version changes without modifying files

import { dryRun, createConventionalFlow } from '@hyperfrontend/versioning'

const flow = createConventionalFlow()
const result = await dryRun(flow, 'my-lib', '/workspace')

// Preview what would happen
console.log('Would bump to:', result.state.nextVersion)
// No files modified, no git operations performed
§function

executeFlow(flow: VersionFlow, projectName: string, workspaceRoot: string, options: ExecuteOptions): Promise<FlowResult>

Executes a version flow.
This is the main entry point for running a versioning workflow. Steps are executed in order, with state accumulated between steps.
Parameters
NameTypeDescription
§flow
VersionFlowThe version flow to execute
§projectName
stringName of the project to version (e.g., 'lib-versioning')
§workspaceRoot
stringAbsolute path to workspace root
§options
ExecuteOptionsExecution options(default: {})
Returns
Promise<FlowResult>
Flow execution result
Example

Executing a conventional version flow

import { createConventionalFlow, executeFlow } from '@hyperfrontend/versioning'

const flow = createConventionalFlow({ dryRun: true })
const result = await executeFlow(flow, 'lib-utils', '/path/to/workspace')

console.log(result.summary)
// "Flow success in 234ms: 8 completed, 0 skipped, 0 failed. Version: 1.2.3 → 1.3.0"
§function

validateFlow(flow: VersionFlow): unknown

Validates a flow before execution.
Checks for:
  • Duplicate step IDs
  • Invalid dependency references
  • Circular dependencies
Parameters
NameTypeDescription
§flow
VersionFlowThe flow to validate
Returns
unknown
Array of validation errors (empty if valid)
Example

Validating a flow before execution

import { validateFlow, createConventionalFlow } from '@hyperfrontend/versioning'

const flow = createConventionalFlow()
const errors = validateFlow(flow)

if (errors.length > 0) {
  console.error('Invalid flow:', errors)
}
// => []

◈ Interfaces

§interface

ExecuteOptions

Options for flow execution.
Properties
§dryRun?:booleanDry run - don't commit changes to disk
§verbose?:booleanVerbose logging
§showDiff?:booleanShow unified diff of changes before committing
§diffFormat?:DiffFormatOutput format for diff: 'unified' (full patch) or 'summary' (stats only)
§rollbackOnFailure?:booleanWhether to rollback all pending changes on step failure.
When true (default), pending VFS changes are discarded when a step fails and continueOnError is false. This ensures no partial state remains.
§logger?:LoggerCustom logger (defaults to console)
§tree?:TreeCustom Tree instance (for testing)
§registry?:RegistryCustom Registry instance (for testing)
§git?:GitClientCustom GitClient instance (for testing)
§projectRoot?:stringProject root path (relative to workspace root, e.g., 'libs/utils/immutable-api'). If provided, this is used directly instead of deriving from project name. This is the recommended approach when calling from the Nx executor.