Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.ellomas.com/llms.txt

Use this file to discover all available pages before exploring further.

Writing Workflows

A Replay workflow is a YAML file that describes a sequence of steps to execute. Each step performs an action, optionally extracts values into the shared state bag, and asserts outcomes.

Anatomy of a Workflow

name: my-workflow                  # Required — workflow name
version: v0.1                      # Optional — DSL version (defaults to v0.1)
config:
  http:
    base_url: https://api.example.com
  vars:
    region: us-east-1              # Convenience variables
steps:
  - name: step-1                   # Required — unique step name
    type: http                     # Required — step type
    request:
      method: GET
      url: /health
    extract:
      status_code: $.status        # Extract value into state bag
    assert:
      - ["$.status", "eq", 200]    # Assert expected outcome
  - name: step-2
    type: shell
    command: "echo {{ status_code }}"

The State Bag

Every workflow has a shared state bag — a key-value store that lives across all steps. Values extracted in one step are available in all later steps via {{ variable_name }} syntax.
steps:
  - name: fetch-token
    type: http
    request:
      method: POST
      url: /auth/login
      body:
        email: test@example.com
    extract:
      token: $.data.token           # ← saved to state bag

  - name: use-token
    type: http
    request:
      method: GET
      url: /users/me
      headers:
        Authorization: Bearer {{ token }}  # ← reused here

Step Types

TypeDescription
httpExecute HTTP requests (GET, POST, PUT, DELETE)
dbRun PostgreSQL queries or Redis commands
shellExecute shell commands
printPrint formatted output to the terminal
loopIterate over an array and run nested steps
callImport and execute steps from another workflow file
ifConditionally execute steps based on an assertion

Extract

The extract block maps JSONPath expressions to variable names:
extract:
  user_id: $.data.id
  user_name: $.data.name
  first_tag: data.tags[0]
Extracted values are available in all subsequent steps.

Assert

The assert block validates outcomes. Each rule has a path, operator, and expected value:
assert:
  - ["$.status", "eq", 200]
  - ["$.data.email", "not_null"]
  - ["$.data.count", "gt", 0]
You can also use the object form:
assert:
  - path: $.status
    op: eq
    value: 200

Templates

Any string field in a step can reference state variables with {{ var }} syntax:
- name: dynamic
  type: http
  request:
    url: /users/{{ user_id }}
    headers:
      Authorization: Bearer {{ token }}
    body:
      message: "Hello {{ user_name }}"
You can also use built-in functions:
- name: transform
  type: print
  message: "{{ upper name }} — {{ lower email }}"

Ignoring Errors

Use ignore_error: true to continue execution even when a step fails:
- name: risky-step
  type: shell
  command: "might-fail"
  ignore_error: true

- name: still-runs
  type: print
  message: "This runs regardless"

Cleanup

The cleanup field deletes variables from the state bag after a step completes:
- name: temp-data
  type: shell
  command: 'echo "{\"temp\": \"secret\"}"'
  extract:
    temp_key: $.temp
  cleanup:
    - temp_key
This is useful for sensitive data that should not leak to later steps.

Variable Scope

Variables exist in a three-level scope hierarchy:
  1. Global — Environment variables loaded at startup
  2. Workflow — Set via config.vars or extract at the workflow level
  3. Step — Set via extract within a step, cleaned up when the step exits
Inner scopes inherit from outer scopes. A step can read global and workflow variables.

What’s Next?