Skip to content

CI/CD (Continuous Integration/Continuous Deployment) para .NET Senior

📋 Visão Geral

CI/CD é um conjunto de práticas e ferramentas que automatizam o processo de integração, teste e deploy de código. Permite entregas mais rápidas, seguras e confiáveis.

🏗️ Conceitos Fundamentais

Continuous Integration (CI)

O que é: Prática de integrar código frequentemente em um repositório compartilhado.

Benefícios:

  • Detecção precoce de bugs
  • Redução de conflitos de merge
  • Feedback rápido para desenvolvedores
  • Qualidade de código consistente

Continuous Deployment (CD)

O que é: Automatização do processo de deploy para produção.

Benefícios:

  • Deploy mais rápido e confiável
  • Redução de erros humanos
  • Rollback rápido
  • Entrega contínua de valor

Continuous Delivery

O que é: Capacidade de entregar software em qualquer momento.

Características:

  • Código sempre pronto para produção
  • Deploy manual para produção
  • Pipeline automatizado até staging

🛠️ Ferramentas de CI/CD

1. Jenkins

O que é: Servidor de automação open-source para CI/CD.

Características:

  • Plugin-based: Extensível via plugins
  • Pipeline as Code: Jenkinsfile
  • Multi-platform: Suporte a múltiplas plataformas
  • Distributed: Execução distribuída
  • Open-source: Gratuito e customizável

Vantagens:

  • Muito flexível e customizável
  • Grande ecossistema de plugins
  • Suporte a múltiplas tecnologias
  • Comunidade ativa

Desvantagens:

  • Complexidade de configuração
  • Necessidade de manutenção de servidor
  • Curva de aprendizado alta
groovy
// Exemplo: Jenkinsfile para .NET
pipeline {
    agent any
    
    environment {
        DOTNET_VERSION = '7.0.x'
    }
    
    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }
        
        stage('Restore') {
            steps {
                sh 'dotnet restore'
            }
        }
        
        stage('Build') {
            steps {
                sh 'dotnet build --no-restore'
            }
        }
        
        stage('Test') {
            steps {
                sh 'dotnet test --no-build --verbosity normal'
            }
        }
        
        stage('Publish') {
            steps {
                sh 'dotnet publish -c Release -o ./publish'
            }
        }
        
        stage('Deploy') {
            when {
                branch 'main'
            }
            steps {
                sh 'docker build -t myapp .'
                sh 'docker push myapp:latest'
            }
        }
    }
    
    post {
        always {
            cleanWs()
        }
        success {
            echo 'Pipeline executed successfully!'
        }
        failure {
            echo 'Pipeline failed!'
        }
    }
}

2. Azure DevOps

O que é: Plataforma completa de DevOps da Microsoft.

Características:

  • Azure Pipelines: CI/CD nativo
  • Azure Repos: Git repositories
  • Azure Boards: Project management
  • Azure Artifacts: Package management
  • Azure Test Plans: Test management

Vantagens:

  • Integração nativa com Azure
  • Interface unificada
  • Suporte completo a .NET
  • Gerenciamento de projetos integrado

Desvantagens:

  • Vendor lock-in com Microsoft
  • Custo pode ser alto
  • Menos flexibilidade que Jenkins
yaml
# Exemplo: azure-pipelines.yml
trigger:
- main

pool:
  vmImage: 'ubuntu-latest'

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'

stages:
- stage: Build
  displayName: 'Build and Test'
  jobs:
  - job: Build
    steps:
    - task: UseDotNet@2
      inputs:
        version: '7.0.x'
    
    - task: DotNetCoreCLI@2
      displayName: 'Restore packages'
      inputs:
        command: 'restore'
        projects: '$(solution)'
    
    - task: DotNetCoreCLI@2
      displayName: 'Build solution'
      inputs:
        command: 'build'
        projects: '$(solution)'
        arguments: '--configuration $(buildConfiguration)'
    
    - task: DotNetCoreCLI@2
      displayName: 'Run tests'
      inputs:
        command: 'test'
        projects: '**/*Tests/*.csproj'
        arguments: '--configuration $(buildConfiguration) --collect "Code coverage"'
    
    - task: DotNetCoreCLI@2
      displayName: 'Publish'
      inputs:
        command: 'publish'
        projects: '**/*.csproj'
        arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)'
        publishWebProjects: true
        zipAfterPublish: true
    
    - task: PublishBuildArtifacts@1
      inputs:
        pathToPublish: '$(Build.ArtifactStagingDirectory)'
        artifactName: 'drop'

