DEV Community

Cover image for De "Merge é Deploy" para Release Engineering com GitHub Actions
Victor Lis Bronzo
Victor Lis Bronzo

Posted on

De "Merge é Deploy" para Release Engineering com GitHub Actions

Você já parou pra pensar no risco de manter uma esteira onde qualquer merge na branch principal vai direto pra produção sem nenhum gate de segurança?

Por muito tempo, o nosso fluxo aqui era aquele clássico script que quase todo mundo já usou na vida: merge na main disparando SSH com git pull e pm2 restart

Funcionava no dia a dia, mas era aquela falsa sensação de estabilidade kkkk

A ficha caiu de verdade quando encontrei um ponto cego crítico na automação: os scripts remotos rodavam sem tratamento estrito de erro. Ou seja, se um git pull gerasse conflito ou uma migração de banco falhasse no meio do processo, o script ignorava o erro, executava até o final e o GitHub Actions marcava o pipeline como sucesso

O pior cenário para quem monitora: a esteira reportava que tudo tinha corrido bem, enquanto a aplicação em produção já estava fora do ar

Além disso, a ordem de execução estava invertida: a migração de banco rodava antes do build da aplicação. Se o TypeScript acusasse um erro de tipagem logo depois, o banco já tinha sido alterado e o código novo nem subia. Como o Prisma não possui down migrations nativas, reverter o estado virava uma intervenção manual de alto risco

Decidi parar e redesenhar toda a nossa arquitetura de entrega do zero, partindo de uma premissa clara: tag é release, merge não é

Hoje, nada toca o servidor sem uma tag SemVer anotada, atravessando 6 estágios encadeados:

  1. Validação estrita da tag: só aceita tag anotada no padrão vX.Y.Z, garantindo autor, data e o registro auditável de cada release
  2. Gates de qualidade em PR e Release: testes automatizados com Vitest, typecheck rigoroso, build e validação de migrações em banco limpo via workflow_call
  3. Backup desacoplado: rotina diária agendada somada a um snapshot obrigatório antes de qualquer alteração de infraestrutura
  4. Ensaio real de migração: o gate de maior valor, onde o pipeline restaura o dump de produção num banco descartável dentro da própria VPS, executa a migração cronometrada e checa drift de schema antes de tocar a base oficial
  5. Deploy determinístico: checkout direto na tag imutável, build antes da migração e trava de concorrência pra evitar deploys simultâneos
  6. Smoke tests: validação ativa das portas HTTP e varredura de processos no PM2 pra garantir que nada entrou em loop de erro

O impacto dessa mudança na operação é brutal: conquistamos previsibilidade real nas migrações, rastreabilidade de cada versão e a certeza de que pipeline verde significa sistema íntegro no ar

Pra quem também gerencia aplicações Node e TypeScript em VPS ou servidores dedicados e quer sair do deploy cego, estruturei toda essa arquitetura em um template modular de GitHub Actions

Deixei o repositório aberto pra quem quiser usar de base nos seus projetos: https://github.com/victor-lis-bronzo/tag-release-template

Como vocês costumam desenhar os gates de deploy e migração de banco por aí?

Top comments (0)