Skip to content

CI/CD Patterns


CI/CD Overview

CI/CD Pipeline Overview


GitHub Actions

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

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

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up JDK
        uses: actions/setup-java@v4
        with:
          java-version: '21'
          distribution: 'temurin'
          cache: 'maven'

      - name: Run tests
        run: mvn test

      - name: Upload coverage
        uses: codecov/codecov-action@v3

  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run linter
        run: mvn spotless:check

  security-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run Trivy
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: 'fs'
          severity: 'CRITICAL,HIGH'

  build:
    needs: [test, lint, security-scan]
    runs-on: ubuntu-latest
    outputs:
      image-tag: ${{ steps.meta.outputs.tags }}
    steps:
      - uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=sha,prefix=
            type=ref,event=branch
            type=semver,pattern={{version}}

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

  deploy-staging:
    needs: build
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - name: Deploy to staging
        run: |
          kubectl set image deployment/app \
            app=${{ needs.build.outputs.image-tag }}

      - name: Run smoke tests
        run: ./scripts/smoke-test.sh

  deploy-production:
    needs: deploy-staging
    runs-on: ubuntu-latest
    environment: production
    steps:
      - name: Deploy to production
        run: |
          kubectl set image deployment/app \
            app=${{ needs.build.outputs.image-tag }}

Deployment Strategies

Blue-Green Deployment

Blue-Green Deployment

Canary Deployment

Canary Deployment

Rolling Deployment

Rolling Deployment


Feature Flags

// Feature flag service
public class FeatureFlagService {

    private final FeatureFlagClient client;

    public boolean isEnabled(String flag, User user) {
        return client.evaluate(flag, user.getId(), user.getAttributes());
    }
}

// Usage in code
public class CheckoutService {

    private final FeatureFlagService featureFlags;

    public CheckoutResult checkout(Cart cart, User user) {
        if (featureFlags.isEnabled("new-payment-flow", user)) {
            return newPaymentFlow(cart, user);
        }
        return legacyPaymentFlow(cart, user);
    }
}

// Gradual rollout configuration
{
  "flag": "new-payment-flow",
  "enabled": true,
  "rules": [
    {
      "percentage": 10,
      "variants": {
        "on": 10,
        "off": 90
      }
    }
  ],
  "targeting": {
    "beta_users": true,
    "country": ["US", "CA"]
  }
}

Feature Flag Best Practices

Feature Flag Best Practices


GitOps

GitOps Flow

ArgoCD Application

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/org/gitops-repo
    targetRevision: HEAD
    path: apps/my-app/overlays/production
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

Pipeline Best Practices

CI/CD Best Practices


Trunk-Based Development

Trunk-Based Development


Common Interview Questions

  1. Blue-green vs Canary?
  2. Blue-green: Instant switch, full environment
  3. Canary: Gradual rollout, percentage-based

  4. What is GitOps?

  5. Git as source of truth
  6. Declarative, automated deployment
  7. Pull-based (ArgoCD, Flux)

  8. Feature flags benefits?

  9. Decouple deploy from release
  10. Gradual rollout, A/B testing
  11. Quick rollback

  12. CI vs CD?

  13. CI: Build, test, integrate
  14. CD: Automated deployment (Delivery = manual gate, Deployment = fully automated)

  15. How to speed up pipelines?

  16. Parallelization
  17. Caching
  18. Incremental builds
  19. Smaller test suites