- stage: Deploy
  displayName: 'Deploy to Azure'
  dependsOn: Build
  condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
  jobs:
  - deployment: Deploy
    environment: 'production'
    strategy:
      runOnce:
        deploy:
          steps:
          - task: AzureWebApp@1
            inputs:
              azureSubscription: 'My Azure Subscription'
              appName: 'my-app'
              package: '$(Pipeline.Workspace)/drop/**/*.zip'

3. GitHub Actions

O que é: Plataforma de CI/CD integrada ao GitHub.

Características:

  • GitHub-native: Integração nativa
  • YAML-based: Configuração simples
  • Marketplace: Actions reutilizáveis
  • Matrix builds: Execução paralela
  • Self-hosted runners: Execução customizada

Vantagens:

  • Integração perfeita com GitHub
  • Configuração simples
  • Marketplace rico
  • Gratuito para projetos open-source

Desvantagens:

  • Vendor lock-in com GitHub
  • Limitações para projetos privados
  • Menos flexibilidade que Jenkins
yaml
# Exemplo: .github/workflows/ci-cd.yml
name: CI/CD Pipeline

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

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup .NET
      uses: actions/setup-dotnet@v3
      with:
        dotnet-version: '7.0.x'
    
    - name: Restore dependencies
      run: dotnet restore
    
    - name: Build
      run: dotnet build --no-restore
    
    - name: Test
      run: dotnet test --no-build --verbosity normal --collect:"XPlat Code Coverage"
    
    - name: Upload coverage to Codecov
      uses: codecov/codecov-action@v3
      with:
        file: ./coverage.cobertura.xml
    
    - name: Publish
      run: dotnet publish -c Release -o ./publish
    
    - name: Upload artifacts
      uses: actions/upload-artifact@v3
      with:
        name: app-files
        path: ./publish

  deploy:
    needs: build-and-test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Download artifacts
      uses: actions/download-artifact@v3
      with:
        name: app-files
        path: ./publish
    
    - name: Deploy to Azure
      uses: azure/webapps-deploy@v2
      with:
        app-name: 'my-app'
        publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
        package: ./publish

4. GitLab CI/CD

O que é: Sistema de CI/CD integrado ao GitLab.

Características:

  • GitLab-native: Integração nativa
  • YAML-based: Configuração simples
  • Auto DevOps: Configuração automática
  • Container Registry: Registry integrado
  • Kubernetes integration: Deploy direto para K8s

Vantagens:

  • Integração perfeita com GitLab
  • Auto DevOps para projetos simples
  • Container Registry integrado
  • Suporte nativo a Kubernetes

Desvantagens:

  • Vendor lock-in com GitLab
  • Menos flexibilidade que Jenkins
  • Comunidade menor que GitHub
yaml
# Exemplo: .gitlab-ci.yml
stages:
  - build
  - test
  - deploy

variables:
  DOTNET_VERSION: "7.0.x"

build:
  stage: build
  image: mcr.microsoft.com/dotnet/sdk:7.0
  script:
    - dotnet restore
    - dotnet build --configuration Release
  artifacts:
    paths:
      - bin/
    expire_in: 1 week

test:
  stage: test
  image: mcr.microsoft.com/dotnet/sdk:7.0
  script:
    - dotnet test --no-build --verbosity normal
  dependencies:
    - build

deploy:staging:
  stage: deploy
  image: mcr.microsoft.com/dotnet/sdk:7.0
  script:
    - dotnet publish -c Release -o ./publish
    - docker build -t myapp:$CI_COMMIT_SHA .
    - docker push myapp:$CI_COMMIT_SHA
  environment:
    name: staging
    url: https://staging.myapp.com
  only:
    - develop

