Add SignStack to Your CI/CD Pipeline
Because your blueprints, templates, schemas, assets, and functions live as YAML in your repo, they fit naturally into the same CI/CD pipeline as the rest of your code: validate on PR, push to a staging namespace on merge, push to live on release. This guide shows the canonical setup with GitHub Actions.
The CLI operates per resource, not per folder. signstack validate blueprint@1.0.0 walks the blueprint and every primitive it depends on (templates, assets, schemas, functions); same for push and preview. If your repo has multiple blueprints, run the command once per blueprint.
What You're Wiring Up
| Stage | Trigger | What runs |
|---|---|---|
| Validate | Pull request opened/updated | signstack validate <blueprint>@<version> — validates the blueprint and every dependency (recursively) |
| Push to staging | Merge to main |
signstack push <blueprint>@<version> — pushes the blueprint and every dependency (recursively) to your test namespace |
| Smoke test | After staging push | signstack run <blueprint>@<version> --scenario smoke_test |
| Push to live | Release tag / manual gate | signstack push <blueprint>@<version> — same recursive push against your live namespace |
Prerequisites
- SignStack CLI installed in CI (Node 18+, then
npm install -g signstack). - Two namespaces: a
test-mode one for staging (the defaultdefault-testis fine) and alive-mode one for production. - Two API keys, one per namespace, stored as GitHub Secrets:
SIGNSTACK_TEST_API_KEYSIGNSTACK_LIVE_API_KEY
Validate on Pull Request
.github/workflows/signstack-validate.yml:
name: Validate SignStack primitives
on:
pull_request:
paths:
- 'agreements/**'
- '.github/workflows/signstack-validate.yml'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm install -g signstack
- run: signstack auth login --api-key "${{ secrets.SIGNSTACK_TEST_API_KEY }}"
- run: signstack validate consulting_agreement@1.0.0 -d ./agreements
signstack validate checks YAML structure, schema references, dependency graph, and JSONata expressions for the given blueprint and everything it depends on. Anything broken fails the PR before review. For multiple blueprints, call signstack validate once per blueprint.
Push to Staging on Merge to Main
.github/workflows/signstack-push-staging.yml:
name: Push primitives to staging
on:
push:
branches: [main]
paths:
- 'agreements/**'
jobs:
push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm install -g signstack
- run: signstack auth login --api-key "${{ secrets.SIGNSTACK_TEST_API_KEY }}"
- run: signstack push consulting_agreement@1.0.0 -d ./agreements
- name: Smoke test
run: signstack run consulting_agreement@1.0.0 --scenario smoke_test
The push step walks the blueprint's dependency graph, uploads any changed binary assets, creates new versions of changed primitives, and leaves unchanged primitives alone. The smoke test runs an actual workflow against a known scenario — if the blueprint can't render and orchestrate, the deploy fails loud.
Promote to Live
Hold live promotion behind an explicit gate — usually a release tag or a manual approval. Two patterns:
Pattern A: tag-driven
on:
push:
tags: ['v*']
jobs:
push-live:
runs-on: ubuntu-latest
environment: production # GitHub environment with required reviewers
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm install -g signstack
- run: signstack auth login --api-key "${{ secrets.SIGNSTACK_LIVE_API_KEY }}"
- run: signstack push consulting_agreement@1.0.0 -d ./agreements
Pattern B: manual dispatch — replace the on: block with workflow_dispatch: so a human pushes the button when ready.
Either way, push goes to your live namespace's API key. Because every primitive version is immutable, "promoting" is just publishing the same key+version into the live namespace — what runs in staging is byte-identical to what runs in live.
Tips
- Scope
paths:so the workflow only runs when YAML inagreements/changes — saves CI minutes. - Cache the global npm install of
signstackif push frequency is high. - Use
signstack push --dry-runin PR jobs to see what would change without touching the namespace. - Use distinct namespaces per environment — never share the same namespace between staging and live.
Related
- Quick Start — The CLI commands this guide automates
- Namespaces — Why test/live mode separation matters here
- Scenarios — How smoke-test data is structured
