Imagine receber uma mensagem de um colega dizendo: "o bug está na versão nova". Qual versão nova? Nova em relação a quê? Lançada quando?
Sem uma convenção de versionamento, equipes acabam usando nomes arbitrários — "versão de dezembro", "build final", "build final v2", "build final v2 revisado". Em produção, esse caos tem consequências reais: dificuldade em identificar qual código está rodando, impossibilidade de comparar comportamentos entre versões e incapacidade de comunicar claramente o impacto de uma atualização para clientes e parceiros.
O Semantic Versioning — ou SemVer — é a convenção que resolve esse problema. Adotada pela maioria dos projetos de software modernos, ela transforma um número de versão em uma comunicação precisa sobre o que mudou.
A Lógica do SemVer
Um número de versão SemVer tem o formato MAJOR.MINOR.PATCH — por exemplo, 2.4.1.
Cada parte tem um significado definido:
PATCH — incrementado quando são feitas correções de bugs compatíveis com versões anteriores. Quem usa 2.4.0 pode atualizar para 2.4.1 sem preocupação. Nada quebrou, apenas foi corrigido.
MINOR — incrementado quando novas funcionalidades são adicionadas de forma compatível com versões anteriores. Quem usa 2.4.1 pode atualizar para 2.5.0 com segurança — o que já funcionava continua funcionando.
MAJOR — incrementado quando mudanças incompatíveis são introduzidas. Quem usa 2.x precisa ler o changelog antes de atualizar para 3.0.0 — algo pode ter quebrado intencionalmente.
Regras adicionais importantes:
- Quando MINOR é incrementado, PATCH volta a zero:
2.4.1→2.5.0 - Quando MAJOR é incrementado, MINOR e PATCH voltam a zero:
2.5.3→3.0.0 - Versões com MAJOR igual a zero (
0.x.y) indicam desenvolvimento inicial — a API pública não é considerada estável
Sufixos de Pré-release
Para versões que ainda não estão prontas para produção, o SemVer permite sufixos:
1.0.0-alpha # primeira fase de testes internos
1.0.0-alpha.2 # segunda iteração do alpha
1.0.0-beta.1 # fase de testes mais ampla
1.0.0-rc.1 # release candidate — candidato a versão final
1.0.0 # versão estável final
Em pipelines de CI/CD, é comum gerar versões de pré-release automaticamente para branches de desenvolvimento, enquanto versões estáveis são geradas apenas a partir de merges na main.
Tags no Git
No Git, uma tag é um ponteiro nomeado para um commit específico. Diferentemente das branches, tags não se movem — elas marcam um ponto fixo no histórico, ideal para representar releases.
# Cria uma tag leve (apenas um ponteiro)
git tag v1.2.0
# Cria uma tag anotada (recomendada — inclui mensagem, autor e data)
git tag -a v1.2.0 -m "Release 1.2.0: adiciona suporte a autenticação OAuth"
# Lista todas as tags
git tag
# Lista tags com filtro
git tag -l "v1.*"
# Mostra detalhes de uma tag anotada
git show v1.2.0
# Cria tag em um commit específico (não necessariamente o mais recente)
git tag -a v1.1.5 abc1234 -m "Hotfix: corrige falha de segurança no login"
Tags precisam ser enviadas explicitamente para o repositório remoto — o git push padrão não as inclui:
# Envia uma tag específica
git push origin v1.2.0
# Envia todas as tags locais
git push origin --tags
Conventional Commits: A Base para Automação
O Semantic Versioning define como nomear versões. O Conventional Commits define como escrever mensagens de commit de forma que ferramentas possam determinar automaticamente qual parte da versão deve ser incrementada.
O formato é simples:
<tipo>[escopo opcional]: <descrição>
[corpo opcional]
[rodapé opcional]
Os tipos mais comuns e sua relação com o SemVer:
# Incrementa PATCH — correção de bug
git commit -m "fix: corrige cálculo incorreto de frete para regiões remotas"
# Incrementa MINOR — nova funcionalidade
git commit -m "feat: adiciona suporte a pagamento via PIX"
# Incrementa MAJOR — mudança incompatível (indicada no rodapé)
git commit -m "feat!: remove suporte à API v1
BREAKING CHANGE: os endpoints /api/v1/* foram removidos.
Migre para /api/v2/* conforme documentação."
# Não incrementa versão — mudanças que não afetam o produto
git commit -m "docs: atualiza exemplos de autenticação no README"
git commit -m "chore: atualiza dependências de desenvolvimento"
git commit -m "ci: adiciona cache de dependências no pipeline"
git commit -m "refactor: extrai lógica de validação para módulo separado"
git commit -m "test: adiciona testes para o módulo de pagamento"
Automatizando Releases com GitHub Actions
Com Conventional Commits no histórico, é possível automatizar completamente o processo de versionamento e geração de changelog. A ferramenta Release Please, mantida pelo Google, faz exatamente isso:
# .github/workflows/release.yml
name: Release
on:
push:
branches: [ main ]
permissions:
contents: write
pull-requests: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
release-type: node
O que esse workflow faz: a cada push na main, o Release Please analisa os commits desde a última release, determina qual parte do SemVer deve ser incrementada, cria automaticamente um Pull Request com a atualização de versão e o changelog gerado. Quando esse PR é mergeado, uma tag Git e uma GitHub Release são criadas automaticamente.
Criando uma Release no GitHub Manualmente
Para projetos que preferem controle manual sobre o processo de release:
# Garante que a main está atualizada
git checkout main
git pull
# Cria a tag anotada
git tag -a v2.1.0 -m "Release 2.1.0
Novidades:
- Autenticação via OAuth com Google e GitHub
- Dashboard de métricas em tempo real
- Correção de falha em sessões simultâneas"
# Envia a tag
git push origin v2.1.0
No GitHub, navega-se até Releases → Create a release, seleciona-se a tag criada e adiciona-se as notas de release. O GitHub renderiza o markdown e disponibiliza a release publicamente, com download do código-fonte em zip e tar.gz automaticamente.
Um Fluxo Completo de Versionamento
Reunindo tudo em um cenário real:
# Desenvolvimento da funcionalidade
git checkout -b feature/dashboard-metricas
git commit -m "feat: adiciona componente de gráfico de requisições por minuto"
git commit -m "feat: adiciona filtro por intervalo de datas no dashboard"
git commit -m "test: adiciona testes do componente de gráfico"
git push origin feature/dashboard-metricas
# PR criado, revisado e mergeado na main
# O Release Please detecta dois commits 'feat' e propõe incremento MINOR
# Versão atual: 1.4.2 → proposta: 1.5.0
# PR de release mergeado → tag v1.5.0 criada automaticamente
# Changelog gerado automaticamente:
# ## [1.5.0] - 2025-03-10
# ### Features
# - adiciona componente de gráfico de requisições por minuto
# - adiciona filtro por intervalo de datas no dashboard
Referências para Aprofundamento
Especificações
- Semantic Versioning 2.0.0 — semver.org — A especificação oficial do SemVer, disponível em português. Leitura rápida e essencial.
- Conventional Commits — conventionalcommits.org — Especificação completa em português para mensagens de commit estruturadas.
Ferramentas
- Release Please — GitHub — Ferramenta do Google para automação de releases baseada em Conventional Commits. Documentação completa no repositório.
- semantic-release — Alternativa ao Release Please, mais configurável e com ecossistema de plugins. Popular em projetos Node.js.
- git-cliff — Gerador de changelog altamente configurável, escrito em Rust. Suporta templates customizados para o formato de changelog.
Leitura complementar
- Keep a Changelog — Guia e convenção para escrita manual de changelogs, em português. Explica os princípios por trás de um bom changelog mesmo quando o processo não é automatizado.