Skip to main content

Ready-to-run automations with a Python escape hatch

Project description

Stepyard

Stepyard

YAML pipelines. Python plugins. Runs on your machine - no server to set up, no cloud account needed.

CI Coverage PyPI Python License: MIT Issues

Stepyard demo

pip install stepyard
stepyard init my-automations && cd my-automations
stepyard run hello

Quick example

Build a container, smoke-test it, summarise the result with an LLM, and post to Slack. One YAML file, no glue scripts.

name: deploy
description: Build the image, smoke-test it, and post an AI summary to Slack.

steps:
  - id: build
    uses: shell.run
    with:
      command: docker build -t myapp:${{ env.GIT_SHA }} .

  - id: smoke_test
    uses: http.request
    with:
      method: GET
      url: https://staging.myapp.com/healthz

  - id: summary
    uses: llm.generate            # built-in - reads OPENAI_API_KEY from the env
    with:
      model: gpt-4o-mini
      prompt: |
        Write a one-line Slack message about this deploy.
        Build exit code: ${{ steps.build.output.code }}
        Health check HTTP status: ${{ steps.smoke_test.output.status }}

  - id: notify
    uses: http.request
    with:
      method: POST
      url: ${{ env.SLACK_WEBHOOK }}
      json_body:
        text: ${{ steps.summary.output.output }}

Run it:

GIT_SHA=$(git rev-parse --short HEAD) stepyard run deploy
✓  build         12.4s
✓  smoke_test     0.3s
✓  summary        0.9s
✓  notify         0.2s

Flow completed in 13.8s

Reading step outputs. Each node has a documented output shape, referenced as ${{ steps.<id>.output... }}:

Node output shape
shell.run { stdout, stderr, code }
http.request { status, headers, body }
llm.generate { output, usage, model, provider } (use ${{ steps.<id>.output.output }} for text)

Full reference: docs/nodes/builtin.md.


Why Stepyard?

  • Flows are YAML files in your repo. Steps, conditions, loops, and retries are plain keys. Version-control them alongside your code; no proprietary DSL to learn.
  • Extend with plain Python. One @node decorator turns any function into a reusable step. Inputs are type-validated automatically; plugin dependencies run in an isolated virtualenv, so they never clash with Stepyard's own.
  • Nothing leaves your machine. State is stored in a local SQLite database. Data only goes out if a step in your flow explicitly sends it.
  • Every run is its own process. Each flow executes in a dedicated OS subprocess, so a crash, timeout, or sys.exit in one run cannot take down the scheduler or a sibling run. See Execution model.
  • Built-in scheduler, no hosted service. Add a trigger: block with cron, interval, or startup, run stepyard service start, and flows execute on schedule without a control plane.

Install

# from PyPI
pip install stepyard

# or, for development, with uv
git clone https://github.com/rorlikowski/stepyard && cd stepyard
uv pip install -e ".[dev,docs]"
uv run stepyard doctor      # verify the install

Requires Python 3.10+. Works on macOS, Linux, and Windows (WSL).


The 60-second tour

stepyard init my-automations   # scaffold flows/ + .gitignore + .stepyard/
cd my-automations

stepyard run hello             # run a flow now (in its own subprocess)
stepyard status               # see every flow and its latest run
stepyard show <run-id>        # drill into the steps of one run
stepyard logs <run-id>        # stream the captured logs
stepyard validate --all       # type-check your YAML without running it

Schedule it instead of running by hand - add a trigger and start the daemon:

name: nightly_backup
trigger:
  uses: cron
  with:
    schedule: "0 3 * * *"      # every day at 03:00

steps:
  - id: dump
    uses: shell.run
    with:
      command: pg_dump ${{ env.DATABASE_URL }} | gzip > /tmp/backup.sql.gz
stepyard service start          # run the scheduler in the background
stepyard service status

Execution model

Stepyard is deliberately process-isolated:

  1. stepyard run <flow> spawns a fresh subprocess (python -m stepyard.engine.runner) for that single run. Its stdout/stderr are captured to .stepyard/logs/.
  2. The scheduler daemon (stepyard service start) runs separately. It evaluates triggers, enqueues runs in SQLite, and a worker spawns one subprocess per run (bounded by STEPYARD_MAX_CONCURRENT_FLOWS, default 4).
  3. Inside a run, steps execute sequentially. Built-in nodes run in-process; plugin nodes installed into an isolated virtualenv run in a second short-lived subprocess that talks JSON over stdin/stdout - so a plugin's dependencies can never clash with Stepyard's own.

The practical upshot: one misbehaving flow or plugin cannot corrupt the scheduler or sibling runs.


Write your own step

# my_plugin/nodes.py
from stepyard.sdk import node, NodeResult, NodeStatus

@node(name="math.add")
def add(a: int, b: int) -> int:
    return a + b

@node(name="files.archive")
def archive(path: str) -> NodeResult:
    if not path:
        return NodeResult(status=NodeStatus.FAILED, error="path is required")
    # ... do the work ...
    return NodeResult(status=NodeStatus.SUCCESS, output={"archived": path})

Register it via an entry point and it becomes available as uses: math.add in every flow. See docs/plugins/creating.md.


Documentation

Section What's inside
Getting Started Install, quickstart, two tutorials
Core Concepts Flows, expressions, control flow, triggers, errors
How-to Guides Scheduling, secrets, approvals, debugging
Built-in Nodes Every node that ships with Stepyard
Plugin Development Write, test, and publish plugins
CLI Reference Every command and flag

The full documentation is published at rorlikowski.github.io/stepyard.

Browse the docs locally with uv run mkdocs serve.


License

MIT - see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

stepyard-0.1.2.tar.gz (1.5 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

stepyard-0.1.2-py3-none-any.whl (127.9 kB view details)

Uploaded Python 3

File details

Details for the file stepyard-0.1.2.tar.gz.

File metadata

  • Download URL: stepyard-0.1.2.tar.gz
  • Upload date:
  • Size: 1.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for stepyard-0.1.2.tar.gz
Algorithm Hash digest
SHA256 fae515974453efb4a460366047debef97fd8756e01538857d3d52c5af8888993
MD5 59e04c949178fe045b51e681324c76f5
BLAKE2b-256 fb8d007b6b6bcdaeffea3ab80553b22e7dac7dc11f972d60d6c63880539867c0

See more details on using hashes here.

Provenance

The following attestation bundles were made for stepyard-0.1.2.tar.gz:

Publisher: release.yml on rorlikowski/stepyard

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file stepyard-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: stepyard-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 127.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for stepyard-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 78788e741d89187ecc19bc2f0c7c1f81a336c2c5d3440d36ccc09fd8daf38d6c
MD5 2383acebee4677f17ad15027da53363c
BLAKE2b-256 a9098c9eed84f753e1299fe3eeba21b1e2a4bb1a1bcc8e7c317a78d98b9d7611

See more details on using hashes here.

Provenance

The following attestation bundles were made for stepyard-0.1.2-py3-none-any.whl:

Publisher: release.yml on rorlikowski/stepyard

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page