Deploy Pipeline (Stripe / Supabase / Vercel)
Use This Skill When
- Full-stack product launch touching billing, database, and frontend
- Promoting a preview build to production with Stripe price updates and Supabase migrations
- Weekly release trains requiring repeatable, reliable deploy sequences
- Coordinating changes across multiple external services in strict order
- Need post-deploy verification and automated release announcements
When NOT to Use
- Single-service deployments (use Vercel/Stripe/Supabase UIs)
- Manual, one-off changes without automation
- Deployments requiring complex approval workflows
- Services not integrated via Composio (unsupported platforms)
Context: Pipeline Automation Maturity
Undeveloped: Manual steps across Stripe, Supabase, Vercel; no coordination; error-prone ordering.
Target: Composio CLI orchestration of Stripe → Supabase → Vercel in correct sequence with basic verification.
Optimized: Automated pipeline with rollback strategies, feature flags, comprehensive post-deploy checks, scheduled releases.
Core Principle
Order matters for full-stack releases. Stripe → Supabase → Vercel ensures billing changes precede database migrations, and migrations precede frontend deployment. One coordinated script prevents cascading failures.
Instructions
Step 1: Install and Link Services
Install Composio CLI:
curl -fsSL https://composio.dev/install | bash
composio login
Link all three services:
composio link stripe
composio link supabase
composio link vercel
composio link slack # For release announcements
Step 2: Discover and Verify Actions
Search available actions:
| Service | Discovery Command |
|---|---|
| Stripe | composio search "create price" --toolkits stripe |
| Supabase | composio search "apply migration" --toolkits supabase |
| Vercel | composio search "create deployment" --toolkits vercel |
Common action slugs:
STRIPE_CREATE_PRODUCT, STRIPE_CREATE_PRICE, STRIPE_UPDATE_PRODUCT
SUPABASE_LIST_PROJECTS, SUPABASE_RUN_SQL_QUERY, SUPABASE_APPLY_MIGRATION
VERCEL_CREATE_A_NEW_DEPLOYMENT, VERCEL_GET_A_DEPLOYMENT_BY_ID_OR_URL, VERCEL_PROMOTE_DEPLOYMENT
Verify schemas:
composio tools get-schema STRIPE_CREATE_PRICE
composio tools get-schema SUPABASE_APPLY_MIGRATION
composio tools get-schema VERCEL_CREATE_A_NEW_DEPLOYMENT
Step 3: Execute Stripe Actions (Pricing & Products)
Create new price:
composio execute STRIPE_CREATE_PRICE -d '{
"product": "prod_abc123",
"unit_amount": 2900,
"currency": "usd",
"recurring": { "interval": "month" },
"lookup_key": "team-plan-v2"
}'
Update product metadata:
composio execute STRIPE_UPDATE_PRODUCT -d '{
"id": "prod_abc123",
"name": "Team Plan v2",
"description": "Enhanced team collaboration features"
}'
List and verify prices:
composio execute STRIPE_LIST_PRICES -d '{
"product": "prod_abc123",
"limit": 10
}' | jq '.data[] | {id, lookup_key, unit_amount}'
Step 4: Execute Supabase Actions (Database Migrations)
Apply database migration:
composio execute SUPABASE_APPLY_MIGRATION -d '{
"project_id": "abcxyz",
"name": "add_team_tier_column",
"query": "ALTER TABLE teams ADD COLUMN tier TEXT DEFAULT '"'"'free'"'"';"
}'
Verify schema changes:
composio execute SUPABASE_RUN_SQL_QUERY -d '{
"project_id": "abcxyz",
"query": "SELECT column_name FROM information_schema.columns WHERE table_name='"'"'teams'"'"' AND column_name='"'"'tier'"'"';"
}'
Check for data issues:
composio execute SUPABASE_RUN_SQL_QUERY -d '{
"project_id": "abcxyz",
"query": "SELECT COUNT(*) FROM teams WHERE tier IS NULL;"
}'
Step 5: Execute Vercel Actions (Frontend Deployment)
Create production deployment:
composio execute VERCEL_CREATE_A_NEW_DEPLOYMENT -d '{
"name": "web",
"target": "production",
"gitSource": {
"type": "github",
"ref": "main",
"repoId": 123456
}
}'
Poll deployment status:
composio execute VERCEL_GET_A_DEPLOYMENT_BY_ID_OR_URL -d '{
"idOrUrl": "dpl_xxx"
}' | jq '.readyState'
Wait for ready state (shell loop):
DEPLOYMENT_ID="dpl_xxx"
while true; do
STATE=$(composio execute VERCEL_GET_A_DEPLOYMENT_BY_ID_OR_URL -d "{\"idOrUrl\":\"$DEPLOYMENT_ID\"}" | jq -r '.readyState')
[ "$STATE" = "READY" ] && break
[ "$STATE" = "ERROR" ] && exit 1
sleep 4
done
Step 6: Post-Deployment Verification
Health check:
curl -fsS https://app.acme.com/api/health || exit 1
Database verification:
composio execute SUPABASE_RUN_SQL_QUERY -d '{
"project_id": "abcxyz",
"query": "SELECT COUNT(*) as total, COUNT(CASE WHEN tier IS NOT NULL THEN 1 END) as migrated FROM teams;"
}'
Stripe verification:
composio execute STRIPE_LIST_PRICES -d '{
"product": "prod_abc123",
"active": true
}' | jq '.data[].lookup_key'
Step 7: Automate with Workflow File
Create scripts/ship.ts:
const ref = process.argv[process.argv.indexOf("--ref") + 1] ?? "main";
const channel = process.argv[process.argv.indexOf("--channel") + 1] ?? "releases";
try {
// Step 1: Stripe - Create price
const price = await execute("STRIPE_CREATE_PRICE", {
product: "prod_abc123",
unit_amount: 2900,
currency: "usd",
recurring: { interval: "month" },
lookup_key: "team-plan-v2"
});
console.log(`✓ Stripe price created: ${price.id}`);
// Step 2: Supabase - Apply migration
await execute("SUPABASE_APPLY_MIGRATION", {
project_id: "abcxyz",
name: "add_team_tier_column",
query: "ALTER TABLE teams ADD COLUMN tier TEXT DEFAULT 'free';"
});
console.log(`✓ Supabase migration applied`);
// Step 3: Vercel - Create deployment
const dep = await execute("VERCEL_CREATE_A_NEW_DEPLOYMENT", {
name: "web",
target: "production",
gitSource: { type: "github", ref, repoId: 123456 }
});
console.log(`✓ Vercel deployment created: ${dep.id}`);
// Step 4: Wait for Vercel ready
let state = "QUEUED";
let attempts = 0;
while (state !== "READY" && state !== "ERROR" && attempts < 60) {
await new Promise(r => setTimeout(r, 4000));
const d = await execute("VERCEL_GET_A_DEPLOYMENT_BY_ID_OR_URL", { idOrUrl: dep.id });
state = d.readyState;
attempts++;
}
if (state !== "READY") throw new Error(`Vercel deploy failed: ${state}`);
console.log(`✓ Vercel deployment ready`);
// Step 5: Announce
await execute("SLACK_SEND_MESSAGE", {
channel,
text: `✅ *Production Release* — Ref: \`${ref}\`\nStripe: ${price.id}\nVercel: ${dep.url}`
});
console.log(`✓ Release announced on #${channel}`);
} catch (error) {
console.error(`✗ Pipeline failed: ${error.message}`);
await execute("SLACK_SEND_MESSAGE", {
channel,
text: `❌ *Release Failed* — ${error.message}`
});
throw error;
}
Run the workflow:
composio run --file scripts/ship.ts -- --ref main --channel releases
Step 8: Rollback Strategy
If verification fails, undo in reverse order:
Vercel: Promote previous deployment
composio execute VERCEL_PROMOTE_DEPLOYMENT -d '{ "deploymentId": "dpl_previous" }'Supabase: Apply down migration
composio execute SUPABASE_APPLY_MIGRATION -d '{ "project_id": "abcxyz", "name": "rollback_add_team_tier_column", "query": "ALTER TABLE teams DROP COLUMN tier;" }'Stripe: Hide new price (don't delete)
composio execute STRIPE_UPDATE_PRODUCT -d '{ "id": "prod_abc123", "metadata": { "rollback": "true" } }'Announce rollback
composio execute SLACK_SEND_MESSAGE -d '{ "channel": "releases", "text": "⚠️ Release rolled back due to verification failure" }'
Troubleshooting
| Issue | Solution |
|---|---|
| Stripe price visible but old price in checkout | Cache issue on app side; verify lookup_key matches what checkout fetches |
| Supabase migration hangs | Another connection holds a lock; check: SELECT pid, state FROM pg_stat_activity WHERE state <> 'idle'; |
| Vercel deployment stuck in QUEUED | Check build logs; verify git ref exists and permissions are set |
| Frontend reads column before migration applies | Never parallelize; always serialize Stripe → Supabase → Vercel |
| Rollback partially failed | Check Slack history for last successful state; manually verify each service |
Output
Deliver:
- Deployment IDs and timestamps for each service
- Verification results (health checks, data counts)
- Slack announcement with links to deployments
- Rollback reference if needed for quick recovery