CI/CD — Continuous Integration and Deployment

Continuous integration pipelines, automated testing, and deployment strategies: blue-green, canary, and rolling updates.

What is CI/CD?

CI/CD (Continuous Integration / Continuous Delivery or Deployment) is a set of practices that automate the process of moving code from the repository to production.

  • CI (Continuous Integration): every code change is integrated frequently, built, and tested automatically
  • CD (Continuous Delivery): code that passes CI is always ready to be deployed to production
  • CD (Continuous Deployment): code is deployed automatically to production without manual intervention

CI/CD Pipeline

A pipeline is a sequence of automated stages that code goes through from commit to production.

Typical stages

Commit → Build → Test → Analysis → Artifact → Deploy Staging → Deploy Production
  1. Build: compile the code, generate artifacts
  2. Unit tests: run fast tests that validate the logic
  3. Integration tests: verify that components work together
  4. Static analysis: linting, type checking, security analysis
  5. Artifact build: create a Docker image, package, etc.
  6. Deploy to staging: deploy automatically for final testing
  7. Deploy to production: deploy using the chosen strategy

Example with GitHub Actions

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
      - run: npm ci
      - run: npm run lint
      - run: npm run test
      - run: npm run build

  deploy-staging:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build Docker image
        run: docker build -t my-app:${{ github.sha }} .
      - name: Push to registry
        run: docker push my-app:${{ github.sha }}
      - name: Deploy to staging
        run: kubectl set image deployment/my-app my-app=my-app:${{ github.sha }} -n staging

Automated testing in CI

Testing is the backbone of CI. Without reliable tests, automation is meaningless.

The testing pyramid in CI

  • Unit tests (many, fast): validate individual functions and modules
  • Integration tests (moderate): validate communication between components
  • End-to-end tests (few, slow): validate complete user flows

Best practices

  • Tests must be deterministic: the same code always produces the same result
  • Tests must be fast: a slow pipeline discourages frequent integration
  • Tests must be independent: not dependent on execution order or shared state
  • Use parallelization to reduce the total pipeline time

Deployment strategies

Rolling update

The default strategy in Kubernetes. It gradually replaces the old instances with new ones.

  • Advantage: requires no additional infrastructure
  • Disadvantage: during the update, two versions coexist
  • Rollback: automatic if health checks fail
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0

Blue-Green deployment

Maintains two identical environments: Blue (current) and Green (new). Traffic is redirected from Blue to Green once Green is ready.

  • Advantage: instant rollback (switch back to Blue)
  • Disadvantage: requires double the infrastructure during deployment
  • Ideal for: large changes or database migrations

Canary deployment

Deploys the new version to a small percentage of users first. If everything goes well, it is gradually increased up to 100%.

  • Advantage: minimal risk, early detection of problems
  • Disadvantage: more complex to implement and monitor
  • Ideal for: risky changes or experimental features
Phase 1: 5% of traffic → new version
Phase 2: 25% of traffic → new version
Phase 3: 50% of traffic → new version
Phase 4: 100% of traffic → new version

Feature flags

Not a deployment strategy per se, but it complements the ones above. It allows you to enable or disable features without redeploying.

  • The new code is deployed but disabled by default
  • It is enabled gradually for specific users
  • If there are problems, it is disabled without a rollback

CI/CD best practices

  1. Make small, frequent commits: makes it easier to detect errors
  2. The pipeline must be fast: ideally under 10 minutes for CI
  3. Never skip the pipeline: every change goes through CI, no exceptions
  4. Immutable artifacts: the same artifact is promoted across environments
  5. Monitor deployments: automatic alerts if something fails post-deploy
  6. Automate rollbacks: if metrics degrade, revert automatically

Summary

CI/CD automates the path from code to production. Continuous integration ensures that every change is validated automatically, while deployment strategies (rolling, blue-green, canary) allow changes to reach production with confidence and minimal risk.