Isaac.

devops

Continuous Integration Pipelines

Build automated CI/CD pipelines for reliable deployments.

By Emem IsaacJanuary 5, 20223 min read
#ci/cd#github actions#gitlab ci#automation#deployment
Share:

A Simple Analogy

CI/CD pipelines are like assembly line quality control. Every change is automatically tested and deployed through a series of checkpoints.


Why CI/CD?

  • Automation: Reduce manual steps
  • Quality: Catch issues early
  • Speed: Deploy frequently
  • Consistency: Same process every time
  • Confidence: Safe deployments

GitHub Actions Pipeline

name: CI/CD Pipeline

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

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18.x, 20.x]
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'
    
    - name: Install dependencies
      run: npm ci
    
    - name: Run linter
      run: npm run lint
    
    - name: Run tests
      run: npm run test:coverage
    
    - name: Upload coverage
      uses: codecov/codecov-action@v3
      with:
        file: ./coverage/coverage-final.json

  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Deploy to production
      run: |
        npm run build
        npm run deploy:prod
      env:
        DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
        API_URL: ${{ secrets.PROD_API_URL }}

.NET Pipeline

name: .NET CI/CD

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

jobs:
  build-test:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup .NET
      uses: actions/setup-dotnet@v3
      with:
        dotnet-version: '8.0.x'
    
    - name: Restore dependencies
      run: dotnet restore
    
    - name: Build
      run: dotnet build --configuration Release --no-restore
    
    - name: Run tests
      run: dotnet test --configuration Release --no-build --verbosity normal
    
    - name: Publish
      run: dotnet publish -c Release -o ./publish
    
    - name: Upload artifacts
      uses: actions/upload-artifact@v3
      with:
        name: app-release
        path: ./publish

  deploy-docker:
    needs: build-test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    
    steps:
    - uses: actions/checkout@v3
    
    - 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 tag myapp:${{ github.sha }} myregistry/myapp:latest
        docker push myregistry/myapp:latest

GitLab CI Pipeline

stages:
  - build
  - test
  - deploy

variables:
  DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  DOCKER_LATEST: $CI_REGISTRY_IMAGE:latest

build:
  stage: build
  image: node:20
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/
  cache:
    paths:
      - node_modules/

test:
  stage: test
  image: node:20
  script:
    - npm ci
    - npm run lint
    - npm run test:coverage
  coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml

deploy_staging:
  stage: deploy
  image: alpine:latest
  script:
    - apk add --no-cache curl
    - curl -X POST $DEPLOY_WEBHOOK_STAGING
  environment:
    name: staging
  only:
    - develop

deploy_production:
  stage: deploy
  image: alpine:latest
  script:
    - apk add --no-cache curl
    - curl -X POST $DEPLOY_WEBHOOK_PROD
  environment:
    name: production
  only:
    - main
  when: manual

Quality Gates

# GitHub Actions with quality gates
- name: SonarQube scan
  uses: SonarSource/sonarcloud-github-action@master
  with:
    args: >
      -Dsonar.projectKey=myproject
      -Dsonar.organization=myorg

- name: Check test coverage
  run: |
    coverage=$(cat coverage/coverage-summary.json | jq '.total.lines.pct')
    if (( $(echo "$coverage < 80" | bc -l) )); then
      echo "Coverage below 80%: $coverage%"
      exit 1
    fi

Best Practices

  1. Test first: Fail fast
  2. Parallelize: Run tests in parallel
  3. Cache dependencies: Faster builds
  4. Gate production: Manual approval for production
  5. Monitor deployments: Track metrics

Related Concepts

  • Infrastructure as Code
  • Container deployment
  • Health checks
  • Rollback strategies

Summary

CI/CD pipelines automate testing and deployment, enabling frequent, confident releases. Use GitHub Actions or GitLab CI to define reproducible build processes.

Share:

Written by Emem Isaac

Expert Software Engineer with 15+ years of experience building scalable enterprise applications. Specialized in ASP.NET Core, Azure, Docker, and modern web development. Passionate about sharing knowledge and helping developers grow.

Ready to Build Something Amazing?

Let's discuss your project and explore how my expertise can help you achieve your goals. Free consultation available.

💼 Trusted by 50+ companies worldwide | ⚡ Average response time: 24 hours