Sets up and audits a battle-tested GitHub Actions pipeline โ with the hard lessons already baked in.
# Install the skill with one command npx nextjs-cicd-skill # Copies SKILL.md to ~/.claude/skills/nextjs-cicd/ # Safe to re-run โ skips if already installed
// 1. Add to ~/.claude/settings.json { "extraKnownMarketplaces": { "nextjs-cicd": { "source": { "source": "github", "repo": "liveedevteam/nextjs-cicd-skill" } } } } # 2. Install via Claude Code /plugin install nextjs-cicd@nextjs-cicd
# In any Next.js project conversation, type: /nextjs-cicd # Or just describe what you need โ Claude activates # the skill automatically for CI/CD questions: "Set up CI/CD for my Next.js project" "My deploy ran before CI finished" "Add Playwright E2E tests" "Knip is reporting false positives"
CI runs first. Deploy fires only after every gate passes.
Install mode copies files. Audit mode diagnoses problems.
CI gate, tag-based deploy (dev/uat/prd), reusable Vercel workflow, composite Node setup action.
jsdom environment, @/ alias, jest-dom setup โ ready to run with npm test.
Chromium only, 1 retry on CI, auto dev-server locally, trace + screenshot artifacts on failure.
Generic Next.js baseline with both src/app/ and app/ path variants and false-positive fix guide.
Zod schema โ Claude scans your codebase for process.env.* before writing it.
Symptom โ fix table for 8 common pipeline failures. No more guessing why the deploy ran twice.
Tell Claude what's wrong โ the skill maps symptoms to root causes.
| Symptom | Root cause identified |
|---|---|
| Deploy ran before CI finished | Wrong trigger โ push instead of workflow_run |
| Deploy ran twice | Unconditional cancel-in-progress: true |
| Knip false positives | Missing entry points in knip.config.ts |
| Semgrep blocking merges | continue-on-error missing before baseline triage |
| Build fails on CI only | Missing build-time env var in lint-and-build job |
| E2E runs on every push | Missing if: github.event_name == 'pull_request' |
| Deploy never triggers | workflows: [CI] name doesn't match ci.yml exactly |
| Shell injection warning | ${{ }} expression in run: step instead of env: |
Things that take hours to debug without prior experience.
${{ }} expressions never go in run: steps โ always moved to env: blocks.
Auto-detects npm, pnpm, or Yarn (classic) from packageManager in package.json or the lockfile present, and generates the matching frozen-lockfile install command. For npm specifically: plain npm ci drops optional deps on Linux runners, so --include=optional is used to preserve lockfile determinism and fix cross-platform native binding failures.
Deploy fires only after CI concludes with success โ never triggered directly by a tag push.
cancel-in-progress is conditional โ only PR previews can be cancelled, never environment deploys.
Every workflow declares a permissions: block. Without it, GITHUB_TOKEN inherits repo-wide write access.
The workflows: [CI] string must match the name: field in ci.yml exactly โ a mismatch silently never triggers the deploy.
vercel pull --environment=production writes to .vercel/.env.production.local, not .env.local. Both must be loaded in validate-env.ts.
Deploys use plain vercel deploy instead of vercel pull โ vercel build โ vercel deploy --prebuilt. Vercel teams with "Sensitive" env vars can't decrypt them via CLI pull/build on external CI โ remote build sidesteps this entirely.
Every Vercel CLI step needs all three IDs as env vars, not just VERCEL_TOKEN. Missing org/project IDs don't error โ the CLI silently resolves or creates a stray project instead.