CI/CD Pipeline Automation: From Code to Production in Minutes

15. MÀrz 2025 · CodeMatic Team

CI/CD Pipeline Automation

Continuous Integration and Continuous Deployment (CI/CD) pipelines automate the entire software delivery process, from code commit to production deployment. This guide covers building robust, automated pipelines that improve development velocity and code quality.

What is CI/CD?

CI/CD automates the software delivery process:

  • Continuous Integration (CI): Automatically test and build code on every commit
  • Continuous Deployment (CD): Automatically deploy to production after successful tests
  • Benefits: Faster releases, fewer bugs, consistent deployments

GitHub Actions CI/CD

Complete Pipeline Example

# .github/workflows/deploy.yml
name: CI/CD Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run linter
        run: npm run lint
      
      - name: Run tests
        run: npm test
      
      - name: Run E2E tests
        run: npm run test:e2e
      
      - name: Upload coverage
        uses: codecov/codecov-action@v3
        with:
          files: ./coverage/lcov.info

  build:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Build application
        run: npm run build
        env:
          NEXT_PUBLIC_API_URL: ${{ secrets.API_URL }}
      
      - name: Build Docker image
        run: docker build -t myapp:${{ github.sha }} .
      
      - name: Push to registry
        run: |
          echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
          docker push myapp:${{ github.sha }}

  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - name: Deploy to production
        uses: azure/webapps-deploy@v2
        with:
          app-name: 'myapp'
          publish-profile: ${{ secrets.AZURE_PUBLISH_PROFILE }}
          package: ./dist

GitLab CI/CD

# .gitlab-ci.yml
stages:
  - test
  - build
  - deploy

variables:
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: "/certs"

test:
  stage: test
  image: node:20
  script:
    - npm ci
    - npm run lint
    - npm test
    - npm run test:e2e
  coverage: '/Lines\s*:\s*\d+\.\d+%/'

build:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  only:
    - main
    - develop

deploy_production:
  stage: deploy
  image: alpine:latest
  script:
    - apk add --no-cache curl
    - curl -X POST $DEPLOY_WEBHOOK_URL
  environment:
    name: production
    url: https://myapp.com
  only:
    - main
  when: manual

Pipeline Stages

1. Code Quality Checks

  • Linting (ESLint, Prettier)
  • Type checking (TypeScript)
  • Code formatting validation
  • Security scanning (Snyk, OWASP)

2. Testing

  • Unit tests
  • Integration tests
  • E2E tests (Playwright, Cypress)
  • Performance tests
  • Coverage reporting

3. Building

  • Compile/transpile code
  • Bundle assets
  • Optimize images
  • Generate production builds
  • Create Docker images

4. Deployment

  • Deploy to staging
  • Run smoke tests
  • Deploy to production
  • Health checks
  • Rollback on failure

Advanced CI/CD Patterns

Parallel Execution

jobs:
  test:
    strategy:
      matrix:
        node-version: [18, 20]
        os: [ubuntu-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm test

Conditional Deployment

deploy:
  if: |
    github.ref == 'refs/heads/main' &&
    github.event_name == 'push' &&
    !contains(github.event.head_commit.message, '[skip ci]')
  steps:
    - name: Deploy
      run: ./deploy.sh

Docker in CI/CD

# Multi-stage Dockerfile for CI/CD
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV production
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static

EXPOSE 3000
CMD ["node", "server.js"]

# Build and push in CI
- name: Build and push
  run: |
    docker buildx create --use
    docker buildx build --platform linux/amd64,linux/arm64       -t myapp:${{ github.sha }}       -t myapp:latest       --push .

Environment Management

  • Use secrets for sensitive data
  • Separate configs for dev/staging/prod
  • Feature flags for gradual rollouts
  • Environment-specific variables

Best Practices

  • Fail fast - stop pipeline on first error
  • Cache dependencies to speed up builds
  • Run tests in parallel when possible
  • Use matrix builds for multiple versions
  • Implement proper secrets management
  • Add deployment approvals for production
  • Monitor pipeline performance
  • Keep pipelines idempotent

Real-World Example

Complete CI/CD pipeline for a Next.js application:

  • Lint and type check: 2 minutes
  • Run tests (parallel): 5 minutes
  • Build application: 3 minutes
  • Build Docker image: 4 minutes
  • Deploy to staging: 2 minutes
  • Smoke tests: 1 minute
  • Total: ~17 minutes from commit to staging
  • Result: 10x faster releases, 90% fewer deployment errors

Conclusion

CI/CD pipelines are essential for modern software development. Automate testing, building, and deployment to improve code quality, reduce manual errors, and accelerate delivery. Start with basic pipelines and gradually add more automation as your needs grow.