satus in one composite action.
passkeybridge/satus-action@v1 runs satus generate inside a GitHub Actions workflow and uploads the run manifest as a workflow artifact. It is a composite action, not a Docker container — three shell steps that install Node, call npx @passkeybridge/satus@0.3.3, and upload the result. No container startup cost, no root filesystem writes.
The action is a wrapper. If a run works on your laptop it works here, with the same flags, the same exit codes, the same three guarantees.
drop it into your PR workflow.
The intended shape for a preview-database workflow:
name: Seed preview database
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
seed:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: passkeybridge/satus-action@v1
with:
database-url: ${{ secrets.PREVIEW_DATABASE_URL }}
rows: 250
profile: saas
max-cost: '0.50'
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
Swap OPENAI_API_KEY for ANTHROPIC_API_KEY and add provider: anthropic under with: to drive Anthropic instead. The CLI auto-detects from whichever env key is present.
every knob, defaulted.
| name | required | default | description |
|---|---|---|---|
| database-url | yes | — | Postgres connection string. Pass as a secret. |
| rows | no | 50 | Rows per table. Free tier caps at 25. |
| profile | no | saas | Reference profile: saas | ecommerce | b2b. |
| provider | no | auto | openai | anthropic. Auto-detected from env. |
| model | no | provider default | Model id override. |
| max-cost | no | '1.00' | USD ceiling. Quote it so YAML keeps a string. |
| dry-run | no | false | Validate without inserting or spending. |
| working-directory | no | . | Where satus.config.json lives. |
| satus-version | no | 0.3.3 | npm version to install. Pin for reproducibility. |
parsed from the JSON manifest.
All outputs are parsed from the --json payload the CLI writes to stdout. They are also uploaded verbatim as the satus-run-manifest workflow artifact so a downstream job can read the full record.
| name | description |
|---|---|
| run-id | Server-side run UUID. |
| tables-seeded | Number of tables the run touched. |
| rows-inserted | Total rows inserted (0 on dry-run). |
| tokens-in | Total input tokens across the run. |
| tokens-out | Total output tokens across the run. |
| spent-usd | Actual LLM spend in USD. |
three deliberate choices.
database-urlis an input, not an env var. GitHub redacts inputs in logs the same way it redacts env vars, but making it an input surfaces it in the Marketplace UI as a required field so a caller cannot leave it empty by accident.max-costis a string. YAML parses0.5as a float and the CLI expects a string so it can normalise the format itself. Quote it in your workflow.- The provider key stays in
env:, notwith:. The action never touches your provider key. That keeps it off the action's public input schema and out of anything a compromised action version could exfiltrate through inputs.
Pin the action to a full commit SHA if you want defence in depth against a compromised release tag, and pin satus-version to a specific npm version for reproducibility. Both are documented in the GitHub security-hardening guide.
four things the action does not do.
- No hosted-key tier. Bring your own OpenAI or Anthropic key. A managed-key mode is on the roadmap for a later release, not this one.
- No auto-commit of generated data. The action does not open a follow-up PR with a SQL dump. Seed data belongs in the ephemeral preview database, not in git history.
- No cache of previously-generated rows. Every invocation regenerates. The correctness problem for a cache key (schema hash + profile hash + provider version) is not worth solving for a first release.
- No GitLab CI, no CircleCI, no Buildkite variant. The CLI runs anywhere Node runs. This action is a convenience layer for GitHub, not a portability layer.
Reference for passkeybridge/satus-action@v1. If anything here drifts from action.yml, action.yml wins — file an issue.