0 XP
Módulo 5 · CI/CD com GitHub Actions

Cache, testes e pipeline rápido

Intermediário 40 min+25 XPGitHub Actionscacheservice containers

Objetivos desta aula

  • Configurar cache com chave correta
  • Rodar testes de integração com service container
  • Manter o pipeline abaixo de cinco minutos

Pipeline lento é pipeline ignorado: as pessoas param de esperar e passam a burlar. Cache de dependências, baseado no hash do lockfile, é a otimização de maior retorno. Chave errada gera dois problemas opostos — cache nunca reaproveitado ou cache velho reaproveitado indevidamente.

Testes de integração precisam de dependências reais: no GitHub Actions, service containers sobem PostgreSQL ou Redis ao lado do job, com healthcheck. Isso é infinitamente mais fiel que mock quando o objetivo é validar migração e consulta.

Organize a execução por custo: lint e testes unitários primeiro (segundos), integração depois, build de imagem por último. Falhar rápido no que é barato preserva minutos e paciência.

1. Onde o tempo vai

Pipelines lentos quase sempre gastam tempo em instalar dependências, rebuildar imagens e rodar testes em série. Meça cada step antes de otimizar.

2. Cache de dependências

setup-node com cache: npm usa o hash do lockfile como chave. Lockfile igual = cache reaproveitado.

3. Cache de camadas Docker

docker/build-push-action com cache-from: type=gha e cache-to: type=gha,mode=max reaproveita camadas entre execuções.

4. Pirâmide de testes e fail fast

Lint e testes unitários primeiro (segundos), integração depois, end-to-end por último. Paralelize com sharding. Falhar cedo economiza tempo de todos.

5. Testes instáveis (flaky)

Um teste que falha às vezes destrói a confiança no pipeline. Coloque em quarentena, registre e corrija; nunca normalize o 'roda de novo que passa'.

6. Checagem final

O pipeline do CloudShop deve rodar em menos de 10 minutos e mostrar claramente qual etapa falhou.

Na prática

Testes de integração com PostgreSQL

yaml

jobs:
  integracao:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16-alpine
        env:
          POSTGRES_PASSWORD: test
          POSTGRES_DB: cloudshop_test
        ports: ["5432:5432"]
        options: >-
          --health-cmd "pg_isready -U postgres"
          --health-interval 10s --health-timeout 5s --health-retries 5
    env:
      DATABASE_URL: postgres://postgres:test@localhost:5432/cloudshop_test
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 22, cache: npm }
      - run: npm ci
      - run: npm run migrate
      - run: npm run test:integration

      - name: Cache do build do Docker
        uses: actions/cache@v4
        with:
          path: /tmp/.buildx-cache
          key: buildx-${{ hashFiles('api/package-lock.json','api/Dockerfile') }}
          restore-keys: buildx-

Nota de segurança: Credenciais de service container são de teste e efêmeras, mas nunca reutilize a mesma senha de produção nem em teste.

Integração com Postgres como service container

yaml

jobs:
  integration:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16
        env: { POSTGRES_PASSWORD: test }
        ports: ["5432:5432"]
        options: >-
          --health-cmd "pg_isready" --health-interval 5s --health-retries 10
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 20, cache: npm, cache-dependency-path: api/package-lock.json }
      - run: npm ci && npm run test:integration
        working-directory: api
        env: { DATABASE_URL: "postgres://postgres:test@localhost:5432/postgres" }

Por que isso importa

Tempo de feedback é a métrica DORA mais sentida no dia a dia do time.

Erro comum

Usar chave de cache fixa e receber dependências desatualizadas silenciosamente.

Dica de produção

Meça a duração de cada job e trate pipeline lento como bug com prioridade.

Pergunta de entrevista

Como você reduziria um pipeline de 22 minutos para menos de 5?

Glossário

service container
Container auxiliar iniciado pelo runner para dependências de teste.
chave de cache
Identificador derivado de arquivos que determina reaproveitamento do cache.
flaky test
Teste que passa ou falha sem mudança no código.
service container
Container auxiliar (banco, cache) disponível durante o job.
sharding
Dividir a suíte de testes entre várias máquinas em paralelo.

Conexão com o CloudShop

Rodar as migrações e testes de integração do CloudShop a cada PR.

Quiz da aula

  1. 1. Qual a melhor base para a chave de cache de dependências Node?

  2. 2. Qual a chave típica do cache de dependências npm?

  3. 3. Ordem recomendada de testes?

Minhas anotações

Salvo automaticamente neste navegador.

AnteriorPróxima