Mergulhe no Pipeline CI/CD: seu primeiro passo concreto hoje

CI CD Pipeline : o essencial em um artigo — código real, diagramas e etapas concretas, extraídos de um curso de 20 lições.

Mergulhe no Pipeline CI/CD: seu primeiro passo concreto hoje

A melhor forma de aprender CI CD Pipeline é fazendo. Este artigo te dá o pontapé inicial com trechos práticos extraídos de um curso de 20 lições — o suficiente para obter um primeiro resultado já hoje.

tl;dr
  • Introdução ao CICD
  • Integração Contínua
  • Qualidade do Código
  • Otimização do Pipeline
  • Implantação Contínua
~$ cat ./parcours.md # CI CD Pipeline — 6 capítulos
01
Introdução ao CICD
→ Capítulo 00.1 — Filosofia CI/CD : Por que automatizar ?→ Capítulo 00.2 — O ecossistema das ferramentas CI/CD+ 1 mais lições
02
Integração Contínua
→ Capítulo 01.1 — Estratégias de branches Git→ Capítulo 01.2 — Builds automatizados e pipelines YAML avançados+ 1 mais lições
03
Qualidade do Código
→ Capítulo 02.1 — Análise estática com SonarQube→ Capítulo 02.2 — Segurança no CI/CD : SAST, DAST e dependências+ 1 mais lições
04
Otimização do Pipeline
→ Capítulo 03.1 — Otimização do Pipeline : Cache, Paralelização e Matrizes→ Capítulo 03.2 — Otimização dos builds Docker+ 1 mais lições
05
Implantação Contínua
→ Capítulo 04.1 — Estratégias de implantação avançadas→ Capítulo 04.2 — Ambientes, Secrets e Rollback+ 1 mais lições
06
Monitoramento e Observabilidade
→ Capítulo 05.1 — Monitoramento e Observabilidade pós-implantação→ Capítulo 05.2 — SLO, SLA e Métricas DORA
🏁
Projeto final
→ Você sai com um projeto concreto e demonstrável

Cobertura de código e limites de qualidade

Capítulo 02 • Lição 03 • Duração: 45 min

NOTE🎯 Objetivos
  • Compreender o que é cobertura de código e seus limites
  • Medir a cobertura com as ferramentas padrão (pytest-cov, jest, JaCoCo)
  • Definir limites inteligentes (line, branch, mutation)
  • Bloquear um PR se a cobertura cair
  • Visualizar os relatórios no Codecov ou SonarQube

1. O que é cobertura de código?

A cobertura de código mede a porcentagem de linhas (ou de branches, condições, funções) executadas pelos seus testes automatizados.

TipoMedidaExemplo
Line Coverage% de linhas executadas80 % = 80 linhas de 100 são atingidas
Branch Coverage% de branches condicionais testadasif/else, switch — os 2 caminhos devem passar
Function Coverage% de funções chamadasTodas as funções exportadas estão sendo testadas?
Statement Coverage% de instruções executadasPróximo do line coverage
Mutation Coverage% de mutações detectadas pelos testesMais confiável, porém custoso (mutation testing)
WARNING⚠️ Armadilha clássica

100 % de cobertura NÃO significa 100 % de qualidade. É possível ter 100 % de linhas executadas sem verificar os resultados. assert é tão importante quanto executar o código.

2. Coverage em Python com pytest-cov

output
pip install pytest pytest-cov

# Executar os testes com coverage
pytest --cov=mon_module --cov-report=term --cov-report=html

# Saída no console :
# Name            Stmts   Miss  Cover
# -------------------------------------
# mon_module.py     50      5    90%
# -------------------------------------
# TOTAL             50      5    90%

# Relatório HTML interativo em htmlcov/index.html

Configuração via pyproject.toml

output
[tool.pytest.ini_options]
addopts = "--cov=src --cov-report=term-missing --cov-report=xml --cov-fail-under=80"

[tool.coverage.run]
source = ["src"]
omit = [
    "*/tests/*",
    "*/migrations/*",
    "*/__init__.py"
]

[tool.coverage.report]
exclude_lines = [
    "pragma: no cover",
    "raise NotImplementedError",
    "if __name__ == .__main__.:",
]
fail_under = 80
show_missing = true

3. Coverage em JavaScript com Jest

output
npm install --save-dev jest

