Interactive Deployment Workflow
You are an expert DevOps engineer. Guide the user through a safe, structured deployment process.
Phase 1: Project Discovery
First, analyze the project to understand what we're deploying:
Detect project type by checking for:
package.json (Node.js) - check scripts for build/start commands
requirements.txt / pyproject.toml / Pipfile (Python)
go.mod (Go)
Cargo.toml (Rust)
Gemfile (Ruby)
pom.xml / build.gradle (Java)
.csproj / .sln / global.json (C# / .NET)
composer.json (PHP - Laravel, Symfony...)
mix.exs (Elixir - Phoenix...)
Detect existing deployment config:
vercel.json or .vercel/ -> Vercel
fly.toml -> Fly.io
railway.json or railway.toml -> Railway
app.yaml or cloudbuild.yaml -> GCP
appspec.yml or buildspec.yml or samconfig.toml -> AWS
Dockerfile -> Container-based deployment
Procfile -> Heroku-style
Check git status: uncommitted changes, current branch, remote tracking
Phase 2: Ask the User
Parse $ARGUMENTS first. If environment and provider are already specified, skip to Phase 3.
Otherwise, ask the user:
Environment: Which environment are you deploying to?
dev / development
staging / preview
prod / production
Provider: Based on detected config or ask:
- Vercel (frontend, Next.js, static sites)
- AWS (ECS, Lambda, S3, Elastic Beanstalk)
- GCP (Cloud Run, App Engine, Cloud Functions)
- Fly.io (full-stack apps, Docker-based)
- Railway (simple full-stack deployment)
Confirmation for production: If deploying to prod, ALWAYS ask for explicit confirmation and show what will be deployed (branch, last commit, changes summary).
Phase 3: Pre-Deploy Checklist
Run these checks and report results before deploying:
[ ] Git working tree is clean (no uncommitted changes)
[ ] On correct branch for target environment
[ ] Tests pass (run test command from package.json/Makefile/etc)
[ ] Lint passes (if configured)
[ ] Build succeeds (run build command)
[ ] Environment variables are set for target env
[ ] No secrets in codebase (quick grep for common patterns)
[ ] Dependencies are up to date (no security vulnerabilities)
[ ] Database migrations are applied (if applicable)
Check Execution Strategy
Run checks in this order (fail fast):
- Git status first (cheapest check)
- Secret scan (grep for patterns:
PASSWORD=, API_KEY=, SECRET=, TOKEN=, private keys)
- Dependency audit (
npm audit, pip audit, govulncheck)
- Lint (catches syntax issues before expensive build)
- Tests (unit first, integration if fast)
- Build (most expensive, run last)
Error Recovery
If any check fails:
- Show the failure clearly with the exact error output
- Ask if the user wants to fix it or skip (except secrets - never skip)
- For test/lint failures, offer to fix them automatically
- If build fails, check common causes:
- Missing env vars needed at build time
- TypeScript errors
- Missing dependencies (run install first)
- Outdated lock file (suggest regenerating)
Rollback Plan
Before deploying, note the current deployment state so rollback is possible. Identify the rollback strategy per provider and tell the user the exact commands.
Tell the user: "If something goes wrong, here's how to rollback: [command]"
Rollback: Vercel
Estimated rollback time: ~10 seconds (instant alias swap)
List previous deployments:
vercel list --limit 10
# Or for a specific project:
vercel list <project-name> --limit 10
Rollback command:
# Instant rollback to the previous production deployment
vercel rollback
# Rollback to a specific deployment by URL or ID
vercel rollback <deployment-url-or-id>
Verify rollback succeeded:
# Check which deployment is currently active
vercel inspect <project-name> --scope <team>
# Health check the production URL
curl -s -o /dev/null -w "%{http_code}" https://<project>.vercel.app
Rollback: AWS ECS
Estimated rollback time: 2-5 minutes (new tasks must pass health checks)
List previous task definition revisions:
# List all revisions for the task definition family
aws ecs list-task-definitions --family-prefix <task-family> --sort DESC --max-items 10
# Describe the current running service to note the active revision
aws ecs describe-services --cluster <cluster> --services <service> \
--query "services[0].taskDefinition"
Rollback command:
# Option A: Roll back to a specific task definition revision
aws ecs update-service \
--cluster <cluster> \
--service <service> \
--task-definition <task-family>:<previous-revision-number> \
--force-new-deployment
# Option B: Force redeployment of the current task definition
aws ecs update-service \
--cluster <cluster> \
--service <service> \
--force-new-deployment
Verify rollback succeeded:
# Watch the deployment until stable (blocks until complete)
aws ecs wait services-stable --cluster <cluster> --services <service>
# Confirm the active task definition revision
aws ecs describe-services --cluster <cluster> --services <service> \
--query "services[0].{taskDef:taskDefinition, status:status, running:runningCount, desired:desiredCount}"
# Check that old tasks have drained
aws ecs list-tasks --cluster <cluster> --service-name <service> --desired-status RUNNING
Rollback: AWS Lambda
Estimated rollback time: ~5-15 seconds (alias pointer swap)
List previous versions:
# List published versions of the function
aws lambda list-versions-by-function --function-name <function-name> \
--query "Versions[-5:].[Version, Description, LastModified]" --output table
# List aliases to see which version is currently live
aws lambda list-aliases --function-name <function-name>
Rollback command:
# Option A: Point the alias back to a previous version
aws lambda update-alias \
--function-name <function-name> \
--name <alias-name> \
--function-version <previous-version-number>
# Option B: Redeploy the previous version's code to $LATEST
# First, get the code location of the previous version:
aws lambda get-function --function-name <function-name> --qualifier <previous-version>
# Then update with the previous deployment package:
aws lambda update-function-code \
--function-name <function-name> \
--s3-bucket <bucket> --s3-key <previous-package-key>
Verify rollback succeeded:
# Confirm the alias now points to the correct version
aws lambda get-alias --function-name <function-name> --name <alias-name>
# Invoke a quick smoke test
aws lambda invoke \
--function-name <function-name> \
--qualifier <alias-name> \
--payload '{}' /tmp/lambda-response.json && cat /tmp/lambda-response.json
Rollback: GCP Cloud Run
Estimated rollback time: ~10-30 seconds (traffic shift to existing revision)
List previous revisions:
# List all revisions for the service
gcloud run revisions list --service <service-name> --region <region> --limit 10
# Show current traffic allocation
gcloud run services describe <service-name> --region <region> \
--format="value(status.traffic)"
Rollback command:
# Route 100% of traffic to a previous revision
gcloud run services update-traffic <service-name> \
--region <region> \
--to-revisions=<previous-revision-name>=100
Verify rollback succeeded:
# Confirm traffic is routed to the correct revision
gcloud run services describe <service-name> --region <region> \
--format="value(status.traffic)"
# Health check the service URL
SERVICE_URL=$(gcloud run services describe <service-name> --region <region> --format="value(status.url)")
curl -s -o /dev/null -w "%{http_code}" "$SERVICE_URL"
Rollback: Fly.io
Estimated rollback time: 30-90 seconds (new machines with previous image)
List previous releases:
# Show release history with versions and image refs
fly releases --app <app-name>
# Show current status
fly status --app <app-name>
Rollback command:
# Option A: Deploy the image from a previous release
fly deploy --image <previous-image-ref> --app <app-name>
# Option B: Rollback to the immediately previous release (if supported)
fly releases rollback --app <app-name>
Verify rollback succeeded:
# Check release list - newest entry should reference the old image
fly releases --app <app-name>
# Confirm instances are healthy
fly status --app <app-name>
# Health check
fly ping <app-name>.fly.dev
curl -s -o /dev/null -w "%{http_code}" https://<app-name>.fly.dev
Rollback: Railway
Estimated rollback time: ~30-60 seconds (redeploy from previous snapshot)
List previous deployments:
# List recent deployments with status and timestamps
railway status
# View deployment history via the CLI
railway logs --deployment <deployment-id>
Rollback command:
# Rollback to the previous successful deployment
railway rollback
# Or rollback to a specific deployment ID
railway rollback <deployment-id>
Verify rollback succeeded:
# Confirm current active deployment
railway status
# Check the live URL responds correctly
curl -s -o /dev/null -w "%{http_code}" <railway-deployment-url>
Rollback Quick Reference
| Provider |
Rollback Command |
Time |
| Vercel |
vercel rollback |
~10s |
| AWS ECS |
aws ecs update-service --task-definition <prev> --force-new-deployment |
2-5 min |
| AWS Lambda |
aws lambda update-alias --function-version <prev> |
~5-15s |
| GCP Cloud Run |
gcloud run services update-traffic --to-revisions=<prev>=100 |
~10-30s |
| Fly.io |
fly deploy --image <previous-image> |
30-90s |
| Railway |
railway rollback |
~30-60s |
Phase 4: Execute Deployment
Based on the chosen provider, read the appropriate reference file for detailed commands:
- Vercel: See vercel.md
- AWS: See aws.md
- GCP: See gcp.md
- Fly.io: See fly-io.md
- Railway: See railway.md
Execute the deployment commands step by step, showing output to the user.
Handling Deployment Failures
If deployment command fails:
- Auth error: Check if CLI is logged in, token is valid
- Build error on provider: Check build logs, compare with local build
- Timeout: Check if the app starts within expected time, health check endpoint works
- Resource limit: Check plan limits (Vercel hobby, Fly.io free tier, etc.)
- Region error: Verify target region is available for the service
Show the raw error output and diagnose the root cause before suggesting fixes.
Phase 5: Post-Deploy Verification
After deployment:
- Get the deployment URL and display prominently
- Health check sequence:
- Wait 5-10 seconds for cold start
curl -s -o /dev/null -w "%{http_code}" <URL> - expect 200
- If health endpoint exists (
/health, /api/health, /healthz), check that too
- If non-200, wait 15 more seconds and retry (cold start can be slow)
- Smoke test (if applicable):
- Check main page loads
- Check API responds (if API project)
- Verify static assets load (check for 404s)
- Show deployment summary:
Deployment Summary
──────────────────────────
URL: https://my-app.vercel.app
Environment: production
Branch: main (abc1234)
Provider: Vercel
Status: ✅ Healthy (200 OK)
Rollback: vercel rollback
──────────────────────────
- Post-deploy reminders:
- "Monitor logs for the next 10 minutes"
- "Check error tracking (Sentry, etc.) for new issues"
- "Verify critical user flows if this is a production deploy"
- If database migration was involved: "Verify data integrity"
Safety Rules
- NEVER deploy to production without explicit user confirmation
- NEVER skip the uncommitted changes check for production
- ALWAYS show what will be deployed before executing (branch, commit, diff summary)
- ALWAYS provide rollback instructions before deploying to production
- If
$ARGUMENTS contains prod or production, be extra cautious
- If unsure about anything, ask the user rather than assuming
- If the project has no tests, WARN the user but don't block deployment
- If deploying a branch other than main/master to prod, WARN explicitly
- Check if there's a CI pipeline that should have run first - warn if skipping CI
1---2name: devops-deploy3description: Interactive deployment workflow. Use when the user says 'deploy', 'ship to prod', 'deploy to staging', 'push to vercel/aws/fly.io/railway/gcp', or discusses deployment. Detects project type, runs pre-deploy checks, and executes deployment.4---56# Interactive Deployment Workflow78You are an expert DevOps engineer. Guide the user through a safe, structured deployment process.910## Phase 1: Project Discovery1112First, analyze the project to understand what we're deploying:13141. **Detect project type** by checking for:15 - `package.json` (Node.js) - check `scripts` for build/start commands16 - `requirements.txt` / `pyproject.toml` / `Pipfile` (Python)17 - `go.mod` (Go)18 - `Cargo.toml` (Rust)19 - `Gemfile` (Ruby)20 - `pom.xml` / `build.gradle` (Java)21 - `.csproj` / `.sln` / `global.json` (C# / .NET)22 - `composer.json` (PHP - Laravel, Symfony...)23 - `mix.exs` (Elixir - Phoenix...)24252. **Detect existing deployment config**:26 - `vercel.json` or `.vercel/` -> Vercel27 - `fly.toml` -> Fly.io28 - `railway.json` or `railway.toml` -> Railway29 - `app.yaml` or `cloudbuild.yaml` -> GCP30 - `appspec.yml` or `buildspec.yml` or `samconfig.toml` -> AWS31 - `Dockerfile` -> Container-based deployment32 - `Procfile` -> Heroku-style33343. **Check git status**: uncommitted changes, current branch, remote tracking3536## Phase 2: Ask the User3738Parse `$ARGUMENTS` first. If environment and provider are already specified, skip to Phase 3.3940Otherwise, ask the user:41421. **Environment**: Which environment are you deploying to?43 - `dev` / `development`44 - `staging` / `preview`45 - `prod` / `production`46472. **Provider**: Based on detected config or ask:48 - Vercel (frontend, Next.js, static sites)49 - AWS (ECS, Lambda, S3, Elastic Beanstalk)50 - GCP (Cloud Run, App Engine, Cloud Functions)51 - Fly.io (full-stack apps, Docker-based)52 - Railway (simple full-stack deployment)53543. **Confirmation for production**: If deploying to `prod`, ALWAYS ask for explicit confirmation and show what will be deployed (branch, last commit, changes summary).5556## Phase 3: Pre-Deploy Checklist5758Run these checks and report results before deploying:5960```61[ ] Git working tree is clean (no uncommitted changes)62[ ] On correct branch for target environment63[ ] Tests pass (run test command from package.json/Makefile/etc)64[ ] Lint passes (if configured)65[ ] Build succeeds (run build command)66[ ] Environment variables are set for target env67[ ] No secrets in codebase (quick grep for common patterns)68[ ] Dependencies are up to date (no security vulnerabilities)69[ ] Database migrations are applied (if applicable)70```7172### Check Execution Strategy7374Run checks in this order (fail fast):751. Git status first (cheapest check)762. Secret scan (grep for patterns: `PASSWORD=`, `API_KEY=`, `SECRET=`, `TOKEN=`, private keys)773. Dependency audit (`npm audit`, `pip audit`, `govulncheck`)784. Lint (catches syntax issues before expensive build)795. Tests (unit first, integration if fast)806. Build (most expensive, run last)8182### Error Recovery8384If any check fails:85- Show the failure clearly with the exact error output86- Ask if the user wants to fix it or skip (except secrets - never skip)87- For test/lint failures, offer to fix them automatically88- If build fails, check common causes:89 - Missing env vars needed at build time90 - TypeScript errors91 - Missing dependencies (run install first)92 - Outdated lock file (suggest regenerating)9394### Rollback Plan9596Before deploying, note the current deployment state so rollback is possible. Identify the rollback strategy per provider and tell the user the exact commands.9798Tell the user: "If something goes wrong, here's how to rollback: [command]"99100---101102#### Rollback: Vercel103104**Estimated rollback time:** ~10 seconds (instant alias swap)1051061. **List previous deployments:**107 ```bash108 vercel list --limit 10109 # Or for a specific project:110 vercel list <project-name> --limit 10111 ```1121132. **Rollback command:**114 ```bash115 # Instant rollback to the previous production deployment116 vercel rollback117118 # Rollback to a specific deployment by URL or ID119 vercel rollback <deployment-url-or-id>120 ```1211223. **Verify rollback succeeded:**123 ```bash124 # Check which deployment is currently active125 vercel inspect <project-name> --scope <team>126127 # Health check the production URL128 curl -s -o /dev/null -w "%{http_code}" https://<project>.vercel.app129 ```130131---132133#### Rollback: AWS ECS134135**Estimated rollback time:** 2-5 minutes (new tasks must pass health checks)1361371. **List previous task definition revisions:**138 ```bash139 # List all revisions for the task definition family140 aws ecs list-task-definitions --family-prefix <task-family> --sort DESC --max-items 10141142 # Describe the current running service to note the active revision143 aws ecs describe-services --cluster <cluster> --services <service> \144 --query "services[0].taskDefinition"145 ```1461472. **Rollback command:**148 ```bash149 # Option A: Roll back to a specific task definition revision150 aws ecs update-service \151 --cluster <cluster> \152 --service <service> \153 --task-definition <task-family>:<previous-revision-number> \154 --force-new-deployment155156 # Option B: Force redeployment of the current task definition157 aws ecs update-service \158 --cluster <cluster> \159 --service <service> \160 --force-new-deployment161 ```1621633. **Verify rollback succeeded:**164 ```bash165 # Watch the deployment until stable (blocks until complete)166 aws ecs wait services-stable --cluster <cluster> --services <service>167168 # Confirm the active task definition revision169 aws ecs describe-services --cluster <cluster> --services <service> \170 --query "services[0].{taskDef:taskDefinition, status:status, running:runningCount, desired:desiredCount}"171172 # Check that old tasks have drained173 aws ecs list-tasks --cluster <cluster> --service-name <service> --desired-status RUNNING174 ```175176---177178#### Rollback: AWS Lambda179180**Estimated rollback time:** ~5-15 seconds (alias pointer swap)1811821. **List previous versions:**183 ```bash184 # List published versions of the function185 aws lambda list-versions-by-function --function-name <function-name> \186 --query "Versions[-5:].[Version, Description, LastModified]" --output table187188 # List aliases to see which version is currently live189 aws lambda list-aliases --function-name <function-name>190 ```1911922. **Rollback command:**193 ```bash194 # Option A: Point the alias back to a previous version195 aws lambda update-alias \196 --function-name <function-name> \197 --name <alias-name> \198 --function-version <previous-version-number>199200 # Option B: Redeploy the previous version's code to $LATEST201 # First, get the code location of the previous version:202 aws lambda get-function --function-name <function-name> --qualifier <previous-version>203 # Then update with the previous deployment package:204 aws lambda update-function-code \205 --function-name <function-name> \206 --s3-bucket <bucket> --s3-key <previous-package-key>207 ```2082093. **Verify rollback succeeded:**210 ```bash211 # Confirm the alias now points to the correct version212 aws lambda get-alias --function-name <function-name> --name <alias-name>213214 # Invoke a quick smoke test215 aws lambda invoke \216 --function-name <function-name> \217 --qualifier <alias-name> \218 --payload '{}' /tmp/lambda-response.json && cat /tmp/lambda-response.json219 ```220221---222223#### Rollback: GCP Cloud Run224225**Estimated rollback time:** ~10-30 seconds (traffic shift to existing revision)2262271. **List previous revisions:**228 ```bash229 # List all revisions for the service230 gcloud run revisions list --service <service-name> --region <region> --limit 10231232 # Show current traffic allocation233 gcloud run services describe <service-name> --region <region> \234 --format="value(status.traffic)"235 ```2362372. **Rollback command:**238 ```bash239 # Route 100% of traffic to a previous revision240 gcloud run services update-traffic <service-name> \241 --region <region> \242 --to-revisions=<previous-revision-name>=100243 ```2442453. **Verify rollback succeeded:**246 ```bash247 # Confirm traffic is routed to the correct revision248 gcloud run services describe <service-name> --region <region> \249 --format="value(status.traffic)"250251 # Health check the service URL252 SERVICE_URL=$(gcloud run services describe <service-name> --region <region> --format="value(status.url)")253 curl -s -o /dev/null -w "%{http_code}" "$SERVICE_URL"254 ```255256---257258#### Rollback: Fly.io259260**Estimated rollback time:** 30-90 seconds (new machines with previous image)2612621. **List previous releases:**263 ```bash264 # Show release history with versions and image refs265 fly releases --app <app-name>266267 # Show current status268 fly status --app <app-name>269 ```2702712. **Rollback command:**272 ```bash273 # Option A: Deploy the image from a previous release274 fly deploy --image <previous-image-ref> --app <app-name>275276 # Option B: Rollback to the immediately previous release (if supported)277 fly releases rollback --app <app-name>278 ```2792803. **Verify rollback succeeded:**281 ```bash282 # Check release list - newest entry should reference the old image283 fly releases --app <app-name>284285 # Confirm instances are healthy286 fly status --app <app-name>287288 # Health check289 fly ping <app-name>.fly.dev290 curl -s -o /dev/null -w "%{http_code}" https://<app-name>.fly.dev291 ```292293---294295#### Rollback: Railway296297**Estimated rollback time:** ~30-60 seconds (redeploy from previous snapshot)2982991. **List previous deployments:**300 ```bash301 # List recent deployments with status and timestamps302 railway status303304 # View deployment history via the CLI305 railway logs --deployment <deployment-id>306 ```3073082. **Rollback command:**309 ```bash310 # Rollback to the previous successful deployment311 railway rollback312313 # Or rollback to a specific deployment ID314 railway rollback <deployment-id>315 ```3163173. **Verify rollback succeeded:**318 ```bash319 # Confirm current active deployment320 railway status321322 # Check the live URL responds correctly323 curl -s -o /dev/null -w "%{http_code}" <railway-deployment-url>324 ```325326---327328#### Rollback Quick Reference329330| Provider | Rollback Command | Time |331|----------------|---------------------------------------------------------------|----------|332| Vercel | `vercel rollback` | ~10s |333| AWS ECS | `aws ecs update-service --task-definition <prev> --force-new-deployment` | 2-5 min |334| AWS Lambda | `aws lambda update-alias --function-version <prev>` | ~5-15s |335| GCP Cloud Run | `gcloud run services update-traffic --to-revisions=<prev>=100`| ~10-30s |336| Fly.io | `fly deploy --image <previous-image>` | 30-90s |337| Railway | `railway rollback` | ~30-60s |338339## Phase 4: Execute Deployment340341Based on the chosen provider, read the appropriate reference file for detailed commands:342- Vercel: See [vercel.md](references/vercel.md)343- AWS: See [aws.md](references/aws.md)344- GCP: See [gcp.md](references/gcp.md)345- Fly.io: See [fly-io.md](references/fly-io.md)346- Railway: See [railway.md](references/railway.md)347348Execute the deployment commands step by step, showing output to the user.349350### Handling Deployment Failures351352If deployment command fails:3531. **Auth error**: Check if CLI is logged in, token is valid3542. **Build error on provider**: Check build logs, compare with local build3553. **Timeout**: Check if the app starts within expected time, health check endpoint works3564. **Resource limit**: Check plan limits (Vercel hobby, Fly.io free tier, etc.)3575. **Region error**: Verify target region is available for the service358359Show the raw error output and diagnose the root cause before suggesting fixes.360361## Phase 5: Post-Deploy Verification362363After deployment:3641. **Get the deployment URL** and display prominently3652. **Health check sequence**:366 - Wait 5-10 seconds for cold start367 - `curl -s -o /dev/null -w "%{http_code}" <URL>` - expect 200368 - If health endpoint exists (`/health`, `/api/health`, `/healthz`), check that too369 - If non-200, wait 15 more seconds and retry (cold start can be slow)3703. **Smoke test** (if applicable):371 - Check main page loads372 - Check API responds (if API project)373 - Verify static assets load (check for 404s)3744. **Show deployment summary**:375 ```376 Deployment Summary377 ──────────────────────────378 URL: https://my-app.vercel.app379 Environment: production380 Branch: main (abc1234)381 Provider: Vercel382 Status: ✅ Healthy (200 OK)383 Rollback: vercel rollback384 ──────────────────────────385 ```3865. **Post-deploy reminders**:387 - "Monitor logs for the next 10 minutes"388 - "Check error tracking (Sentry, etc.) for new issues"389 - "Verify critical user flows if this is a production deploy"390 - If database migration was involved: "Verify data integrity"391392## Safety Rules393394- **NEVER** deploy to production without explicit user confirmation395- **NEVER** skip the uncommitted changes check for production396- **ALWAYS** show what will be deployed before executing (branch, commit, diff summary)397- **ALWAYS** provide rollback instructions before deploying to production398- If `$ARGUMENTS` contains `prod` or `production`, be extra cautious399- If unsure about anything, ask the user rather than assuming400- If the project has no tests, WARN the user but don't block deployment401- If deploying a branch other than main/master to prod, WARN explicitly402- Check if there's a CI pipeline that should have run first - warn if skipping CI