Lightning.Workflows.Spec (Lightning v2.19.0-pre)

View Source

Lightning's hand-writable workflow format, and its translation into a provisioning document.

This is the same format the collaborative editor imports and exports (assets/js/yaml/util.ts) and that workflow templates are written in: jobs, triggers and edges are maps keyed by slug, and they reference each other by those keys rather than by id.

name: My Workflow
jobs:
  transform-data:
    name: Transform data
    adaptor: "@openfn/language-common@latest"
    body: fn(state => state);
triggers:
  webhook:
    type: webhook
    enabled: true
edges:
  webhook->transform-data:
    source_trigger: webhook
    target_job: transform-data
    condition_type: always
    enabled: true

to_document/2 resolves those key references into the id-based document Lightning.Projects.Provisioner consumes (jobs, triggers and edges as lists, wired together with source_job_id, source_trigger_id, target_job_id, ...).

It is the Elixir counterpart of convertWorkflowSpecToState in assets/js/yaml/util.ts and validates against the very same JSON Schema (assets/js/yaml/schema/workflow-spec.json, read at compile time), so a workflow that the editor accepts is a workflow this accepts, and vice versa.

Options

  • :id_fun - (kind, key -> uuid) used to mint ids for records that don't carry an explicit id, where kind is :workflow, :job, :trigger or :edge and key is the record's key in the spec (the workflow's name, for :workflow). Defaults to random UUIDs, like the editor does; callers that need idempotent re-runs (see Lightning.Kickstart) pass a deterministic function.

  • :credentials - %{credential_name => project_credential_id}, used to resolve a job's credential key into project_credential_id. Jobs referencing a credential that isn't in the map are an error.

Not covered

pos is accepted (it's part of the format, and the editor round-trips it) but not carried into the document: the provisioner has no way to set node positions.

Summary

Functions

Convert a workflow spec into a provisioning document.

Same as to_document/2, raising on an invalid spec.

Validate a spec against the workflow-spec JSON Schema (plus the duplicate job name check the editor also applies).

Types

id_fun()

@type id_fun() :: (kind(), String.t() | nil -> Ecto.UUID.t())

kind()

@type kind() :: :workflow | :job | :trigger | :edge

spec()

@type spec() :: %{required(String.t()) => any()}

Functions

to_document(spec, opts \\ [])

@spec to_document(
  spec(),
  keyword()
) :: {:ok, map()} | {:error, String.t()}

Convert a workflow spec into a provisioning document.

See the module docs for the available options.

to_document!(spec, opts \\ [])

@spec to_document!(
  spec(),
  keyword()
) :: map()

Same as to_document/2, raising on an invalid spec.

validate(spec)

@spec validate(spec()) :: :ok | {:error, String.t()}

Validate a spec against the workflow-spec JSON Schema (plus the duplicate job name check the editor also applies).