plugins/frontend-toolkit/skills/cicd-pipeline/SKILL.md
Set up GitHub Actions for Next.js with parallel type-check / lint / test / build, dependency + Next.js caching, concurrency cancellation, Vercel Preview, branch protection, and least-privilege CI security. Use at project start, when manual deploys cause errors, or when the team grows. Coordinates with test-strategy for what gets gated and developer-experience for local pre-commit gating.
npx skillsauth add jaykim88/claude-ai-engineering cicd-pipelineInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Every PR runs type-check, lint, test, and build automatically. Failures block merge. Pipeline completes in under 10 minutes (ideally under 3) so developers don't abandon discipline.
Universal concept, platform-bound Procedure — the pipeline structure (parallel type-check / lint / test / build, dependency + framework-output caching, branch protection, preview deploys) applies to any stack. But the Procedure below is written concretely for GitHub Actions + Vercel; the job-DAG and caching concepts port to GitLab CI / CircleCI / others (see Other stacks), where the YAML and platform UI differ.
Define the workflow stages (parallel where possible)
on: pull_request + push to main; add paths-ignore for docs-only changes so a README edit doesn't run the full buildconcurrency: { group: ${{ github.workflow }}-${{ github.ref }}, cancel-in-progress: true } — a new push to a PR cancels the stale in-progress run (saves minutes + CI cost).nvmrc / engines)tsc --noEmiteslint .vitest runnext buildConfigure caching
actions/setup-node@v4 with cache: 'npm'actions/cache@v4 for ~/.npm and .next/cacherestore-keys fallback is what delivers the warm-cache speedup):
- uses: actions/cache@v4
with:
path: |
~/.npm
${{ github.workspace }}/.next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-
Vercel Preview integration
Branch protection on main
Environment variable management
developer-experience skill)5b. Harden the CI itself (it runs with your secrets)
permissions: contents: read at the workflow top, widen per-job only as needed — the default GITHUB_TOKEN is over-permissioned@v4 can be re-pointed to malicious code); let Dependabot bump thempull_request (the safe default) has no secret access; reach for pull_request_target only with extreme care (it runs with secrets against the PR's code)security-audit)Optional integrations
accessibility-audit)observability-setup)continue-on-error), then flip it to required once it's stableVerify pipeline performance (validation loop)
next build or npm install), expand cache scope or parallelize further, and re-trigger; loop until ≤ 10 minrestore-keys fallback and re-measurecancel-in-progress)permissions:; third-party actions pinned to SHA; no secrets exposed to fork PRs.github/workflows/ci.yml with parallel jobs (type-check / lint / test / build) + caching blockmain requiring all CI status checks to pass + PR review ≥ 1chore(ci): <change> for workflow updates; chore(infra): <change> for branch protection / env configactions/checkout + actions/setup-node + actions/cache, each pinned to a commit SHA (Dependabot github-actions ecosystem bumps them)concurrency: { group: ${{ github.workflow }}-${{ github.ref }}, cancel-in-progress: true }permissions: contents: read at the top; widen per-job as needed${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.{js,jsx,ts,tsx}') }} + restore-keys fallback.nuxt/cache and node_modules/.cache/nuxt; deploy preview via Vercel/Netlify (both auto-detect Nuxt).svelte-kit/output; deploy preview via Vercel/Netlify/Cloudflare Pages (built-in adapters).angular/cache; deploy preview via Firebase Hosting or Verceltest-strategy — defines what gets gated in CI (and keeps required checks non-flaky)accessibility-audit — axe-core wired here as a gatesecurity-audit — least-privilege tokens, SHA-pinned actions, npm audit as a CI gateobservability-setup — Sentry release tagging coordinated with CIdeveloper-experience — husky + lint-staged complement CI by gating locally~/.npm + .next/cache keyed on package-lock.json + source hashes — this is the single biggest pipeline speedup. Run type-check / lint / test as parallel jobs (not sequential steps) to hit sub-3-minute warm pipelines. The next build step is usually the long pole; its caching benefit compounds across PRs. Two senior must-haves often missed: concurrency: cancel-in-progress (kill stale runs on a new push) and treating the workflow as a security boundary — least-privilege permissions:, SHA-pinned actions, and no secrets for fork PRs.development
Audit and optimize third-party scripts — analytics, tag managers, chat widgets, embeds — with the right loading strategy, performance budget, facades, and CSP/consent controls. Use when adding a script, when TBT/INP regress, when a GDPR/CCPA consent requirement arises, or before shipping. Not for first-party bundle size (use bundle-optimization) or broad Core Web Vitals diagnosis (use rendering-performance).
development
Apply the Testing Trophy (mostly integration tests with RTL + MSW, sparing E2E with Playwright) and set coverage thresholds. Use before new feature work, after bug fixes, when CI coverage falls below target, or when tests are flaky or break on every refactor. Not for wiring coverage gates + Playwright into the GitHub Actions matrix (use cicd-pipeline) or auditing WCAG a11y compliance (use accessibility-audit).
development
Inventory and prioritize technical debt — TODO/FIXME/HACK, any usage, deprecated APIs, untested logic — with impact × effort matrix. Use at quarter start, before a refactoring sprint, when a new teammate joins, or when feature velocity slows. Not for actually paying down debt (use code-refactoring) or recording a migration approach (use decision-records) — this only inventories and prioritizes.
development
Decision framework for choosing the right state location — URL, server cache, local component, or shared/global store. Use when state-sync bugs appear, prop drilling gets deep (3+ levels), filters/tabs lose state on reload, or quarterly review. Not for form state specifically (use form-ux) or when the state is actually server data (use api-caching-optimization).