GitHub & CI/CD
GitHub environments, workflows, and Conductor workspace automation
Overview
When you select GitHub during scaffolding, your project ships with a complete CI/CD pipeline:
- 3 GitHub Environments — development, preview, production
- 5 Workflows — CI, deploy, production deploy, database migrations, PR cleanup
- Conductor scripts — automated workspace creation per feature branch
GitHub Environments
The deploy wizard creates three environments:
| Environment | Branch | Auto-deploy | Protection |
|---|---|---|---|
development | development | Yes | None |
preview | preview | Yes | None |
production | main | Manual only | 2 reviewer approvals |
Each environment has its own set of secrets and variables, provisioned by the deploy wizard or manually via:
scripts/env/provision-github-env.sh development
scripts/env/provision-github-env.sh previewWorkflows
ci.yml — Pull Request Quality Gates
Triggers on PRs to development. Runs:
- Biome linting
- TypeScript typecheck
- Vitest unit tests
- Full build verification
All must pass before merge.
deploy-environment.yml — Dev & Preview Auto-Deploy
Triggers on push to development or preview. Deploys all services in order:
- Migrate databases (Drizzle schema push)
- Push secrets to workers
- Deploy Auth (others depend on it)
- Deploy API + Metering (parallel)
- Deploy Mastra (build, patch, Studio assets)
- Deploy Web (Service Binding to Mastra)
- Smoke tests (health checks on all services)
deploy-prd.yml — Manual Production Deploy
Triggered manually with inputs:
- version — git tag or commit SHA
- run_migrations — whether to run DB migrations
- confirm_deploy — must type "DEPLOY" to proceed
Requires 2 reviewer approvals via the production GitHub Environment.
db-migrate.yml — Standalone Database Migrations
For running Drizzle migrations outside of a deploy. Supports dry-run mode.
pr-cleanup.yml — Feature Branch Cleanup
Triggers when a PR to development is closed. Deletes:
- Cloudflare Workers created by Conductor for that branch
- Turso database branches
Secrets & Variables
Secrets (sensitive, stored encrypted)
Pushed via gh secret set --env <environment>:
- Database URLs and tokens (AUTH, API, MASTRA, METERING)
BETTER_AUTH_SECRET,SESSION_SECRETSTRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRETGOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRETANTHROPIC_API_KEY/OPENAI_API_KEYCF_API_TOKENRESEND_API_KEYTWILIO_ACCOUNT_SID,TWILIO_AUTH_TOKEN,TWILIO_PHONE_NUMBERLANGFUSE_PUBLIC_KEY,LANGFUSE_SECRET_KEY,LANGFUSE_BASE_URL
Note: GitHub reserves the GITHUB_* prefix. GitHub OAuth credentials are stored as OAUTH_GITHUB_CLIENT_ID and OAUTH_GITHUB_CLIENT_SECRET.
Variables (non-sensitive, visible in logs)
Pushed via gh variable set --env <environment>:
CF_ACCOUNT_ID,CF_GATEWAY_IDSTRIPE_PUBLISHABLE_KEYSTRIPE_PRO_PRICE_ID,STRIPE_ENTERPRISE_PRICE_IDTRIAL_DAYS_PRO,TRIAL_DAYS_ENTERPRISEGOOGLE_PLACES_API_KEY
Conductor Workspace Automation
Conductor automates per-branch deployments. When you create a feature branch:
Setup (scripts/conductor/setup.sh)
- Derives a slug from the branch name (e.g.,
feat/MAK-33-settingsbecomesfeat-mak-33-settings) - Branches Turso databases from development (each feature gets isolated data)
- Saves database URLs and tokens for the deploy step
- Updates Linear issue to "In Progress" (if
LINEAR_API_KEYis set)
Deploy (scripts/conductor/deploy.sh)
- On first deploy: pushes all secrets to the new workers
- Deploys services in dependency order (Auth first, then API/Metering, then Mastra/Web)
- On subsequent deploys: only redeploys changed services (incremental)
- Creates a per-workspace Stripe webhook
Services are available at: https://{service}-{slug}.mastrakit.dev
Archive (scripts/conductor/archive.sh)
On workspace deletion:
- Deletes Stripe webhook
- Deletes all Cloudflare Workers
- Deletes Turso database branches
- Updates Linear issue to "Done"
Branch Strategy
feature/* ──PR──> development ──merge──> preview ──merge──> main
│ │ │
auto-deploy auto-deploy manual deploy
dev-*.domain preview-*.domain *.domainFeature branches deploy via Conductor. development and preview auto-deploy via GitHub Actions. main (production) requires manual trigger with approval.
Environment File Management
The scripts/env/ directory contains:
| File | Purpose |
|---|---|
.env.dev-secrets.example | Template with all keys (empty values) |
.env.dev-secrets | Your actual secrets (gitignored, populated by deploy wizard) |
.env.preview-secrets.example | Template for preview environment |
.env.preview-secrets | Preview secrets (gitignored) |
setup-dev-secrets.sh | Push secrets to per-developer Cloudflare Workers |
setup-preview-secrets.sh | Push secrets to preview Workers |
provision-github-env.sh | Push secrets to GitHub Environments |
Provisioning Flow
.env.dev-secrets (local file)
│
├── setup-dev-secrets.sh ──> Cloudflare Workers (per developer)
│
└── provision-github-env.sh ──> GitHub Environment secrets/variables
│
└── deploy-environment.yml ──> Workers (CI/CD)