| name | devops-deploy |
| description | 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. |
| argument-hint | [environment] [provider] |
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
vercel list <project-name> --limit 10
-
Rollback command:
vercel rollback
vercel rollback <deployment-url-or-id>
-
Verify rollback succeeded:
vercel inspect <project-name> --scope <team>
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:
aws ecs list-task-definitions --family-prefix <task-family> --sort DESC --max-items 10
aws ecs describe-services --cluster <cluster> --services <service> \
--query "services[0].taskDefinition"
-
Rollback command:
aws ecs update-service \
--cluster <cluster> \
--service <service> \
--task-definition <task-family>:<previous-revision-number> \
--force-new-deployment
aws ecs update-service \
--cluster <cluster> \
--service <service> \
--force-new-deployment
-
Verify rollback succeeded:
aws ecs wait services-stable --cluster <cluster> --services <service>
aws ecs describe-services --cluster <cluster> --services <service> \
--query "services[0].{taskDef:taskDefinition, status:status, running:runningCount, desired:desiredCount}"
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:
aws lambda list-versions-by-function --function-name <function-name> \
--query "Versions[-5:].[Version, Description, LastModified]" --output table
aws lambda list-aliases --function-name <function-name>
-
Rollback command:
aws lambda update-alias \
--function-name <function-name> \
--name <alias-name> \
--function-version <previous-version-number>
aws lambda get-function --function-name <function-name> --qualifier <previous-version>
aws lambda update-function-code \
--function-name <function-name> \
--s3-bucket <bucket> --s3-key <previous-package-key>
-
Verify rollback succeeded:
aws lambda get-alias --function-name <function-name> --name <alias-name>
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:
gcloud run revisions list --service <service-name> --region <region> --limit 10
gcloud run services describe <service-name> --region <region> \
--format="value(status.traffic)"
-
Rollback command:
gcloud run services update-traffic <service-name> \
--region <region> \
--to-revisions=<previous-revision-name>=100
-
Verify rollback succeeded:
gcloud run services describe <service-name> --region <region> \
--format="value(status.traffic)"
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:
fly releases --app <app-name>
fly status --app <app-name>
-
Rollback command:
fly deploy --image <previous-image-ref> --app <app-name>
fly releases rollback --app <app-name>
-
Verify rollback succeeded:
fly releases --app <app-name>
fly status --app <app-name>
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:
railway status
railway logs --deployment <deployment-id>
-
Rollback command:
railway rollback
railway rollback <deployment-id>
-
Verify rollback succeeded:
railway status
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:
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