Pular para o conteúdo
~/buildbase $ 06/11/2026
Sistemas

O que é CI/CD e como automatizar testes e entregas de software

Código verde rolando em tela escura durante uma instalação

Automatizar testes e deploy não deixa o time mais rápido no primeiro mês. Muitas vezes deixa mais lento. Você passa dias escrevendo arquivos YAML, o pipeline reprova código que “funcionava”, e alguém do time pergunta se não era mais fácil subir pelo FTP como antes. A velocidade vem depois, e vem justamente porque o pipeline começou a barrar os problemas que antes chegavam ao cliente.

$ ls ./neste-artigo
  1. Um pipeline de CI/CD, visto de perto
  2. Chamar de CI um pipeline sem testes
  3. Deixar o ramo principal quebrado “só até amanhã”
  4. Branches que vivem semanas longe do main
  5. Um pipeline de 40 minutos que todo mundo pula
  6. Senhas e chaves escritas direto no arquivo do pipeline
  7. Implantação automática sem um caminho de volta
  8. Seu primeiro pipeline em 30 minutos

CI/CD é a sigla para integração contínua (Continuous Integration) e entrega contínua ou implantação contínua (Continuous Delivery / Continuous Deployment). Na integração contínua, cada alteração enviada ao repositório é compilada e testada automaticamente, e todo mundo integra seu código ao ramo principal com frequência, pelo menos uma vez por dia. Na entrega contínua, o código aprovado fica sempre pronto para ir à produção com um clique. Na implantação contínua, nem o clique existe: passou nos testes, vai para o ar.

Código JavaScript com destaque de sintaxe em tela escura
O pipeline roda exatamente o mesmo código que está no repositório, a cada alteração enviada. Foto: Gabriel Heinzer / Unsplash

 
 

Um pipeline de CI/CD, visto de perto

No GitHub Actions, um pipeline pequeno para um projeto Node.js cabe em poucas linhas, num arquivo .github/workflows/ci.yml:

name: CI
on: [push, pull_request]
jobs:
  testes:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm ci
      - run: npm run lint
      - run: npm test

A documentação do GitHub Actions tem modelos prontos para quase toda linguagem, e GitLab CI, Jenkins e Bitbucket Pipelines seguem a mesma lógica com outra sintaxe. Escrever o primeiro pipeline é fácil. Os problemas aparecem nas escolhas em volta dele, e é sobre elas o resto deste texto.

 

Entrega contínua e implantação contínua são a mesma coisa?

Não. Na entrega contínua, uma pessoa ainda aperta o botão que manda a versão aprovada para produção, o que é comum em empresas com janelas de mudança ou exigências de auditoria. Na implantação contínua, o próprio pipeline publica. A maioria dos times começa pela primeira e só automatiza o último passo quando confia nos testes.

 

Preciso de um servidor só para isso?

Não para começar. GitHub Actions e GitLab CI oferecem máquinas hospedadas com uma cota gratuita mensal que costuma sobrar para projetos pessoais e pequenos. Jenkins, no extremo oposto, roda num servidor seu e exige manutenção.

O mínimo que funciona: a cada push, o servidor de CI baixa o código, instala dependências, roda lint e testes e, se tudo passar no ramo principal, publica a nova versão. Se qualquer etapa falhar, o processo para e avisa quem enviou.

 

Chamar de CI um pipeline sem testes

Muita equipe monta um pipeline que só compila e publica. Parece CI, tem o ícone verde, mas não protege nada: se o build passa, o bug vai junto para a produção, só que mais rápido.

O custo aparece no primeiro deploy automático que derruba o checkout de uma loja numa sexta à noite. Comece com poucos testes, mas comece pelos que importam: o fluxo de login, o cálculo do valor do pedido, a função que todo mundo tem medo de mexer. Dez testes nos pontos críticos valem mais do que 200 testes de getters e setters.

 

Deixar o ramo principal quebrado “só até amanhã”

