Skip to content

Seed demo database (manual trigger) #4

Seed demo database (manual trigger)

Seed demo database (manual trigger) #4

name: Seed demo database (manual trigger)
# One-click way to apply pending Prisma migrations + run the demo seed
# against a Neon DB without anyone touching a terminal.
#
# Usage:
# 1. Set repo secret PRODUCTION_DATABASE_URL (and/or PREVIEW_DATABASE_URL)
# to the Neon connection string for that environment. Settings →
# Secrets and variables → Actions → New repository secret.
# 2. Trigger from Actions tab → "Seed demo database (manual trigger)" →
# "Run workflow" → pick the target environment.
#
# The workflow runs `prisma migrate deploy` (additive, idempotent) then
# `DEMO_MODE=true npx prisma db seed`. The DEMO_MODE flag is critical:
# without it, the seed dispatcher (prisma/seed.ts) defaults to the
# production-minimal path that creates zero demo data. With it, the
# dispatcher routes to prisma/seed-demo.ts to create the full demo
# dataset. It is intended to be safe to re-run when demo data needs
# refreshing, but the seed's idempotency depends on the unique keys
# used by each upsert (for example, some records may be matched by
# email rather than strictly by `demo-*` IDs).
#
# Hard rule: this workflow only writes to a Neon DB whose connection
# string is in a repo secret. There is no way for a malicious PR to
# trigger a production seed — workflow_dispatch + secrets are
# manually-gated by GitHub.
on:
workflow_dispatch:
inputs:
target:
description: "Which Neon DB to seed (uses the matching repo secret)"
required: true
default: production
type: choice
options:
- production
- preview
jobs:
migrate-and-seed:
runs-on: ubuntu-latest
concurrency:
group: seed-demo-database-${{ inputs.target }}
cancel-in-progress: false
timeout-minutes: 15
steps:
- name: Check out repo
uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Generate Prisma client
run: npx prisma generate
- name: Pick database URL
id: pick-url
env:
PRODUCTION_DATABASE_URL: ${{ secrets.PRODUCTION_DATABASE_URL }}
PREVIEW_DATABASE_URL: ${{ secrets.PREVIEW_DATABASE_URL }}
TARGET: ${{ inputs.target }}
run: |
if [ "$TARGET" = "production" ]; then
URL="$PRODUCTION_DATABASE_URL"
else
URL="$PREVIEW_DATABASE_URL"
fi
if [ -z "$URL" ]; then
echo "::error::No DATABASE_URL secret set for target '$TARGET'."
echo "::error::Add a repo secret named ${TARGET^^}_DATABASE_URL"
echo "::error::(Settings → Secrets and variables → Actions → New repository secret)."
exit 1
fi
# Mask in logs even though the secret machinery should already do this.
echo "::add-mask::$URL"
echo "DATABASE_URL=$URL" >> "$GITHUB_ENV"
- name: Apply pending migrations
run: |
echo "Applying any pending migrations to the ${{ inputs.target }} DB…"
npx prisma migrate deploy
- name: Seed demo data
# `npx prisma db seed` runs `prisma/seed.ts` (per package.json's
# `prisma.seed` field), which is a DISPATCHER:
# - default → production minimal seed (no demo fixture data)
# - DEMO_MODE=true → routes to prisma/seed-demo.ts (Marie,
# Bella, the personas, customers, yards, horses, invoices,
# and other sample/demo fixtures)
# Without DEMO_MODE=true this workflow created zero sample data
# and the demo URL was a clean dashboard. Set it explicitly here.
env:
DEMO_MODE: "true"
run: |
echo "Seeding demo fixtures (Marie, Bella, the 5 personas, etc.) via DEMO_MODE=true…"
npx prisma db seed
- name: Summary
run: |
{
echo "## Demo seed complete"
echo ""
echo "- **Target:** ${{ inputs.target }}"
echo "- **Migrations:** \`prisma migrate deploy\` ✓"
echo "- **Seed:** \`prisma db seed\` ✓"
echo ""
echo "If the demo URL still won't sign in, check that the matching"
echo "Vercel environment has \`AUTH_SECRET\`, \`AUTH_URL\`, and"
echo "\`DEMO_MODE=true\` set, then redeploy."
} >> "$GITHUB_STEP_SUMMARY"