deploy:production:
  stage: deploy
  image: mcr.microsoft.com/dotnet/sdk:7.0
  script:
    - dotnet publish -c Release -o ./publish
    - docker build -t myapp:$CI_COMMIT_SHA .
    - docker push myapp:$CI_COMMIT_SHA
    - kubectl set image deployment/myapp myapp=myapp:$CI_COMMIT_SHA
  environment:
    name: production
    url: https://myapp.com
  only:
    - main
  when: manual

5. CircleCI

O que é: Plataforma de CI/CD em nuvem.

Características:

  • Cloud-native: Sem necessidade de servidor
  • YAML-based: Configuração simples
  • Orbs: Reutilização de configurações
  • Parallel execution: Execução paralela
  • Docker support: Suporte nativo a containers

Vantagens:

  • Configuração simples
  • Sem manutenção de infraestrutura
  • Execução rápida
  • Orbs reutilizáveis

Desvantagens:

  • Custo pode ser alto
  • Menos controle sobre infraestrutura
  • Vendor lock-in
yaml
# Exemplo: .circleci/config.yml
version: 2.1

orbs:
  dotnet: circleci/dotnet@1.0

jobs:
  build-and-test:
    docker:
      - image: mcr.microsoft.com/dotnet/sdk:7.0
    steps:
      - checkout
      - dotnet/restore
      - dotnet/build
      - dotnet/test
      - persist_to_workspace:
          root: .
          paths:
            - .

  deploy:
    docker:
      - image: mcr.microsoft.com/dotnet/sdk:7.0
    steps:
      - checkout
      - attach_workspace:
          at: .
      - run:
          name: Publish
          command: dotnet publish -c Release -o ./publish
      - run:
          name: Deploy to Azure
          command: |
            az webapp deployment source config-zip \
              --resource-group my-rg \
              --name my-app \
              --src ./publish.zip

workflows:
  version: 2
  build-test-deploy:
    jobs:
      - build-and-test
      - deploy:
          requires:
            - build-and-test
          filters:
            branches:
              only: main

6. Travis CI

O que é: Plataforma de CI/CD em nuvem.

Características:

  • GitHub integration: Integração nativa
  • YAML-based: Configuração simples
  • Multi-language: Suporte a múltiplas linguagens
  • Matrix builds: Execução paralela
  • Deploy automation: Deploy automático

Vantagens:

  • Configuração simples
  • Integração perfeita com GitHub
  • Gratuito para projetos open-source
  • Suporte a múltiplas linguagens

Desvantagens:

  • Limitações para projetos privados
  • Menos recursos que outras ferramentas
  • Comunidade menor
yaml
# Exemplo: .travis.yml
language: csharp
mono: none
dotnet: 7.0.x

script:
  - dotnet restore
  - dotnet build --configuration Release
  - dotnet test --no-build --verbosity normal

deploy:
  provider: azure_web_apps
  resource_group_name: my-rg
  webapp_name: my-app
  on:
    branch: main

🔧 Implementação em .NET

Estrutura de Pipeline

yaml
# Pipeline típico para aplicação .NET
stages:
  - Checkout
  - Restore
  - Build
  - Test
  - Analyze
  - Package
  - Deploy

Configuração de Testes