# package.json
{
  "scripts": {
    "test": "jest",
    "test:coverage": "jest --coverage"
  },
  "jest": {
    "collectCoverageFrom": [
      "src/**/*.{js,ts}",
      "!src/**/*.d.ts",
      "!src/index.ts"
    ],
    "coverageThreshold": {
      "global": {
        "branches": 75,
        "functions": 80,
        "lines": 80,
        "statements": 80
      }
    },
    "coverageReporters": ["text", "lcov", "html", "cobertura"]
  }
}

# Executar
npm run test:coverage

# Se o limite não for atingido :
# Jest: "global" coverage threshold for lines (80%) not met: 73.5%
# → Build FALHA

4. Coverage em Java com JaCoCo

output
<!-- pom.xml -->
<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.8.11</version>
  <executions>
    <execution>
      <goals><goal>prepare-agent</goal></goals>
    </execution>
    <execution>
      <id>report</id>
      <phase>test</phase>
      <goals><goal>report</goal></goals>
    </execution>
    <execution>
      <id>jacoco-check</id>
      <goals><goal>check</goal></goals>
      <configuration>
        <rules>
          <rule>
            <element>BUNDLE</element>
            <limits>
              <limit>
                <counter>LINE</counter>
                <value>COVEREDRATIO</value>
                <minimum>0.80</minimum>
              </limit>
            </limits>
          </rule>
        </rules>
      </configuration>
    </execution>
  </executions>
</plugin>

mvn clean test
# Relatório em target/site/jacoco/index.html

5. Definir limites inteligentes

Tipo de projetoLimite recomendado
Critical (banking, healthcare, aerospace)90-95 %
SaaS / Web app production80-85 %
Backend API75-85 %
Frontend (UI logic)60-70 %
Prototype / MVP40-60 %
Script utilitário0-30 % (geralmente desnecessário)
TIP💡 Estratégia realista

Em vez de um limite absoluto, exija que a cobertura não diminua em relação à branch main. Codecov e SonarQube fazem isso nativamente.

6. Integração GitHub Actions

output
name: CI with Coverage

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      
      - name: Install
        run: pip install -e ".[dev]"
      
      - name: Tests + coverage
        run: pytest --cov --cov-report=xml --cov-report=term --cov-fail-under=80
      
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v4
        with:
          file: ./coverage.xml
          token: ${{ secrets.CODECOV_TOKEN }}
          fail_ci_if_error: true

7. Codecov : visualizar e comparar

codecov.yml para personalizar

output
coverage:
  status:
    project:
      default:
        target: 80%
        threshold: 1%
    patch:
      default:
        target: 90%
        threshold: 5%

comment:
  layout: "header, diff, flags, files"
  behavior: default
  require_changes: false

ignore:
  - "tests/**"
  - "**/__init__.py"
  - "migrations/**"

Gestão de artifacts e registries

Capítulo 03 • Lição 03 • Duração: 45 min

NOTE🎯 Objetivos
  • Compreender o que é um artifact e um registry
  • Armazenar e compartilhar artifacts (zip, jar, wheel) no GitHub Actions
  • Enviar imagens Docker para Docker Hub, GHCR, AWS ECR
  • Gerenciar versionamento semântico dos artifacts
  • Definir regras de retenção para evitar explosão de custos

1. O que é um artifact?

Um artifact é qualquer arquivo produzido por um build e destinado a ser usado posteriormente:

Tipo de artifactExemploRegistry típico
Image containerdevforge-api:1.2.3 (Docker)Docker Hub, GHCR, ECR, Quay
Package Pythonmy-lib-1.0.0.whlPyPI, AWS CodeArtifact, GitHub Packages
Package npmmy-lib-1.0.0.tgznpm registry, GitHub Packages
JAR Javamy-app-1.0.jarMaven Central, Nexus, JFrog Artifactory
Binário compiladomy-cli-linux-amd64GitHub Releases, S3
Helm chartmy-chart-1.0.0.tgzChartMuseum, OCI registries
Arquivo ZIP genéricobuild-output.zipGitHub Actions Artifacts, S3

2. Artifacts GitHub Actions (intra-workflow)

Enviar um artifact

output
- name: Build wheel
  run: python -m build

