CI/CD (Continuous Integration/Continuous Deployment)

Contents

CI/CD Fundamentals

Core Concepts

  • Continuous Integration
  • Continuous Delivery
  • Continuous Deployment
  • Pipeline Stages
  • Automation

Pipeline Stages:

  1. Source Code Management
  2. Build
  3. Test
  4. Package
  5. Deploy
  6. Monitor

Jenkins

Pipeline Configuration

// Jenkinsfile pipeline { agent any stages { stage('Build') { steps { sh 'npm install' sh 'npm run build' } } stage('Test') { steps { sh 'npm test' } } stage('Deploy') { steps { sh './deploy.sh' } } } post { always { cleanWs() } success { echo 'Pipeline completed successfully!' } failure { echo 'Pipeline failed!' } } }

Pipeline Script

// Scripted Pipeline node { try { stage('Checkout') { checkout scm } stage('Build') { docker.image('node:14').inside { sh 'npm install' sh 'npm run build' } } stage('Test') { parallel unit: { sh 'npm run test:unit' }, integration: { sh 'npm run test:integration' } } } catch (e) { throw e } finally { cleanWs() } }

GitLab CI/CD

Pipeline Configuration

# .gitlab-ci.yml stages: - build - test - deploy build: stage: build image: node:14 script: - npm install - npm run build artifacts: paths: - dist/ test: stage: test image: node:14 script: - npm install - npm test coverage: '/Coverage: \d+.\d+%/' deploy: stage: deploy script: - apt-get update -qy - apt-get install -y ruby-dev - gem install dpl - dpl --provider=heroku --app=my-app --api-key=$HEROKU_API_KEY

Environment Configuration

# Environment-specific deployment deploy_staging: stage: deploy script: - ./deploy.sh staging environment: name: staging only: - develop deploy_production: stage: deploy script: - ./deploy.sh production environment: name: production when: manual only: - main

GitHub Actions

Workflow Configuration

# .github/workflows/main.yml name: CI/CD Pipeline on: push: branches: [ main ] pull_request: branches: [ main ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Setup Node.js uses: actions/setup-node@v2 with: node-version: '14' - name: Install Dependencies run: npm install - name: Run Tests run: npm test - name: Build run: npm run build

Deployment Workflow

name: Deploy to Production on: release: types: [published] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Deploy to Heroku uses: akhileshns/heroku-deploy@v3.12.12 with: heroku_api_key: ${{secrets.HEROKU_API_KEY}} heroku_app_name: "my-app" heroku_email: "user@example.com"

Automated Testing

Test Configuration

// Jest Configuration module.exports = { preset: 'ts-jest', testEnvironment: 'node', coverageThreshold: { global: { branches: 80, functions: 80, lines: 80, statements: 80 } }, collectCoverageFrom: [ 'src/**/*.{js,ts}', '!src/**/*.d.ts' ] }

Integration Tests

describe('API Integration Tests', () => { beforeAll(async () => { await startTestServer(); }); afterAll(async () => { await stopTestServer(); }); test('should create new user', async () => { const response = await request(app) .post('/api/users') .send({ name: 'Test User', email: 'test@example.com' }); expect(response.status).toBe(201); expect(response.body).toHaveProperty('id'); }); });

Deployment Strategies

Rolling Deployment

# Kubernetes Rolling Update apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: replicas: 3 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 template: spec: containers: - name: my-app image: my-app:1.0

Blue-Green Deployment

# Blue-Green with Nginx upstream backend { server blue.example.com; } server { listen 80; server_name example.com; location / { proxy_pass http://backend; } }

Pipeline Monitoring

Metrics Collection

  • Build Success Rate
  • Test Coverage
  • Deployment Frequency
  • Lead Time
  • Mean Time to Recovery

Alerting

# Prometheus Alert Rule groups: - name: pipeline rules: - alert: PipelineFailure expr: pipeline_status{status="failed"} > 0 for: 5m labels: severity: critical annotations: summary: "Pipeline failure detected" description: "Pipeline has failed for {{ $labels.job }}"