· Denison Caldeira · DevOps · 3 min read
CI/CD com deploy por tag: staging automático e produção controlada
O padrão que dá velocidade sem perder controle — staging deploya sozinho no merge, produção só sai por tag versionada e rastreável.
Dois extremos quebram time: deploy 100% manual (lento, esquece passo) e deploy automático direto em produção (rápido demais pra quem não tem rede de segurança). O meio-termo que funciona é staging automático, produção por tag.
Esse é o padrão que uso em projeto real. Te dá velocidade no dia a dia e controle quando importa.
A regra em uma frase
- Merge na branch principal → deploy automático em staging.
- Criar uma tag
v1.2.3→ deploy em produção.
Staging testa de graça. Produção exige um ato deliberado — criar a tag — que vira seu registro de “o que foi pra produção e quando”.
Por que tag e não branch
Tag é imutável e versionada. v1.4.0 aponta pra um commit exato, pra sempre. Quando produção quebra, você sabe na hora qual versão está rodando e pra qual voltar. Rollback vira “deploya a tag anterior”, não arqueologia no git.
O workflow (GitHub Actions)
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main] # merge → staging
tags: ['v*'] # tag → produção
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: |
docker build -t app:${{ github.sha }} .
- name: Deploy staging
if: github.ref == 'refs/heads/main'
run: ./deploy.sh staging
- name: Deploy produção
if: startsWith(github.ref, 'refs/tags/v')
run: ./deploy.sh prod
O segredo está nos if: o mesmo workflow se comporta diferente conforme o gatilho. Merge aciona o passo de staging; tag aciona o de produção.
O fluxo no dia a dia
# desenvolvimento normal
git checkout -b feature/login
# ... PR, review, merge → staging deploya sozinho
# validou em staging? promove pra produção:
git tag -a v1.2.0 -m "Login com OAuth"
git push origin v1.2.0 # → produção deploya
Ninguém roda comando de deploy na mão. A ação humana é só decidir quando promover, criando a tag.
Versionamento semântico
Use SemVer pra a tag carregar significado:
v1.2.3→MAJOR.MINOR.PATCH- PATCH (
v1.2.4) — correção de bug. - MINOR (
v1.3.0) — feature nova, compatível. - MAJOR (
v2.0.0) — quebra compatibilidade.
Quem olha a tag já entende o risco do deploy só pelo número.
Rollback em 30 segundos
Produção quebrou na v1.3.0? Sem pânico:
git push origin v1.2.0 # re-deploya a versão anterior, conhecida e estável
Como a tag é imutável, você sabe exatamente o que está voltando.
Erros comuns
- Deploy direto em produção sem staging → você testa nos seus usuários.
- Tag sem padrão (
final,final-2,final-real) → ninguém entende a ordem. Use SemVer. - Build na hora do deploy de prod → build uma vez, promova o mesmo artefato. Build novo = risco de divergência.
Próximo passo
Esse padrão é a espinha dorsal de uma entrega previsível: rápido onde dá, controlado onde precisa.
Te mostro montado de ponta a ponta — com Docker, Kubernetes, pipeline e monitoramento num projeto real pra portfólio — no DevOps na Prática. Quer revisar a esteira do seu time? Fala comigo no WhatsApp.