CI/CD Pipeline Design: From Zero to Production Deployment
What CI/CD Actually Means
Continuous Integration (CI)
Every code change triggers automated tests. If tests fail, the change is rejected. The goal is to catch bugs immediately, not days later.
Continuous Delivery (CD)
Every change that passes CI is automatically deployed to a staging environment and can be deployed to production with one click.
Continuous Deployment
Every change that passes CI is automatically deployed to production. No manual approval step.
The Pipeline Stages
1. Lint and Format
Catch style issues and potential errors before running expensive tests.
- name: Lint
run: npm run lint
- name: Type Check
run: npm run type-check
2. Unit Tests
Fast, isolated tests that verify individual functions and components.
- name: Unit Tests
run: npm run test -- --coverage
3. Integration Tests
Test interactions between components, database queries, and API endpoints.
4. Build
Compile, bundle, and optimize the application for production.
- name: Build
run: npm run build
5. Deploy to Staging
Deploy to a staging environment that mirrors production.
6. E2E Tests (on Staging)
Run Playwright or Cypress tests against the staging deployment to verify the full user flow.
7. Deploy to Production
If all checks pass, deploy to production.
GitHub Actions Example
name: CI/CD Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run lint
- run: npm run test -- --coverage
- run: npm run build
deploy:
needs: test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build
- name: Deploy
run: npx wrangler pages deploy dist/
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CF_TOKEN }}
Key Principles
- Fast feedback: The pipeline should complete in under 10 minutes. Slow pipelines get ignored.
- Fail fast: Run the cheapest checks first (lint, then unit tests, then integration).
- Reproducible: Use locked dependency versions and consistent environments.
- Secure: Never hardcode secrets. Use environment variables and secret managers.