Pular para o conteúdo

Deploy não é release

Intermediário12 min de leituraentrega

São duas decisões diferentes, e quase todo processo pesado de entrega existe porque elas vêm grudadas.

  • Deploy é uma decisão técnica: colocar o código em execução em produção. Quem decide é a engenharia, e o critério é “está pronto e seguro para rodar”.
  • Release é uma decisão de produto: tornar a funcionalidade visível para os usuários. Quem decide é quem responde pelo produto, e o critério é de negócio.

Quando as duas são o mesmo evento, o deploy herda todo o peso da decisão de negócio — e aparecem o comitê, a janela mensal e a branch que fica aberta por seis semanas.

Com a separação, o código incompleto entra em produção desligado. Isso destrava várias coisas de uma vez:

  • Integração contínua de verdade: nada de branch longa esperando a funcionalidade fechar.
  • Deploy vira rotina de baixo risco, feito várias vezes por dia.
  • A liberação vira um clique, reversível em segundos — sem novo deploy, sem pipeline.
  • Produto escolhe o momento (campanha, horário, público) sem depender da engenharia.
  • Exposição gradual: 1% dos usuários, depois 10%, depois todos.

O mecanismo mais comum. Um condicional que decide, em tempo de execução, qual caminho seguir.

if flags.ativo("checkout-v2", usuario=usuario):
return checkout_v2(pedido)
return checkout_v1(pedido)

Vale distinguir os tipos, porque eles têm ciclos de vida diferentes:

  • De liberação (temporária): existe até a funcionalidade estar 100% liberada. Deve ser removida em semanas.
  • De experimento (temporária): teste A/B, com prazo definido pela análise.
  • Operacional (permanente): desligar um recurso caro sob carga, ativar modo degradado. Faz parte do sistema.
  • De permissão (permanente): recurso disponível por plano ou cliente. Não é flag, é regra de negócio — e deveria morar no modelo, não no sistema de flags.

Duas técnicas que usam a mesma separação para reduzir risco antes de qualquer usuário ver:

Dark launch — o código novo é executado em produção, mas o resultado é descartado. Você mede latência, erro e consumo com tráfego real, sem afetar ninguém.

Shadow traffic — uma cópia do tráfego real é enviada ao serviço novo, em paralelo ao antigo, e as respostas são comparadas. É a forma mais segura de validar uma reescrita.

Cuidado com o detalhe que morde: se o caminho sombra tem efeito colateral (grava no banco, envia e-mail, cobra), você acabou de duplicar esse efeito. Sombra só funciona sobre operações sem efeito, ou com escrita direcionada a um ambiente separado.

O custo da técnica, e ele é real. Cada flag ativa dobra os caminhos possíveis do código: duas flags são quatro combinações; dez são mil e vinte e quatro — e ninguém testa isso.

Sintomas de que a dívida passou do ponto: flags que ninguém sabe se ainda são usadas, código morto atrás de flags desligadas há meses, comportamento em produção que depende de uma combinação que nunca foi testada, e incidente causado por flag esquecida ligada só num ambiente.

A disciplina que evita:

  • Toda flag temporária nasce com dono e data de remoção registrados.
  • Flag vencida é tratada como bug, não como tarefa “quando sobrar tempo”.
  • Painel com as flags ativas, idade e último uso.
  • Remoção da flag é parte do trabalho da funcionalidade, não um item opcional depois.

Separar deploy de release adiciona uma camada de indireção: para entender o comportamento em produção, é preciso saber o estado das flags — e isso complica diagnóstico. O sistema de flags também vira uma dependência no caminho crítico, com o cuidado que isso exige (falhar para um valor padrão seguro quando ele estiver indisponível).

Para um serviço pequeno, com poucas mudanças por semana, a separação pode custar mais que entrega. Ela ganha valor conforme aumentam a frequência de entrega, o número de pessoas no mesmo código e o custo de errar em produção.