yaml
# Configuração de testes
test:
  script:
    - dotnet test --collect:"XPlat Code Coverage"
    - dotnet test --logger trx --results-directory TestResults
  artifacts:
    reports:
      junit: TestResults/*.trx
      coverage_report:
        coverage_format: cobertura
        path: TestResults/coverage.cobertura.xml

Configuração de Deploy

yaml
# Deploy para diferentes ambientes
deploy:staging:
  script:
    - dotnet publish -c Release -o ./publish
    - az webapp deployment source config-zip --resource-group staging-rg --name staging-app --src ./publish.zip
  environment: staging
  only:
    - develop

deploy:production:
  script:
    - dotnet publish -c Release -o ./publish
    - az webapp deployment source config-zip --resource-group prod-rg --name prod-app --src ./publish.zip
  environment: production
  only:
    - main
  when: manual

⚠️ Considerações Importantes

Segurança

  • Secrets Management: Use variáveis de ambiente para secrets
  • Access Control: Configure permissões adequadas
  • Audit Logging: Mantenha logs de todas as operações
  • Dependency Scanning: Escaneie dependências regularmente

Performance

  • Caching: Cache dependências e artefatos
  • Parallel Execution: Execute jobs em paralelo
  • Optimization: Otimize builds para velocidade
  • Resource Management: Gerencie recursos adequadamente

Qualidade

  • Code Coverage: Mantenha cobertura de testes alta
  • Static Analysis: Use análise estática de código
  • Security Scanning: Escaneie vulnerabilidades
  • Performance Testing: Teste performance regularmente

🔄 GitOps e ArgoCD

O que é GitOps

GitOps é uma prática onde o Git é a fonte única da verdade para infraestrutura e aplicações. Todas as mudanças são versionadas e rastreadas através do Git.

Princípios do GitOps

  • Declarative: Infraestrutura descrita como código
  • Versioned: Todas as mudanças versionadas no Git
  • Automated: Sincronização automática baseada em Git
  • Auditable: Histórico completo de mudanças

ArgoCD - Continuous Deployment

yaml
# ArgoCD Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/myorg/myapp
    targetRevision: HEAD
    path: k8s
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
    - CreateNamespace=true

Kubernetes Manifests

yaml
# Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:latest
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

---
# Service
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
  namespace: production
spec:
  selector:
    app: myapp
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP

Helm Charts

yaml
# values.yaml
replicaCount: 3
image:
  repository: myapp
  tag: latest
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

resources:
  requests:
    memory: "64Mi"
    cpu: "250m"
  limits:
    memory: "128Mi"
    cpu: "500m"

---
# Chart.yaml
apiVersion: v2
name: myapp
description: A Helm chart for MyApp
type: application
version: 0.1.0
appVersion: "1.0.0"

Flux CD - Alternativa ao ArgoCD

yaml
# Flux GitRepository
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
  name: myapp
  namespace: flux-system
spec:
  interval: 1m
  url: https://github.com/myorg/myapp
  ref:
    branch: main

---
# Flux Kustomization
apiVersion: kustomize.toolkit.fluxcd.io/v1beta1
kind: Kustomization
metadata:
  name: myapp
  namespace: flux-system
spec:
  interval: 10m
  path: ./k8s
  prune: true
  sourceRef:
    kind: GitRepository
    name: myapp
  targetNamespace: production

Automated Sync

yaml
# ArgoCD Sync Policy
syncPolicy:
  automated:
    prune: true
    selfHeal: true
    allowEmpty: false
  retry:
    limit: 5
    backoff:
      duration: 5s
      factor: 2
      maxDuration: 3m
  syncOptions:
  - CreateNamespace=true
  - PrunePropagationPolicy=foreground
  - PruneLast=true

Health Checks

yaml
# ArgoCD Health Check
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: myapp
spec:
  # ... other config
  syncPolicy:
    syncOptions:
    - Validate=true
    - PruneLast=true
  healthChecks:
  - type: Deployment
    name: myapp
    namespace: production

Multi-Environment Management

yaml
# ArgoCD ApplicationSet
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: myapp
spec:
  generators:
  - list:
      elements:
      - env: staging
        namespace: staging
      - env: production
        namespace: production
  template:
    metadata:
      name: '{{env}}-myapp'
    spec:
      project: default
      source:
        repoURL: https://github.com/myorg/myapp
        targetRevision: HEAD
        path: k8s/{{env}}
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{namespace}}'

📚 Recursos Adicionais

Ferramentas

  • SonarQube: Análise de qualidade de código
  • Coverity: Análise estática de código
  • Snyk: Análise de vulnerabilidades
  • Artifactory: Gerenciamento de artefatos
  • ArgoCD: GitOps Continuous Deployment
  • Flux CD: GitOps toolkit

Libraries .NET

  • Microsoft.NET.Test.Sdk: Framework de testes
  • coverlet.collector: Coleta de cobertura
  • ReportGenerator: Geração de relatórios
  • Microsoft.Extensions.Configuration: Configuração

Livros Recomendados

  • "The Phoenix Project"
  • "Continuous Delivery"
  • "DevOps Handbook"
  • "Site Reliability Engineering"
  • "GitOps and Kubernetes"