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 default default-test is fine) and a live-mode one for production.
  • Two API keys, one per namespace, stored as GitHub Secrets:
    • SIGNSTACK_TEST_API_KEY
    • SIGNSTACK_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 in agreements/ changes — saves CI minutes.
  • Cache the global npm install of signstack if push frequency is high.
  • Use signstack push --dry-run in 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.
  • Quick Start — The CLI commands this guide automates
  • Namespaces — Why test/live mode separation matters here
  • Scenarios — How smoke-test data is structured