Seedfast

Seedfast

CI/CD Database Seeding

  • Use SEEDFAST_API_KEY environment variable for non-interactive CI/CD authentication
  • The --scope flag accepts natural language descriptions of what to seed
  • --output json enables machine-readable output for pipeline validation
  • Always run database migrations before seeding
  • Create separate API keys per environment (dev, staging, production)

Most teams rely on one of these approaches β€” and each has drawbacks:

Static SQL dumps β€” contain real or semi-anonymized production data, drift from live schemas, require constant maintenance.

Custom seeding scripts β€” become unmaintainable code that breaks with every schema change.

Shared test databases β€” create race conditions and test pollution between concurrent runs.

There's also a deeper issue with any approach based on production data: even anonymized or masked records start from something real. That creates compliance exposure β€” there's always something that needs protecting, auditing, or GDPR-scoping.

Seedfast generates data from scratch on every run. Your production records are never involved:

  • No production data β€” data is synthesized from your schema on every pipeline run, nothing to anonymize or protect
  • Schema-adaptive β€” Seedfast reads your live schema; no script rewrites after migrations
  • Isolated per run β€” each pipeline job seeds its own database; no shared state, no race conditions

Make sure you have:

  • A Seedfast account (sign up at seedfa.st)
  • A PostgreSQL database accessible from your CI/CD environment
  • Access to configure secrets in your CI/CD platform

API keys authenticate the Seedfast CLI in non-interactive environments where browser-based login isn't possible.

  1. Log in and open the Seedfast Dashboard
  2. Click API Keys in the left sidebar
  3. Click Create new key and enter a name (e.g. "GitHub Actions")
  4. Copy the key immediately β€” it won't be shown again

Your API key format: sfk_live_a1b2c3d4e5f6...

Tip: Create separate keys for each environment (dev, staging, production). This enables independent rotation and revocation.

Store your API key and database credentials as encrypted secrets in your CI/CD platform.

GitHub Actions: Go to repository β†’ Settings β†’ Secrets and variables β†’ Actions β†’ New repository secret:

SEEDFAST_API_KEY=sfk_live_...
SEEDFAST_DSN=postgres://user:pass@host:5432/db

Note: Use SEEDFAST_DSN rather than DATABASE_URL. Many CI environments already set DATABASE_URL for other tools β€” using SEEDFAST_DSN avoids conflicts. The CLI checks SEEDFAST_DSN first, then falls back to DATABASE_URL.

GitLab CI: Go to project β†’ Settings β†’ CI/CD β†’ Variables. Mark as Masked and Protected.

CircleCI: Go to Project Settings β†’ Environment Variables.

The simplest way to run Seedfast in CI/CD is via npx:

npx seedfast seed --scope "Your scope description" --output json

The --scope flag describes what data to seed in plain English:

# Seed by schema
--scope "HR schema: employees, departments, payroll"

# Seed by use case
--scope "Customers and orders for checkout flow testing"

# Seed with specificity
--scope "Single user with 3 pending orders"

When --scope is provided, Seedfast automatically approves the seeding plan without prompting β€” enabling fully automated pipelines.

name: E2E Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:15
        env:
          POSTGRES_PASSWORD: testpass
        ports:
          - 5432:5432
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run db:migrate
      - name: Seed test data
        run: npx seedfast seed --scope "Users and orders for E2E tests" --output json
        env:
          SEEDFAST_API_KEY: ${{ secrets.SEEDFAST_API_KEY }}
          SEEDFAST_DSN: postgres://postgres:testpass@localhost:5432/postgres
      - run: npm run test:e2e
test:
  stage: test
  services:
    - postgres:15
  variables:
    POSTGRES_PASSWORD: testpass
    SEEDFAST_DSN: postgres://postgres:testpass@postgres:5432/postgres
  script:
    - npm ci
    - npm run db:migrate
    - npx seedfast seed --scope "Test dataset" --output plain
    - npm run test

The --output flag controls output format:

ModeUse case
interactiveColors and spinners (default, for local dev)
plainTimestamped logs (for CI log output)
jsonMachine-readable (for script validation)

Validate results with JSON output:

RESULT=$(npx seedfast seed --scope "..." --output json)

if [ "$(echo $RESULT | jq -r '.success')" != "true" ]; then
  echo "Seeding failed!"
  exit 1
fi

echo "Seeded $(echo $RESULT | jq -r '.rows') rows"
CodeMeaning
0Success
1Generic error
2Authentication failed (check API key)
3Database connection failed (check SEEDFAST_DSN)
4Quota exceeded
5Operation cancelled by user
  • Never commit API keys β€” use CI/CD secret management
  • Separate keys per environment β€” enable independent rotation
  • Rotate regularly β€” generate new key, update secrets, verify, revoke old key
  • Limit scope β€” expose the API key only to the seeding step:
# Key only in the seeding step, not globally
- name: Seed database
  run: npx seedfast seed --scope "..."
  env:
    SEEDFAST_API_KEY: ${{ secrets.SEEDFAST_API_KEY }}

"Authentication failed" in CI but works locally: Verify the secret name matches exactly. Check for leading/trailing whitespace. Ensure the API key hasn't been revoked.

"Connection refused" to database: Wait for database health check to pass. Use the correct hostname (localhost for GitHub Actions, postgres for GitLab CI). Check that the CI runner can reach the database port.

Seeding takes too long in pipeline: Narrow the scope to only the tables your tests need. A focused scope like "users and orders for checkout tests" is faster than "all tables."

CI/CD database seeding with Seedfast takes minutes to set up. Start with one test job, refine your scope, then expand to your full test suite. Try Seedfast β€” sign up and start seeding in minutes.