[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7523K35GMMRJPR6GXA990JD":3,"skill-same:01M7523K35GMMRJPR6GXA990JD":49},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":26,"commitSha":27,"skillDirectory":28,"forksCount":29,"repositoryHtmlUrl":30,"repositoryHomepageUrl":31,"ownerHtmlUrl":32,"ownerBlogUrl":31,"ownerDescription":33,"updatedAt":34,"install":35,"resources":48},"01M7523K35GMMRJPR6GXA990JD","vercel-deploy-pipeline",null,"Ship a Next.js app to Vercel the production way: promote a tested preview to production, instant-rollback a bad release, build once with --prebuilt, run a staged\u002Fcanary rollout with Rolling Releases (GA), and wire the deploy into CI. Use when someone says \"deploy to Vercel\", \"promote preview to production\", \"vercel promote\", \"roll back the deploy\", \"vercel rollback\", \"instant rollback\", \"canary release on Vercel\", \"rolling release\", \"--prebuilt build\", \"vercel deploy in GitHub Actions\", or \"set up CI for my Vercel project\". Do NOT use to manage env vars or pull .env - use vercel-env-management instead; do NOT use to tune runtime\u002Fcold-start\u002FISR performance - use next-on-vercel-perf or vercel-edge-and-isr instead.","SkillMedev\u002Fskills","SkillMedev","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F298078254?v=4","01M74ZSGTQ918CB0VXW4EG3RMX","SkillMe","01M74ZSGVBT497NA95CBT8JTY4",25,"MIT","https:\u002F\u002Fgithub.com\u002FSkillMedev\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fvercel-deploy-pipeline\u002FSKILL.md",[],[],"2026-11-11 18:27:18",false,"---\nname: vercel-deploy-pipeline\ndescription: \"Ship a Next.js app to Vercel the production way: promote a tested preview to production, instant-rollback a bad release, build once with --prebuilt, run a staged\u002Fcanary rollout with Rolling Releases (GA), and wire the deploy into CI. Use when someone says \\\"deploy to Vercel\\\", \\\"promote preview to production\\\", \\\"vercel promote\\\", \\\"roll back the deploy\\\", \\\"vercel rollback\\\", \\\"instant rollback\\\", \\\"canary release on Vercel\\\", \\\"rolling release\\\", \\\"--prebuilt build\\\", \\\"vercel deploy in GitHub Actions\\\", or \\\"set up CI for my Vercel project\\\". Do NOT use to manage env vars or pull .env - use vercel-env-management instead; do NOT use to tune runtime\u002Fcold-start\u002FISR performance - use next-on-vercel-perf or vercel-edge-and-isr instead.\"\nmetadata:\n  title: \"Vercel Deploy Pipeline\"\n---\n\n# Vercel Deploy Pipeline\n\nYou own the *ship* step of a curated \"Next.js app on Vercel\" workflow. This is not\nthe official Vercel CLI plugin re-stated - it sequences the platform into one\nopinionated path: build a preview, prove it, promote the **same artifact** to\nproduction, and keep a one-command escape hatch. The governing rule is **promote,\ndon't rebuild**: a deployment is immutable, so the bytes you tested in preview are\nthe exact bytes you put in front of users. Rebuilding to \"release\" reintroduces\nevery risk you just verified.\n\nTrigger eagerly on anything about deploying a Next.js app to Vercel, promoting\npreview to production, rolling back, building with `--prebuilt`, canary \u002F staged\nrollouts, or wiring `vercel` into CI. Hand off the adjacent concerns:\n**vercel-env-management** owns env vars and `vercel env pull`;\n**vercel-ai-gateway** owns model routing; **vercel-edge-and-isr** owns ISR \u002F Cache\nComponents and runtime placement; **vercel-firewall-and-botid** owns WAF\u002FBotID;\n**next-on-vercel-perf** owns Fluid Compute cold-start and bundle tuning.\n\n## Platform facts this skill assumes (current as of 2026)\n\n- **Runtime:** Node.js 24 LTS is the default (18 is deprecated). Default function\n  `maxDuration` is 300s on every plan. Default to **Fluid Compute** (full Node.js,\n  instance reuse for fewer cold starts) - Edge Functions are deprecated; do not\n  reach for them.\n- **Config:** prefer `vercel.ts` (`import { ... } from '@vercel\u002Fconfig'`);\n  `vercel.json` still works and is fine for CI-only settings.\n- **Deployments are immutable.** Promotion and rollback re-point the production\n  alias at an existing deployment - they never rebuild. That is the whole reason\n  rollback is instant.\n- **Rolling Releases is GA (Jun 2025):** staged\u002Fcanary traffic shifting to a new\n  production deployment, automatic (time-based) or manual-approval stages.\n\n## The pipeline (run in order)\n\n### 1. Build a preview deployment\n\nEvery change goes through a preview first. From a feature branch:\n\n```bash\nvercel deploy            # preview build + deploy; prints a unique preview URL\n```\n\nGit-connected projects already do this on every push\u002FPR - let the Git integration\nbuild previews and reserve the CLI for promotion, rollback, and CI. Preview URLs\nare immutable and shareable; this URL is the artifact you will promote.\n\n### 2. Prove the preview before it is allowed near production\n\nDo not promote on vibes. Inspect, hit real routes, and check error logs on the\n**preview** deployment:\n\n```bash\nvercel inspect \u003Cpreview-url>                                  # status, build, aliases\nvercel curl \u002Fapi\u002Fhealth --deployment \u003Cpreview-url>            # bypasses deploy protection\nvercel logs --deployment \u003Cpreview-url> --level error --limit 50\n```\n\nIf anything is red here, fix and redeploy a new preview. Promotion should be\nboring.\n\n### 3. Promote the *same* deployment to production\n\nThis is the heart of the pipeline. Re-point the production alias at the preview you\njust verified - no rebuild:\n\n```bash\nvercel promote \u003Cpreview-url> --yes        # --yes skips the confirm prompt (CI-safe)\nvercel promote status                     # confirm the promotion landed\n```\n\n`vercel deploy --prod` is the *build-and-release-in-one* alternative; use it for the\ntrivial path (small project, trunk-based, no separate verification gate). For\nanything with a review gate, **build once in preview, then `vercel promote`** so the\nreleased bytes equal the tested bytes.\n\n### 4. Keep the instant-rollback escape hatch ready\n\nBecause deployments are immutable, rollback is an alias re-point, not a revert\ncommit - it restores service in seconds while you debug at leisure:\n\n```bash\nvercel rollback                                   # roll back to the previous production deployment\nvercel rollback \u003Cgood-deployment-url-or-id>       # or target a specific known-good one\nvercel rollback status                            # confirm the alias moved\n```\n\nWhen you do not know *which* deployment broke, binary-search instead of guessing:\n\n```bash\nvercel bisect --good \u003Cgood-url> --bad \u003Cbad-url>                 # interactive\nvercel bisect --good \u003Cgood-url> --bad \u003Cbad-url> --run .\u002Ftest.sh # exit 0=good, non-0=bad, 125=skip\n```\n\nRoll back **first**, find root cause **second**. A green production beats a clever\ndiagnosis.\n\n### 5. Build once, deploy with --prebuilt (decouple build from deploy)\n\nWhen CI already runs `next build`, do not pay for the build twice. Build locally \u002F\nin CI, then upload the prebuilt output so Vercel skips its build step:\n\n```bash\nvercel pull --yes --environment=production   # fetch project settings + env into .vercel\u002F\nvercel build --prod                          # produces .vercel\u002Foutput (Build Output API)\nvercel deploy --prebuilt --prod              # upload + deploy that output, no remote build\n```\n\nMatch the `vercel build` target to the deploy target: `--prod` on both for\nproduction, neither for preview. `--prebuilt` is what makes CI deploys fast and\nmakes the artifact you tested the artifact you ship.\n\n### 6. Stage the rollout with Rolling Releases (canary)\n\nFor high-traffic or risky changes, shift production traffic gradually instead of a\n100% cutover. Configure stages once per project (CLI shown; the dashboard and REST\nAPI do the same):\n\n```bash\n# Automatic, time-based: 10% for 5m, 50% for 10m, then 100%\nvercel rolling-release configure --cfg '{\"enabled\":true,\"advancementType\":\"automatic\",\"stages\":[{\"targetPercentage\":10,\"duration\":5},{\"targetPercentage\":50,\"duration\":10},{\"targetPercentage\":100}]}'\n\n# Or manual approval between stages (you gate each advance)\nvercel rolling-release configure --enable --advancement-type=manual-approval --stage=10\n```\n\nThen deploy to production and **start** the rolling release so the new deployment\nbecomes a **canary** - it takes the first stage's traffic share while the previous\nproduction serves the rest:\n\n```bash\nvercel deploy --prod                              # deploy the new production candidate\nvercel rolling-release start --dpl \u003Ccanary-url>   # begin the staged rollout for that deployment\nvercel rolling-release fetch                      # current stage + traffic split\n```\n\nAdvance, complete, or abort by traffic-watching the canary. Every command targets\nthe specific deployment with `--dpl`:\n\n```bash\nvercel rolling-release approve --dpl \u003Ccanary-url> --currentStageIndex 0   # advance one stage (manual-approval)\nvercel rolling-release complete --dpl \u003Ccanary-url>                        # promote the canary to 100% production\nvercel rolling-release abort --dpl \u003Ccanary-url>                           # instant rollback: all traffic back to old prod\n```\n\nA rolling release is just a *gated* promotion - same immutable-deployment model,\nsame instant-undo. Aborting is step 4 applied to a canary. Watch the canary's error\nrate (`vercel rolling-release fetch` plus `vercel logs --environment production --level error --since 5m`) before advancing.\n\n### 7. Wire it into CI\n\nEncode steps 1-5 as a workflow so humans never hand-run a production deploy.\nPattern: **PR → preview deploy + checks; merge to main → prebuilt production\ndeploy**. See the runnable GitHub Actions template below. Store `VERCEL_TOKEN`,\n`VERCEL_ORG_ID`, `VERCEL_PROJECT_ID` as CI secrets;\n**runtime app env vars belong in Vercel and are pulled by `vercel pull` - manage\nthose with vercel-env-management, not in the workflow file.**\n\n## Quality bar\n\nA deploy pipeline is A+ only when all hold:\n\n- **Promote, don't rebuild.** Production runs a deployment that was first built and\n  verified as a preview (`vercel promote` \u002F `--prebuilt`), not a fresh `--prod` build\n  whose bytes nobody has seen.\n- **Every promotion is gated** by an inspect + real-route check + error-log scan on\n  the preview (step 2). No green checks, no promote.\n- **Rollback is one command and rehearsed.** The team knows `vercel rollback` and has\n  run it at least once on purpose, not for the first time during an incident.\n- **CI deploys are non-interactive:** `--yes` on prompts, target flags\n  (`--prod`\u002Fnone) consistent between `vercel build` and `vercel deploy`, secrets in the CI\n  store.\n- **Risky changes ship as a canary** (Rolling Releases) with a watched first stage,\n  not a 100% cutover.\n- **No stale runtime claims.** Functions default to Node.js 24 + Fluid Compute;\n  nothing in the pipeline pins Node 18 or routes new code onto Edge Functions.\n\n## Do NOT\n\n- Do NOT run a fresh `vercel deploy --prod` to \"release\" a change you already built and\n  tested in preview - promote the existing deployment so released bytes equal tested\n  bytes.\n- Do NOT debug a broken production before rolling back. Run `vercel rollback` to\n  restore service, *then* investigate.\n- Do NOT mismatch build\u002Fdeploy targets: `vercel build` (preview) + `vercel deploy --prebuilt --prod`\n  ships a preview build to production. Keep `--prod` on both or neither.\n- Do NOT bake runtime app secrets into the CI workflow or `vercel.json` - they live in\n  Vercel and arrive via `vercel pull`. That is vercel-env-management's job.\n- Do NOT target deprecated Edge Functions or pin Node 18 for new functions; default\n  to Fluid Compute on Node.js 24.\n- Do NOT hand-promote production from a laptop once CI exists - the workflow is the\n  source of truth; manual `promote`\u002F`rollback` is the break-glass path.\n- Do NOT treat a rolling release as fire-and-forget: watch the canary's error rate\n  before `approve`\u002F`complete`, and `abort` the moment it regresses.\n\n## Artifact: preflight gate script\n\nSelf-contained Bash. Save as `promote-gate.sh`, run as\n`.\u002Fpromote-gate.sh \u003Cpreview-url>`. It runs the step-2 checks and only prints the\nexact `vercel promote` command when the preview passes - so a human (or CI) never\npromotes an unproven deployment. Needs the Vercel CLI logged in (`vercel login`) and\na linked project. No other dependencies.\n\n```bash\n#!\u002Fusr\u002Fbin\u002Fenv bash\n# Gate a preview deployment before promotion. Usage: .\u002Fpromote-gate.sh \u003Cpreview-url> [health-path]\nset -euo pipefail\n\nURL=\"${1:?usage: .\u002Fpromote-gate.sh \u003Cpreview-url> [health-path]}\"\nHEALTH=\"${2:-\u002Fapi\u002Fhealth}\"\n\necho \"==> Inspecting $URL\"\nvercel inspect \"$URL\" >\u002Fdev\u002Fnull || { echo \"FAIL: deployment not inspectable\"; exit 1; }\n\necho \"==> Hitting $HEALTH (deploy-protection bypassed)\"\nif ! vercel curl \"$HEALTH\" --deployment \"$URL\" >\u002Fdev\u002Fnull 2>&1; then\n  echo \"FAIL: health route $HEALTH did not respond 2xx\"; exit 1\nfi\n\necho \"==> Scanning error logs\"\nERRS=\"$(vercel logs --deployment \"$URL\" --level error --limit 50 2>\u002Fdev\u002Fnull | grep -c . || true)\"\nif [ \"${ERRS:-0}\" -gt 0 ]; then\n  echo \"FAIL: $ERRS error log line(s) on the preview - fix before promoting\"; exit 1\nfi\n\necho \"==> PASS. Promote the SAME deployment (no rebuild) with:\"\necho \"    vercel promote $URL --yes && vercel promote status\"\n```\n\n### Worked example output\n\n```\n$ .\u002Fpromote-gate.sh https:\u002F\u002Facme-7gk2qz.vercel.app\n==> Inspecting https:\u002F\u002Facme-7gk2qz.vercel.app\n==> Hitting \u002Fapi\u002Fhealth (deploy-protection bypassed)\n==> Scanning error logs\n==> PASS. Promote the SAME deployment (no rebuild) with:\n    vercel promote https:\u002F\u002Facme-7gk2qz.vercel.app --yes && vercel promote status\n```\n\nRead it: the preview was inspectable, its health route returned 2xx, and there were\nno error-level logs - so the gate emits the promote command for the *exact* URL it\nverified. A failing health check or any error line exits non-zero and prints no\npromote command, so CI stops and nothing reaches production.\n\n## Template: CI deploy workflow (GitHub Actions)\n\nDrop in `.github\u002Fworkflows\u002Fdeploy.yml`. PRs get a verified preview; merges to `main`\nget a **prebuilt** production deploy (build once, deploy that output). Set\n`VERCEL_TOKEN`, `VERCEL_ORG_ID`, `VERCEL_PROJECT_ID` as repo secrets. Runtime app env vars\nare NOT here - they live in Vercel and are fetched by `vercel pull` (see\nvercel-env-management).\n\n```yaml\nname: Deploy\non:\n  push:\n    branches: [main]\n  pull_request:\n\nenv:\n  VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}\n  VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}\n\njobs:\n  preview:\n    if: github.event_name == 'pull_request'\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@v4\n      - uses: actions\u002Fsetup-node@v4\n        with: { node-version: 24 }          # Node.js 24 LTS - matches the runtime default\n      - run: npm i -g vercel@latest\n      - run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}\n      - run: vercel build --token=${{ secrets.VERCEL_TOKEN }}\n      - name: Deploy preview (prebuilt)\n        run: |\n          URL=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})\n          echo \"Preview: $URL\"\n          # gate before this preview is allowed to be promoted by the prod job\n          vercel inspect \"$URL\" --token=${{ secrets.VERCEL_TOKEN }}\n\n  production:\n    if: github.ref == 'refs\u002Fheads\u002Fmain' && github.event_name == 'push'\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@v4\n      - uses: actions\u002Fsetup-node@v4\n        with: { node-version: 24 }\n      - run: npm i -g vercel@latest\n      - run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}\n      - run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}     # build once\n      - name: Deploy production (prebuilt, same bytes)\n        run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}\n      # Rollback is intentionally a manual break-glass step:\n      #   vercel rollback --token=$VERCEL_TOKEN && vercel rollback status\n```\n\nFill in the secrets, commit, and the pipeline runs steps 1-5 on every change. Add a\nmanual-approval environment around the `production` job, or swap the prod deploy for a\nRolling Release (step 6), when a change needs a canary instead of a cutover.\n","# Vercel Deploy Pipeline\n\nYou own the *ship* step of a curated \"Next.js app on Vercel\" workflow. This is not\nthe official Vercel CLI plugin re-stated - it sequences the platform into one\nopinionated path: build a preview, prove it, promote the **same artifact** to\nproduction, and keep a one-command escape hatch. The governing rule is **promote,\ndon't rebuild**: a deployment is immutable, so the bytes you tested in preview are\nthe exact bytes you put in front of users. Rebuilding to \"release\" reintroduces\nevery risk you just verified.\n\nTrigger eagerly on anything about deploying a Next.js app to Vercel, promoting\npreview to production, rolling back, building with `--prebuilt`, canary \u002F staged\nrollouts, or wiring `vercel` into CI. Hand off the adjacent concerns:\n**vercel-env-management** owns env vars and `vercel env pull`;\n**vercel-ai-gateway** owns model routing; **vercel-edge-and-isr** owns ISR \u002F Cache\nComponents and runtime placement; **vercel-firewall-and-botid** owns WAF\u002FBotID;\n**next-on-vercel-perf** owns Fluid Compute cold-start and bundle tuning.\n\n## Platform facts this skill assumes (current as of 2026)\n\n- **Runtime:** Node.js 24 LTS is the default (18 is deprecated). Default function\n  `maxDuration` is 300s on every plan. Default to **Fluid Compute** (full Node.js,\n  instance reuse for fewer cold starts) - Edge Functions are deprecated; do not\n  reach for them.\n- **Config:** prefer `vercel.ts` (`import { ... } from '@vercel\u002Fconfig'`);\n  `vercel.json` still works and is fine for CI-only settings.\n- **Deployments are immutable.** Promotion and rollback re-point the production\n  alias at an existing deployment - they never rebuild. That is the whole reason\n  rollback is instant.\n- **Rolling Releases is GA (Jun 2025):** staged\u002Fcanary traffic shifting to a new\n  production deployment, automatic (time-based) or manual-approval stages.\n\n## The pipeline (run in order)\n\n### 1. Build a preview deployment\n\nEvery change goes through a preview first. From a feature branch:\n\n```bash\nvercel deploy            # preview build + deploy; prints a unique preview URL\n```\n\nGit-connected projects already do this on every push\u002FPR - let the Git integration\nbuild previews and reserve the CLI for promotion, rollback, and CI. Preview URLs\nare immutable and shareable; this URL is the artifact you will promote.\n\n### 2. Prove the preview before it is allowed near production\n\nDo not promote on vibes. Inspect, hit real routes, and check error logs on the\n**preview** deployment:\n\n```bash\nvercel inspect \u003Cpreview-url>                                  # status, build, aliases\nvercel curl \u002Fapi\u002Fhealth --deployment \u003Cpreview-url>            # bypasses deploy protection\nvercel logs --deployment \u003Cpreview-url> --level error --limit 50\n```\n\nIf anything is red here, fix and redeploy a new preview. Promotion should be\nboring.\n\n### 3. Promote the *same* deployment to production\n\nThis is the heart of the pipeline. Re-point the production alias at the preview you\njust verified - no rebuild:\n\n```bash\nvercel promote \u003Cpreview-url> --yes        # --yes skips the confirm prompt (CI-safe)\nvercel promote status                     # confirm the promotion landed\n```\n\n`vercel deploy --prod` is the *build-and-release-in-one* alternative; use it for the\ntrivial path (small project, trunk-based, no separate verification gate). For\nanything with a review gate, **build once in preview, then `vercel promote`** so the\nreleased bytes equal the tested bytes.\n\n### 4. Keep the instant-rollback escape hatch ready\n\nBecause deployments are immutable, rollback is an alias re-point, not a revert\ncommit - it restores service in seconds while you debug at leisure:\n\n```bash\nvercel rollback                                   # roll back to the previous production deployment\nvercel rollback \u003Cgood-deployment-url-or-id>       # or target a specific known-good one\nvercel rollback status                            # confirm the alias moved\n```\n\nWhen you do not know *which* deployment broke, binary-search instead of guessing:\n\n```bash\nvercel bisect --good \u003Cgood-url> --bad \u003Cbad-url>                 # interactive\nvercel bisect --good \u003Cgood-url> --bad \u003Cbad-url> --run .\u002Ftest.sh # exit 0=good, non-0=bad, 125=skip\n```\n\nRoll back **first**, find root cause **second**. A green production beats a clever\ndiagnosis.\n\n### 5. Build once, deploy with --prebuilt (decouple build from deploy)\n\nWhen CI already runs `next build`, do not pay for the build twice. Build locally \u002F\nin CI, then upload the prebuilt output so Vercel skips its build step:\n\n```bash\nvercel pull --yes --environment=production   # fetch project settings + env into .vercel\u002F\nvercel build --prod                          # produces .vercel\u002Foutput (Build Output API)\nvercel deploy --prebuilt --prod              # upload + deploy that output, no remote build\n```\n\nMatch the `vercel build` target to the deploy target: `--prod` on both for\nproduction, neither for preview. `--prebuilt` is what makes CI deploys fast and\nmakes the artifact you tested the artifact you ship.\n\n### 6. Stage the rollout with Rolling Releases (canary)\n\nFor high-traffic or risky changes, shift production traffic gradually instead of a\n100% cutover. Configure stages once per project (CLI shown; the dashboard and REST\nAPI do the same):\n\n```bash\n# Automatic, time-based: 10% for 5m, 50% for 10m, then 100%\nvercel rolling-release configure --cfg '{\"enabled\":true,\"advancementType\":\"automatic\",\"stages\":[{\"targetPercentage\":10,\"duration\":5},{\"targetPercentage\":50,\"duration\":10},{\"targetPercentage\":100}]}'\n\n# Or manual approval between stages (you gate each advance)\nvercel rolling-release configure --enable --advancement-type=manual-approval --stage=10\n```\n\nThen deploy to production and **start** the rolling release so the new deployment\nbecomes a **canary** - it takes the first stage's traffic share while the previous\nproduction serves the rest:\n\n```bash\nvercel deploy --prod                              # deploy the new production candidate\nvercel rolling-release start --dpl \u003Ccanary-url>   # begin the staged rollout for that deployment\nvercel rolling-release fetch                      # current stage + traffic split\n```\n\nAdvance, complete, or abort by traffic-watching the canary. Every command targets\nthe specific deployment with `--dpl`:\n\n```bash\nvercel rolling-release approve --dpl \u003Ccanary-url> --currentStageIndex 0   # advance one stage (manual-approval)\nvercel rolling-release complete --dpl \u003Ccanary-url>                        # promote the canary to 100% production\nvercel rolling-release abort --dpl \u003Ccanary-url>                           # instant rollback: all traffic back to old prod\n```\n\nA rolling release is just a *gated* promotion - same immutable-deployment model,\nsame instant-undo. Aborting is step 4 applied to a canary. Watch the canary's error\nrate (`vercel rolling-release fetch` plus `vercel logs --environment production --level error --since 5m`) before advancing.\n\n### 7. Wire it into CI\n\nEncode steps 1-5 as a workflow so humans never hand-run a production deploy.\nPattern: **PR → preview deploy + checks; merge to main → prebuilt production\ndeploy**. See the runnable GitHub Actions template below. Store `VERCEL_TOKEN`,\n`VERCEL_ORG_ID`, `VERCEL_PROJECT_ID` as CI secrets;\n**runtime app env vars belong in Vercel and are pulled by `vercel pull` - manage\nthose with vercel-env-management, not in the workflow file.**\n\n## Quality bar\n\nA deploy pipeline is A+ only when all hold:\n\n- **Promote, don't rebuild.** Production runs a deployment that was first built and\n  verified as a preview (`vercel promote` \u002F `--prebuilt`), not a fresh `--prod` build\n  whose bytes nobody has seen.\n- **Every promotion is gated** by an inspect + real-route check + error-log scan on\n  the preview (step 2). No green checks, no promote.\n- **Rollback is one command and rehearsed.** The team knows `vercel rollback` and has\n  run it at least once on purpose, not for the first time during an incident.\n- **CI deploys are non-interactive:** `--yes` on prompts, target flags\n  (`--prod`\u002Fnone) consistent between `vercel build` and `vercel deploy`, secrets in the CI\n  store.\n- **Risky changes ship as a canary** (Rolling Releases) with a watched first stage,\n  not a 100% cutover.\n- **No stale runtime claims.** Functions default to Node.js 24 + Fluid Compute;\n  nothing in the pipeline pins Node 18 or routes new code onto Edge Functions.\n\n## Do NOT\n\n- Do NOT run a fresh `vercel deploy --prod` to \"release\" a change you already built and\n  tested in preview - promote the existing deployment so released bytes equal tested\n  bytes.\n- Do NOT debug a broken production before rolling back. Run `vercel rollback` to\n  restore service, *then* investigate.\n- Do NOT mismatch build\u002Fdeploy targets: `vercel build` (preview) + `vercel deploy --prebuilt --prod`\n  ships a preview build to production. Keep `--prod` on both or neither.\n- Do NOT bake runtime app secrets into the CI workflow or `vercel.json` - they live in\n  Vercel and arrive via `vercel pull`. That is vercel-env-management's job.\n- Do NOT target deprecated Edge Functions or pin Node 18 for new functions; default\n  to Fluid Compute on Node.js 24.\n- Do NOT hand-promote production from a laptop once CI exists - the workflow is the\n  source of truth; manual `promote`\u002F`rollback` is the break-glass path.\n- Do NOT treat a rolling release as fire-and-forget: watch the canary's error rate\n  before `approve`\u002F`complete`, and `abort` the moment it regresses.\n\n## Artifact: preflight gate script\n\nSelf-contained Bash. Save as `promote-gate.sh`, run as\n`.\u002Fpromote-gate.sh \u003Cpreview-url>`. It runs the step-2 checks and only prints the\nexact `vercel promote` command when the preview passes - so a human (or CI) never\npromotes an unproven deployment. Needs the Vercel CLI logged in (`vercel login`) and\na linked project. No other dependencies.\n\n```bash\n#!\u002Fusr\u002Fbin\u002Fenv bash\n# Gate a preview deployment before promotion. Usage: .\u002Fpromote-gate.sh \u003Cpreview-url> [health-path]\nset -euo pipefail\n\nURL=\"${1:?usage: .\u002Fpromote-gate.sh \u003Cpreview-url> [health-path]}\"\nHEALTH=\"${2:-\u002Fapi\u002Fhealth}\"\n\necho \"==> Inspecting $URL\"\nvercel inspect \"$URL\" >\u002Fdev\u002Fnull || { echo \"FAIL: deployment not inspectable\"; exit 1; }\n\necho \"==> Hitting $HEALTH (deploy-protection bypassed)\"\nif ! vercel curl \"$HEALTH\" --deployment \"$URL\" >\u002Fdev\u002Fnull 2>&1; then\n  echo \"FAIL: health route $HEALTH did not respond 2xx\"; exit 1\nfi\n\necho \"==> Scanning error logs\"\nERRS=\"$(vercel logs --deployment \"$URL\" --level error --limit 50 2>\u002Fdev\u002Fnull | grep -c . || true)\"\nif [ \"${ERRS:-0}\" -gt 0 ]; then\n  echo \"FAIL: $ERRS error log line(s) on the preview - fix before promoting\"; exit 1\nfi\n\necho \"==> PASS. Promote the SAME deployment (no rebuild) with:\"\necho \"    vercel promote $URL --yes && vercel promote status\"\n```\n\n### Worked example output\n\n```\n$ .\u002Fpromote-gate.sh https:\u002F\u002Facme-7gk2qz.vercel.app\n==> Inspecting https:\u002F\u002Facme-7gk2qz.vercel.app\n==> Hitting \u002Fapi\u002Fhealth (deploy-protection bypassed)\n==> Scanning error logs\n==> PASS. Promote the SAME deployment (no rebuild) with:\n    vercel promote https:\u002F\u002Facme-7gk2qz.vercel.app --yes && vercel promote status\n```\n\nRead it: the preview was inspectable, its health route returned 2xx, and there were\nno error-level logs - so the gate emits the promote command for the *exact* URL it\nverified. A failing health check or any error line exits non-zero and prints no\npromote command, so CI stops and nothing reaches production.\n\n## Template: CI deploy workflow (GitHub Actions)\n\nDrop in `.github\u002Fworkflows\u002Fdeploy.yml`. PRs get a verified preview; merges to `main`\nget a **prebuilt** production deploy (build once, deploy that output). Set\n`VERCEL_TOKEN`, `VERCEL_ORG_ID`, `VERCEL_PROJECT_ID` as repo secrets. Runtime app env vars\nare NOT here - they live in Vercel and are fetched by `vercel pull` (see\nvercel-env-management).\n\n```yaml\nname: Deploy\non:\n  push:\n    branches: [main]\n  pull_request:\n\nenv:\n  VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}\n  VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}\n\njobs:\n  preview:\n    if: github.event_name == 'pull_request'\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@v4\n      - uses: actions\u002Fsetup-node@v4\n        with: { node-version: 24 }          # Node.js 24 LTS - matches the runtime default\n      - run: npm i -g vercel@latest\n      - run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}\n      - run: vercel build --token=${{ secrets.VERCEL_TOKEN }}\n      - name: Deploy preview (prebuilt)\n        run: |\n          URL=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})\n          echo \"Preview: $URL\"\n          # gate before this preview is allowed to be promoted by the prod job\n          vercel inspect \"$URL\" --token=${{ secrets.VERCEL_TOKEN }}\n\n  production:\n    if: github.ref == 'refs\u002Fheads\u002Fmain' && github.event_name == 'push'\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@v4\n      - uses: actions\u002Fsetup-node@v4\n        with: { node-version: 24 }\n      - run: npm i -g vercel@latest\n      - run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}\n      - run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}     # build once\n      - name: Deploy production (prebuilt, same bytes)\n        run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}\n      # Rollback is intentionally a manual break-glass step:\n      #   vercel rollback --token=$VERCEL_TOKEN && vercel rollback status\n```\n\nFill in the secrets, commit, and the pipeline runs steps 1-5 on every change. Add a\nmanual-approval environment around the `production` job, or swap the prod deploy for a\nRolling Release (step 6), when a change needs a canary instead of a cutover.\n",{"name":5,"metadata":24,"description":7},{"title":25},"Vercel Deploy Pipeline","main","97a13607d669157a4a16d5ba79b77f208319f7b9","skills\u002Fvercel-deploy-pipeline",3,"https:\u002F\u002Fgithub.com\u002FSkillMedev\u002Fskills","https:\u002F\u002Fskillme.dev","https:\u002F\u002Fgithub.com\u002FSkillMedev","MCP-native catalog of Claude Agent Skills. Browse, recommend, install, and auto-apply skills in chat. Open source, every skill free and clonable on GitHub.","2026-10-14 03:19:31",{"source":8,"skillName":5,"commands":36,"prompt":46,"zipAvailable":47},[37,40,43],{"tool":38,"command":39},"npx","npx skills add SkillMedev\u002Fskills --skill vercel-deploy-pipeline",{"tool":41,"command":42},"bunx","bunx skills add SkillMedev\u002Fskills --skill vercel-deploy-pipeline",{"tool":44,"command":45},"pnpm","pnpm dlx skills add SkillMedev\u002Fskills --skill vercel-deploy-pipeline","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FSkillMedev\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fvercel-deploy-pipeline\u002FSKILL.md",true,[],[50,57,64,71,78,85],{"skillNo":51,"name":52,"nameZh":6,"description":53,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":54,"categories":55,"keywords":56,"publishedAt":19},"01M75271B256DF3FX2VG5VRYEE","zone-2-cardio-plan","Use when someone asks to build a steady-state cardio plan, train an aerobic base or Zone 2, structure easy or endurance weekly cardio, train by heart-rate zones, or improve resting heart rate, VO2, or endurance. Builds a heart-rate-zone aerobic training block with session structure, modality choice, and progression. General fitness guidance, not medical advice. Do NOT use to design a strength or lifting program (use Strength Training Plan), high-intensity interval conditioning, HIIT, or circuits (use Conditioning & HIIT Program), or a mobility\u002Fflexibility routine (use Mobility Routine).","https:\u002F\u002Fgithub.com\u002FSkillMedev\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fzone-2-cardio-plan\u002FSKILL.md",[],[],{"skillNo":58,"name":59,"nameZh":6,"description":60,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":61,"categories":62,"keywords":63,"publishedAt":19},"01M7526VP1QBBKYBE17S1WR86Y","youtube-script-writer","Writes retention-engineered long-form YouTube scripts on a hook\u002Fbody\u002Fpayoff architecture - a first-30-seconds hook that survives the retention cliff, a beat-sheet body with mini-hooks and bridges, timed pattern interrupts, and a payoff that over-delivers - with B-roll and editing cues marked inline. Use when someone says \"script my next video\", \"my retention graph dies at the start\", \"tighten this draft\", or \"outline a video on X\". Do NOT use for the 3-second opener of TikTok, Reels, or Shorts - use video-hook-writer instead; do NOT use for spoken voiceover synced to on-screen tutorial actions - use narration-script instead; do NOT use for a sales demo built on a buyer's discovery notes - use demo-script instead; do NOT use to design the thumbnail and title - use thumbnail-concept instead.","https:\u002F\u002Fgithub.com\u002FSkillMedev\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fyoutube-script-writer\u002FSKILL.md",[],[],{"skillNo":65,"name":66,"nameZh":6,"description":67,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":68,"categories":69,"keywords":70,"publishedAt":19},"01M7526P2T0WKMHDXS4Q58237T","win-back-campaign","Designs segmented win-back email sequences for dormant users - dormancy tiers, a three-beat sequence with a single proportional incentive, and a suppression rule - and measures success by re-activation, not opens. Use when someone says \"our users went quiet\", \"design a win-back campaign\", \"how do I re-engage lapsed customers\", \"should we email people who haven't logged in for months\", or lifecycle messaging has stopped landing with a lapsed segment. Do NOT use for recovering an unfinished checkout - use abandoned-cart-sequence instead. Do NOT use for diagnosing and fixing why active customers cancel - use churn-reduction instead. Do NOT use for building always-on onboarding or nurture flows - use email-drip-builder instead.","https:\u002F\u002Fgithub.com\u002FSkillMedev\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fwin-back-campaign\u002FSKILL.md",[],[],{"skillNo":72,"name":73,"nameZh":6,"description":74,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":75,"categories":76,"keywords":77,"publishedAt":19},"01M7526HF2RCDJ50P93WRZRHVV","wikipedia-style","Writes neutral, verifiable, encyclopedic prose following Wikipedia's core content policies and manual of style - NPOV, inline citations, notability-backed claims, and a strict ban on promotional language. Use when someone asks \"write this like a Wikipedia article\", \"draft a Wikipedia page for this company or person\", \"make this neutral and encyclopedic\", or \"why does my article draft keep getting rejected\". Do NOT use for persuasive or opinion writing - use op-ed-writer instead; for thesis-driven academic papers, use academic-essay; for verifying claims in existing text, use fact-checker.","https:\u002F\u002Fgithub.com\u002FSkillMedev\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fwikipedia-style\u002FSKILL.md",[],[],{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":19},"01M7526D43CTGRKGKNQ2GB0KVX","whitepapers","Structures and writes authoritative B2B whitepapers - a standalone executive summary, a data-sized problem statement, methodology, evidence-driven findings, recommendations, and a soft call to action - flagging every claim that needs a real citation. Use when a marketer asks \"write a whitepaper on this topic\", \"turn our research into a lead-gen asset\", \"make this credible enough for executives\", or a draft reads like a product pitch instead of analysis. Do NOT use for customer-story-driven proof - use case-study-builder instead; for policy audiences, use policy-brief.","https:\u002F\u002Fgithub.com\u002FSkillMedev\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fwhitepapers\u002FSKILL.md",[],[],{"skillNo":86,"name":87,"nameZh":6,"description":88,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":89,"categories":90,"keywords":91,"publishedAt":19},"01M75268423Y3K50SY5WC2NX2G","white-space-analysis","Finds unmet market gaps by ranking jobs-to-be-done on importance versus satisfaction, overlaying them against current solutions and workarounds, and validating that each gap is real, winnable, and worth winning. Use when someone asks \"where are the gaps in this market\", \"what's underserved here\", \"where should we play next\", or is hunting for product, feature, or market-entry opportunities. Do NOT use for profiling competitors and building battle cards - use competitive-intelligence instead; for putting a dollar figure on an identified opportunity - use market-sizing instead; for extracting jobs-to-be-done from raw customer interviews - use jtbd-extractor instead.","https:\u002F\u002Fgithub.com\u002FSkillMedev\u002Fskills\u002Fblob\u002Fmain\u002Fskills\u002Fwhite-space-analysis\u002FSKILL.md",[],[]]