CI/CD pipelines that save your future self.
Every hour spent setting up a proper CI/CD pipeline saves roughly forty hours of manual testing, broken deployments, and "it works on my machine" conversations over the life of a project. Here's how I set mine up.
I've deployed broken code to production exactly twice. Both times, the root cause was the same: I skipped the process because I was in a hurry. A quick hotfix, a "this is too small to break anything" change, a deploy straight from my laptop. Both times cost me a weekend. The pipeline I run today exists because of those weekends.
Why GitHub Actions over everything else
There are dozens of CI/CD tools, and most of them are perfectly fine. I use GitHub Actions for a simple, pragmatic reason: it lives where my code already lives. Free for public repos, generous for private ones. The configuration is YAML-based and version-controlled alongside your code — no separate dashboards, no third-party accounts to manage.
The GitHub Marketplace has thousands of pre-built actions for nearly any task you can think of. And the deep GitHub integration — PR checks, deployment statuses, environment protection rules — means your pipeline and your workflow are a single thing, not two systems you're stitching together. For most web projects, it's the pragmatic choice.
The four-stage pipeline
Every pipeline I set up follows the same four stages, in order:
- Lint — ESLint, Prettier. Catch style issues and formatting inconsistencies before anyone has to think about them in code review.
- Type check — The TypeScript compiler. Catch type errors that would otherwise surface as runtime bugs in production.
- Test — Unit and integration tests. Catch logic errors, regressions, and broken contracts between modules.
- Build — A full production build. Catch build errors, missing imports, and environment-specific issues.
If any stage fails, the PR can't merge. Period. Each stage runs in parallel where possible, so the total pipeline time is the duration of the slowest stage, not the sum of all four.
Preview deployments for every PR
This is the single highest-leverage practice I've adopted. Every pull request gets deployed to a unique preview URL — whether you're using Vercel, Netlify, or a custom solution. Reviewers can see the actual change rendered in a browser, not just the diff in GitHub.
Product managers can approve visual changes. Designers can catch spacing issues. QA can test edge cases on a real environment. This single practice eliminates 80% of "that's not what I expected" conversations. The cost is nearly zero. The return is enormous.
Environment variables and secrets
Never commit secrets. This sounds obvious, but I've reviewed enough repos to
know it isn't. Use GitHub Secrets for API keys, tokens, and credentials.
Separate your environments clearly: dev, staging,
production.
Use environment protection rules for production deployments. Require manual approval for production releases — an extra click that forces a human to consciously say "yes, this should go live." It's a small friction that prevents large disasters.
Caching and speed
Cache node_modules between runs. Cache your Next.js build output.
Use actions/cache or the built-in npm caching that GitHub Actions
provides. These are small configuration changes that can cut your pipeline time
in half.
A 10-minute pipeline that could be 3 minutes is a tax on every PR. It's a tax on every developer, every day. Fast pipelines get used. Slow pipelines get bypassed. And a bypassed pipeline is worse than no pipeline at all, because it creates a false sense of security.
The CI pipeline is the last honest reviewer on your team. It doesn't get tired, it doesn't skip steps, and it doesn't approve things out of politeness.
Closing thought
A good CI/CD pipeline isn't infrastructure — it's culture. It encodes your team's quality standards into an automated process that runs 24/7. It doesn't take days off. It doesn't have a bad morning. It applies the same rigor to a one-line typo fix and a thousand-line refactor.
Build it once, maintain it quarterly, and trust it always. The hour you spend today will pay you back forty times over. And more importantly, it'll save your future self from a weekend they'd rather spend doing literally anything else.