| name | ship-prod |
| description | Use when deploying qaskills.sh to production, verifying whether a deploy landed, or when a push to main did not show up on the live site, e.g. "deploy", "ship it", "push this live", "is prod updated?", "the site still shows the old version". |
Ship Prod
Deploys COMMITTED HEAD only, to the correct Vercel project, then proves the deploy landed. git push to main does not reliably auto-deploy; this skill is the deploy path.
Fixed facts
- Project:
qaskills.sh, project ID prj_rDKli4AyhHoXZXV8NHrs92Ncbf4f, org team_DGM6VSs6vhASlhktmHkSqPwn, account luckydutta96
- A decoy project
qaskills exists WITHOUT the domain. Never deploy there. Never accept interactive "link this directory?" defaults.
- Build command lives in root
vercel.json (shared build && web build); Node must stay 20.x (Neon driver breaks on 24)
vercel --prod uploads the WORKING TREE, not git HEAD
.vercel/project.json is gitignored, so fresh worktrees are unlinked: explicit env IDs required there
Preflight
cd /Users/promode/qaskills
vercel whoami
git status --short
git log -1 --oneline --stat | head -15
pnpm --filter @qaskills/shared build && pnpm --filter @qaskills/web build
Deploy
Clean tree (no modified or untracked files that could ship):
cd /Users/promode/qaskills && npx vercel --prod --yes
Dirty tree (default assumption; the working tree here usually carries WIP):
DEPLOY_DIR=$(mktemp -d)/qaskills-deploy
git -C /Users/promode/qaskills worktree add "$DEPLOY_DIR" HEAD
cd "$DEPLOY_DIR"
VERCEL_ORG_ID=team_DGM6VSs6vhASlhktmHkSqPwn \
VERCEL_PROJECT_ID=prj_rDKli4AyhHoXZXV8NHrs92Ncbf4f \
npx vercel --prod --yes
cd /Users/promode/qaskills
git worktree remove "$DEPLOY_DIR" --force
Capture the deployment URL the CLI prints; it goes in the final summary.
Verify (required, every deploy)
npx vercel ls | head -5
curl -s -o /dev/null -w '%{http_code}\n' https://qaskills.sh
curl -s -o /dev/null -w '%{http_code}\n' https://qaskills.sh/blog/<new-slug>
curl -s https://qaskills.sh/<changed-page> | grep -c '<expected-marker>'
All three must pass before saying "deployed". If the domain still serves old content while the new deployment is Ready, the alias did not move: npx vercel promote <deployment-url>.
Rollback
npx vercel ls
npx vercel promote <previous-url>
For a code-level revert, git revert <sha> on main, then run this skill again.
Failure modes
| Symptom | Cause | Fix |
|---|
CLI asks to link / offers project qaskills | Unlinked dir, interactive defaults | Abort; re-run with both VERCEL_* env vars set |
Error: not authorized / wrong scope | Logged into another account | vercel whoami; user runs vercel login as luckydutta96 |
| Vercel build fails, local build green | Env-dependent code at import time | Lazy-init pattern (see CLAUDE.md); no secrets required at build |
| Deploy Ready but site unchanged | Domain alias on older deployment, or you shipped stale HEAD | vercel promote; confirm intended commit was in HEAD |
| WIP appeared on prod | Deployed dirty working tree directly | Roll back via promote, then redeploy via worktree |
Red flags
- "The push probably triggered a deploy"
- Deploying from a dirty root without the worktree
- Answering Vercel's interactive prompts with defaults
- Declaring success without the three verification commands' output
- Touching Vercel project settings (Node version, env vars, domains) without user approval