A regra de ouro da integração contínua, descrita por Martin Fowler no artigo clássico sobre integração contínua, é que o build quebrado no ramo principal tem prioridade sobre qualquer outra tarefa. Parece exagero até você ver o que acontece quando ninguém conserta.

Com o main vermelho, cada dev que puxa o código herda o erro, os novos commits não podem ser validados e, em dois dias, ninguém sabe mais qual alteração quebrou o quê. O time passa a ignorar o pipeline, e ele vira decoração. Configure proteção de branch para exigir o CI verde antes do merge e combine com o time: quebrou, conserta ou reverte na hora.

 

Branches que vivem semanas longe do main

Integração contínua pressupõe integrar com frequência. Uma branch de funcionalidade que fica três semanas isolada até ser mesclada não é integração contínua, mesmo com pipeline rodando nela.

O merge dessa branch costuma vir com dezenas de conflitos e com bugs que só aparecem quando o código dela encontra o código que os outros escreveram no mesmo período. A saída é quebrar o trabalho em pedaços que entram no main em um ou dois dias, usando feature flags para esconder o que ainda não está pronto para o usuário.

 

Um pipeline de 40 minutos que todo mundo pula

Se o feedback demora, o dev abre outra tarefa, esquece o que estava fazendo e só descobre o erro no fim do dia. Pior: começa a procurar formas de contornar o CI.

Algumas medidas que reduzem o tempo sem perder segurança:

  • Guardar em cache as dependências (node_modules, pacotes do pip, camadas do Docker) entre execuções.
  • Rodar lint e testes unitários primeiro, que são rápidos, e deixar os testes de ponta a ponta para depois.
  • Paralelizar suítes grandes em vários jobs.
  • Rodar só os testes afetados em monorepos, quando a ferramenta permitir.

Uma meta comum é manter a primeira resposta em menos de dez minutos. Outro vilão silencioso é o teste instável, aquele que falha uma vez a cada cinco execuções sem motivo aparente. Ele ensina o time a clicar em “rodar de novo” sem ler o erro, e um dia o erro é real. Isole esses testes, marque-os e corrija, em vez de conviver com eles.

 

Senhas e chaves escritas direto no arquivo do pipeline

É o erro mais caro desta lista. Uma chave da AWS ou um token de banco de dados colado no YAML vai parar no histórico do Git e, se o repositório for público ou vazar, robôs encontram a chave em minutos e começam a usá-la.

Use o cofre de segredos da ferramenta (Secrets no GitHub, Variables protegidas no GitLab), dê ao pipeline só as permissões necessárias e, sempre que a nuvem permitir, prefira credenciais temporárias via OIDC em vez de chaves fixas. Se uma chave já foi commitada, apagar o arquivo não basta: revogue a chave e gere outra.

 

Implantação automática sem um caminho de volta

Implantação contínua sem plano de reversão é aposta. Antes de deixar o pipeline publicar sozinho, garanta pelo menos estas três coisas:

  1. Um jeito rápido de voltar à versão anterior (republicar a imagem ou o artefato anterior, não “consertar e subir de novo”).
  2. Um ambiente de homologação parecido com produção, onde o deploy roda primeiro.
  3. Monitoramento que mostre, nos minutos seguintes ao deploy, se erros e tempo de resposta pioraram.

Times mais maduros acrescentam deploys graduais (canary ou blue-green), em que a versão nova recebe uma fatia pequena do tráfego antes de ir para todos. Ferramentas novas, como os fluxos com agentes de IA que mostramos em GitHub Agentic Workflows, só fazem sentido em cima dessa base de segurança.

 

Seu primeiro pipeline em 30 minutos

Pegue um projeto pessoal ou de estudo que já esteja no GitHub, crie o arquivo de workflow acima adaptado à sua linguagem e faça um push. Depois escreva de propósito um teste que falha e veja o pipeline ficar vermelho. Corrija, veja ficar verde e ative a proteção de branch. Esse ciclo de 30 minutos ensina mais do que qualquer diagrama, e vira um item concreto para mostrar no portfólio. Os termos que apareceram aqui (build, branch, merge, deploy) estão explicados um a um no glossário de programação do portal.