Show HN: Local automation runner with built-in LLM steps – YAML pipelines

rorlikowski1 pts0 comments

Stepyard

Skip to content

Initializing search

rorlikowski/stepyard

Documentation overview

Compatibility

Getting Started

Core Concepts

How-to Guides

Built-in Nodes

Plugin Development

CLI Reference

Examples

Documentation overview

Compatibility

Stepyard¶

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

Stepyard is an automation runner for developers. Pipelines live as YAML files in your repo. You extend them with plain Python functions. Everything runs from the CLI or a local daemon - on your machine or a server you own.

pip install stepyard<br>stepyard init my-project && cd my-project<br>stepyard run hello

A deploy pipeline: build and push a container, run a smoke test, and post the result to Slack. One YAML file, no supporting scripts.

flows/deploy.yamlname: deploy<br>description: Build, push, and verify the production container.

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

- id: push<br>uses: shell.run<br>with:<br>command: docker push myapp:${{ env.GIT_SHA }}

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

- id: notify<br>uses: llm.generate # built-in - no plugin needed<br>with:<br>model: gpt-4o-mini<br>prompt: |<br>Summarise this deploy result in one sentence for Slack:<br>HTTP status: ${{ steps.smoke_test.output.status }}<br>SHA: ${{ env.GIT_SHA }}

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

Run it:

GIT_SHA=$(git rev-parse --short HEAD) stepyard run deploy

✓ build 12.4 s<br>✓ push 4.1 s<br>✓ smoke_test 0.3 s<br>✓ notify 0.9 s<br>✓ post_to_slack 0.2 s

Flow completed in 18.0 s

Why Stepyard?&para;

Flows are files in your repo

Steps, conditions, loops, and retries are plain YAML keys - no proprietary DSL. Version-control them alongside your code and validate them with stepyard validate.

Extend with plain Python

One @node decorator turns any function into a reusable step. Inputs are type-validated automatically; plugin dependencies are isolated so they never conflict with Stepyard's own.

Nothing leaves your machine

State is stored in a local SQLite database. Data goes out only if a step in your flow explicitly sends it.

Scheduled and on-demand execution

cron, interval, and startup triggers. Run stepyard service start and your flows execute on schedule - no external service or cloud account needed.

Real-world examples&para;

Daily database backup&para;

flows/pg_backup.yamlname: pg_backup<br>trigger:<br>uses: cron<br>with:<br>schedule: "0 3 * * *" # every day at 03:00

steps:<br>- id: dump<br>uses: shell.run<br>with:<br>command: pg_dump ${{ env.DATABASE_URL }} | gzip > /tmp/backup.sql.gz

- id: upload<br>uses: shell.run<br>with:<br>command: |<br>aws s3 cp /tmp/backup.sql.gz \<br>s3://${{ env.BACKUP_BUCKET }}/db/$(date +%Y-%m-%d).sql.gz

- id: cleanup<br>uses: shell.run<br>with:<br>command: rm -f /tmp/backup.sql.gz

Automated code review on every PR&para;

Fetch the diff via the GitHub API, review it with an LLM, and post a comment back - all with built-in nodes, no additional service.

flows/pr_review.yamlname: pr_review<br>description: Review a PR diff with an LLM and post a comment if issues are found.<br># Run: PR=42 GITHUB_REPO=my-org/my-repo stepyard run pr_review

steps:<br>- id: diff<br>uses: http.request<br>with:<br>url: https://api.github.com/repos/${{ env.GITHUB_REPO }}/pulls/${{ env.PR }}/files<br>headers:<br>Authorization: Bearer ${{ env.GITHUB_TOKEN }}<br>Accept: application/vnd.github+json

- id: review<br>uses: llm.generate<br>with:<br>model: gpt-4o<br>system_prompt: |<br>You are a senior engineer doing a code review.<br>Be concise. If everything looks good reply with exactly: LGTM<br>prompt: |<br>Review this pull request for bugs, security issues, and obvious mistakes:

${{ steps.diff.output.body }}

- id: post_comment<br>if: ${{ steps.review.output.output != "LGTM" }}<br>uses: http.request<br>with:<br>url: https://api.github.com/repos/${{ env.GITHUB_REPO }}/issues/${{ env.PR }}/comments<br>method: POST<br>headers:<br>Authorization: Bearer ${{ env.GITHUB_TOKEN }}<br>Accept: application/vnd.github+json<br>json_body:<br>body: ${{ steps.review.output.output }}

Multi-environment deployment with rollback&para;

flows/deploy_multi.yamlname: deploy_multi

steps:<br>- id: deploy_staging<br>uses: shell.run<br>with:<br>command: kubectl apply -f k8s/staging/

- id: integration_tests<br>uses: shell.run<br>continue_on_error: true<br>with:<br>command: pytest tests/integration/ -q

- id: deploy_production<br>if: ${{ steps.integration_tests.output.code == 0 }}<br>uses: shell.run<br>with:<br>command: kubectl apply -f k8s/production/

- id: rollback<br>if: ${{ steps.integration_tests.output.code != 0 }}<br>uses: shell.run<br>with:<br>command: kubectl rollout undo deployment/myapp -n staging

Documentation overview&para;

Section<br>What you'll find

Getting Started<br>Installation and two full tutorials

Core Concepts<br>Flows, expressions, control flow, triggers, error handling

How-to Guides<br>Practical recipes - scheduling, secrets, approvals, debugging

Built-in...

uses steps stepyard output shell command

Related Articles