- name: Upload wheel as artifact
  uses: actions/upload-artifact@v4
  with:
    name: python-wheel
    path: dist/*.whl
    retention-days: 30

Baixar em um job seguinte

output
deploy:
  needs: build
  runs-on: ubuntu-latest
  steps:
    - name: Download wheel
      uses: actions/download-artifact@v4
      with:
        name: python-wheel
        path: ./dist
    
    - name: Install
      run: pip install dist/*.whl
TIP

Os artifacts do GitHub são gratuitos até 500 MB por repositório público e expiram por padrão após 90 dias.

3. Container registries comparados

RegistryCustoVantagensDesvantagens
Docker HubGrátis (público) / 5 $/user (privado)O mais popular, grande ecossistemaRate limits nos pulls
GHCR (GitHub)Grátis (público) / incluso no GitHubIntegração nativa com GitHubMenos conhecido
AWS ECR0.10 $/Go/mêsSegurança IAM, scan automático, integrado ECS/EKSEspecífico por região
GCR / Artifact Registry0.10 $/Go/mêsIntegrado ao GCP, multi-formatoLock-in GCP
Azure ACRBasic 5 $/mêsIntegrado ao AzureLock-in Azure
Quay.ioGrátis (público) / pago (privado)Detector de vulnerabilidades forteMenos suporte
Harbor (self-hosted)Grátis (mas ops)Sem dependência externa, controle totalPrecisa manter você mesmo

4. Push para Docker Hub a partir do GitHub Actions

output
- name: Login Docker Hub
  uses: docker/login-action@v3
  with:
    username: ${{ secrets.DOCKERHUB_USERNAME }}
    password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build and push
  uses: docker/build-push-action@v5
  with:
    context: .
    push: true
    tags: |
      myuser/myapp:latest
      myuser/myapp:${{ github.sha }}
      myuser/myapp:${{ github.ref_name }}
    platforms: linux/amd64,linux/arm64
    cache-from: type=gha
    cache-to: type=gha,mode=max

5. Push para GHCR (GitHub Container Registry)

output
- name: Login to GHCR
  uses: docker/login-action@v3
  with:
    registry: ghcr.io
    username: ${{ github.actor }}
    password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push
  uses: docker/build-push-action@v5
  with:
    push: true
    tags: |
      ghcr.io/${{ github.repository }}:latest
      ghcr.io/${{ github.repository }}:${{ github.sha }}
TIP

GHCR não exige nenhum secret adicional: o GITHUB_TOKEN gerado automaticamente é suficiente.

6. Push para AWS ECR

output
- name: Configure AWS credentials
  uses: aws-actions/configure-aws-credentials@v4
  with:
    role-to-assume: arn:aws:iam::123456789012:role/github-actions-ecr
    aws-region: eu-west-3

- name: Login to ECR
  id: ecr
  uses: aws-actions/amazon-ecr-login@v2

- name: Build and push
  uses: docker/build-push-action@v5
  with:
    push: true
    tags: |
      ${{ steps.ecr.outputs.registry }}/myapp:latest
      ${{ steps.ecr.outputs.registry }}/myapp:${{ github.sha }}

7. Versionamento semântico das imagens

Convenção SemVer : MAJOR.MINOR.PATCH

TagQuando usar
1.2.3Versão exata imutável (produção estrita)
1.2Último patch da minor 1.2
1Última minor da major 1
latestA mais recente (evitar em prod!)
sha-abc1234Tag baseada no commit Git
main / developÚltima da branch
pr-42Específica de uma Pull Request
v1.2.3-rc.1Release candidate

Com docker/metadata-action

output
- name: Generate tags
  id: meta
  uses: docker/metadata-action@v5
  with:
    images: myuser/myapp
    tags: |
      type=ref,event=branch
      type=ref,event=pr
      type=semver,pattern={{version}}
      type=semver,pattern={{major}}.{{minor}}
      type=semver,pattern={{major}}
      type=sha,prefix=sha-,format=short
      type=raw,value=latest,enable={{is_default_branch}}

# Saída automática conforme o contexto :
# - na main : latest, sha-abc1234, main
# - na tag v1.2.3 : 1.2.3, 1.2, 1, sha-abc1234
# - em PR #42 : pr-42, sha-abc1234

Capítulo 00.1 — Filosofia CI/CD : Por que automatizar?

NOTEObjetivo desta lição — Compreender os problemas do desenvolvimento de software tradicional, descobrir por que a automação CI/CD se tornou indispensável e aprender os princípios fundamentais que orientam um pipeline moderno.

1. O mundo antes do CI/CD — O «Integration Hell»

Antes da adoção das práticas CI/CD, as equipes de desenvolvimento trabalhavam em silos durante semanas ou meses em branches separadas. Quando tentavam integrar seu código, o resultado era frequentemente catastrófico. Esse fenômeno era chamado de Integration Hell (inferno da integração).

🔴 Antes do CI/CD

🟢 Com o CI/CD

WARNINGEstatística impactante — Segundo o relatório DORA 2023, as equipes «elite» fazem deploy várias vezes por dia com taxa de falha de deploy inferior a 5 %, contra uma vez por mês ou menos para as equipes «low performers».

2. O custo do bug — A regra do «Shift Left»

O princípio «Shift Left» (deslocar para a esquerda) significa detectar e corrigir problemas o mais cedo possível no ciclo de desenvolvimento. Quanto mais tarde um bug é detectado, mais caro fica corrigi-lo.

O CI/CD permite identificar problemas já no commit, reduzindo drasticamente o custo de correção. Os testes automatizados, a análise estática do código e os scans de segurança são executados a cada push, muito antes de o código chegar à produção.

3. Os três pilares : CI, CD (Entrega) e CD (Deploy)

🔵 CI — Integração Contínua

Os desenvolvedores integram seu código em uma branch comum várias vezes por dia. A cada integração, um pipeline automatizado é disparado: compilação, testes unitários, análise de código.

Objetivo: detectar conflitos e bugs rapidamente.

🟡 CD — Entrega Contínua

O código está sempre em estado deployável. Após a CI, o pipeline prepara automaticamente uma release (package, imagem Docker) pronta para ser implantada em qualquer ambiente.

Objetivo: poder fazer deploy a qualquer momento, com aprovação humana possível.

🟢 CD — Deploy Contínuo

Todo commit que passa nos testes é automaticamente implantado em produção, sem intervenção humana. É o nível máximo de automação, usado por Netflix, Amazon, Google.

Objetivo: eliminar qualquer atraso entre o código e o valor para o usuário.

PráticaFrequência de deployAprovação humanaNível de confiança necessário
ManualTrimestral / AnualSempreBaixo (processo)
Apenas CISemanal / MensalSempreMédio (testes básicos)
CI + CD EntregaDiária / SemanalOpcionalAlto (testes completos)
CI + CD DeployVárias vezes/diaNuncaMuito alto (testes + monitoramento)

4. O pipeline CI/CD — Visão geral

Um pipeline CI/CD é uma cadeia de etapas automatizadas que transforma um commit de código em uma aplicação implantada em produção.

EtapaDescriçãoFerramentas comunsDuração típica
CodeDesenvolvedor envia código para o GitGit, GitHub, GitLab
BuildCompilação, resolução de dependênciasMaven, npm, Gradle, Docker1–5 min
Teste unitárioTestes rápidos no nível das funçõesJUnit, Jest, pytest1–3 min
Análise de qualidadeCobertura de código, linting, segurançaSonarQube, ESLint, Snyk2–5 min
PackageCriação de um artifact implantávelDocker, JAR, ZIP, Helm2–10 min
Teste de integraçãoTestes em um ambiente completoPostman, Cypress, k65–15 min
Deploy StagingImplantação em ambiente de testeKubernetes, ECS, Heroku2–5 min
Deploy ProdImplantação em produçãoRolling, Blue/Green, Canary2–10 min
MonitorMonitoramento e alertas pós-deployPrometheus, Grafana, DatadogContínuo

5. As métricas DORA — Medir o desempenho DevOps

O projeto DORA (DevOps Research and Assessment) identificou quatro métricas-chave que medem a eficácia de uma organização DevOps. Essas métricas permitem posicionar sua equipe e definir objetivos de melhoria.

📈 Deployment Frequency

va-plus-loin

Este artigo cobre os trechos mais úteis — o curso completo CI CD Pipeline (7 capítulos, 20 lições, exercícios corrigidos e projeto final) leva você até o fim.

./acessar-o-curso-completo curso grátis : Dominando o Claude Code

FAQ

Quanto tempo para aprender CI CD Pipeline?
Com uma progressão estruturada (7 capítulos, 20 lições curtas e práticas), é possível atingir um nível operacional em algumas semanas dedicando 30 a 60 minutos por dia. O importante é praticar cada conceito imediatamente.
É preciso ter pré-requisitos?
Básicos de informática são suficientes. Se você sabe usar um terminal e ler código simples, está pronto.
Por onde começar na prática?
Reproduza os comandos deste artigo e depois siga o curso completo CI CD Pipeline: ele encadeia as 20 lições em ordem, com exercícios e projeto final.

📬 Quer receber este tipo de guia toda semana? Inscreva-se gratuitamente — código real, zero enrolação.