https://a.storyblok.com/f/270183/40296/f36544f9c6/3-reasons_conventional-commits.png

3 razões pelas quais você deve usar commits convencionais

Publicado em November 20, 2023

Tempo de leitura: 6 minutos

Introdução

Como programador, você pode desenvolver um aplicativo, uma biblioteca, um microsserviço ou um monorepo repleto de serviços e bibliotecas — ou (Deus me livre!) um enorme monólito. Não importa o tipo de aplicativo que você desenvolva, se você “fizer direito”, vai usar algum sistema de controle de versão (em 90% das vezes será o Git).

A questão é: como você gerencia seu histórico de versões? Como você registra a correção de bugs, a adição de recursos, uma tarefa realizada no espaço de trabalho ou até mesmo uma alteração que causa incompatibilidade? E, mais importante ainda, quão fácil é visualizar isso?

Commits convencionais são uma abordagem padronizada para o controle de versões que aumenta a clareza, a consistência e a colaboração entre desenvolvedores. Nesta postagem, vamos entender o que são os commits convencionais, explorar como eles funcionam e explicar os três principais benefícios que você obtém ao usá-los.

Como seriam as mensagens do Git sem padrões?

Standard Commit Examplestandard_commit_example

A imagem acima ilustra uma sequência comum de commits no Git. Ela apresenta uma linha única e clara, o que é bom, mas deixa muitas perguntas sem resposta. O que podemos deduzir das mensagens de commit? O que fix path significa? Qual caminho? Em qual componente?

Não dá para responder a isso apenas analisando o histórico de commits.

Uma máquina também não consegue fazer isso. Lembre-se disso para mais tarde.

Como funciona com o `commit` convencional?

A título de comparação, veja a seguir como são as mensagens de commit de acordo com os padrões do Conventional Commit:

Conventional Commit Exampleconventional_commit_example

Basta olhar para as duas primeiras informações em cada commit para já aprendermos muito. De baixo para cima, podemos ver que um recurso foi adicionado ao fab componente, corrigiu algo na tipografia, adicionou um recurso ao seletor de datas e realizou algumas tarefas no docs, outro recurso relacionado a accordion item, e assim por diante.

Você não concorda que nossos commits agora estão mais claros e mais descritivos em relação às alterações em cada envio?

Mas os desenvolvedores geralmente não dedicam muito tempo a analisar as mensagens de commit, certo? Vamos ver o verdadeiro potencial dos Commits Convencionais.

Os benefícios do uso de commits convencionais**

Existem três benefícios principais nos commits convencionais: registros de alterações gerados automaticamente, controle automático de versões e melhor comunicação entre a equipe.

1. Registro de alterações gerado automaticamente

Existem muitas ferramentas disponíveis que podem gerar um registro de alterações com base nos commits convencionais. Um registro de alterações tem a seguinte aparência:

Example of Vivid's Auto Generated Changelogvivids_auto_generated_changelog

Você percebeu como o padrão “Conventional Commit” já transforma commits comuns em um registro de alterações de fácil leitura? Ele até mesmo divide o registro em versões com datas para facilitar o rastreamento de novos recursos e correções de bugs.

Como ele consegue saber qual é a versão? Essa é a próxima vantagem.

2. Controle automático de versões de acordo com o SemVer

O padrão Conventional Commit possui a seguinte estrutura:

{type}({scope}): {description}

O tipo é o tipo de alteração que foi feita. Existem três tipos principais: novidades, correções ou tarefas de manutenção.

O escopo refere-se ao que é afetado por essa mudança. Pode ser um componente, uma biblioteca, um aplicativo ou um serviço.

A descrição descreve mais especificamente o que foi alterado.

Essa é a ideia geral. Não vou aborrecer vocês com todas as especificações, mas sugiro que você dê uma lida. É curto e faz sentido.

Então, como isso nos ajuda no gerenciamento de versões?

SemVer é uma forma de numeração de versões do nosso software. A versão é composta por 3 dígitos: X.Y.Z.

X é chamado de Major, Y é chamado de Minor, e Z é chamado de Patch.

Quando você faz uma alteração compatibilidade, aumenta a versão principal. Isso significa que a interface desse escopo foi alterada.

Quando você adiciona um novo recurso (sem comprometer os já existentes), você aumenta a versão secundária.

Quando você corrige algum bug sem adicionar nenhum recurso e sem causar nenhum problema, você aumenta a versão do patch.

Entende onde queremos chegar?

Agora, uma máquina pode ler nossos commits e decidir qual versão nosso escopo deve receber.

E você não precisa fazer isso sozinho. Como o Conventional Commits é um padrão, existem muitas ferramentas que oferecem registro automático de alterações, controle automático de versões e, geralmente, ambos.

Uma dessas ferramentas é release-please, que também conta com uma prática ação no GitHub.

Promovendo uma melhor comunicação na equipe

Além de tornar as mensagens de commit mais legíveis, definir a estrutura nos traz outra vantagem. Ela fornece contexto à mensagem de commit. Mesmo que a descrição seja meh, como o tipo do commit e seu escopo são bem compreendidos, o leitor pode pelo menos antecipar o que está por vir.

Dê uma olhada neste exemplo:

Standarized Commits Still Lack Communicationstandarized_commits_example

Esta é uma tentativa de padronização. No entanto, uma pessoa que analise isso não consegue entender que tipo de alteração foi feita (será uma correção ou um recurso?) nem em qual componente. Também não é possível inferir um registro de alterações a partir disso.

Se mudarmos um pouco isso, ficará assim:

fix(button): verified 48 done and fixed 3 (#172/vivid-103)
feat(button): verified 2 and added demo example (#172/vivid-103)
chore(dialog): fixed 1/5 (font) (#172/vivid-103)

Isso não está muito melhor, porque a descrição não é descritiva.

Por outro lado, se for preciso escrever o commit com fix(button): {description} isso, é menos provável que essa pessoa escreva tal descrição. É mais provável que a pessoa descreva o fix ou feat feito no button.

Como sempre, ter alguns padrões ajuda as pessoas a fazerem as coisas melhor. É mais ou menos como a teoria da janela quebrada.

Experimente. Veja o que acontece.

Exemplo da produção: Padrão de mensagens de confirmação da Vivid

Estamos utilizando o “Conventional Commits” no sistema de design da Vonage, Vivid.

Isso nos ajuda a gerar nosso registro de alterações e registro de lançamento e determinar automaticamente a versão do lançamento.

Além disso, nossas mensagens de commit estão muito melhores desde então.

Mas nossa política de commits não se aplica a todos os commits. Durante o desenvolvimento, um desenvolvedor pode adicionar quantos commits quiser, com qualquer mensagem.

No entanto, quando alguém cria uma solicitação de pull (PR), exigimos que o título da solicitação siga as regras do Conventional Commit:

Github Commit Title Lintergithub_commit_title_linter

Uma ação obrigatória no GitHub que verifica se o título do nosso PR segue as regras do Conventional Commits

Adicionamos mais uma norma que nos ajuda a vincular o commit a um ticket do JIRA. O título de cada PR termina com (VIV-XXX), sendo que XXX é o número do ticket. Por exemplo:

fix(disabled): adds a consistent cursor to disabled elements (VIV-999)

Por fim, em nosso registro de lançamentos, o VIV-XXX se transforma em um link para o JIRA:

Convetional Commits With Jira Linksconvetional_commits_with_jira_links

Por fim, quando um PR é mesclado, o título do PR é definido como o commit. Usamos squash + merge de modo que todo o histórico de commits seja removido do main ramo e apenas o commit convencional permaneça. Fica assim:

Github Squash and Merge Buttongithub_squash_and_merge_button

Se uma solicitação de pull tiver mais de uma alteração (mais de uma correção ou funcionalidade), é sempre possível mencioná-las nos comentários do commit de mesclagem. Fazemos assim:

PR With Multiple Commitspr_with_multiple_commits

A ferramenta de commit convencional (no nosso caso, release-please) considerará esses comentários como se fossem parte da mensagem.

Dessa forma, adotamos uma abordagem relativamente lax em relação às mensagens de commit, garantindo que a última etapa seja, de fato, descrever a alteração.

Resumo

Os commits convencionais nos oferecem duas vantagens claras: um changelog gerado automaticamente e o controle automático de versões.

Existem muitas maneiras de alcançar esses objetivos.

Uma dessas ferramentas é Beachball. Essa ferramenta usa uma interface de linha de comando (CLI) que gera um arquivo JSON em vez de ler o histórico do Git. A grande vantagem disso é que fica muito mais fácil alterar o histórico caso alguém cometa um erro (alterar o histórico do Git pode ser bem complicado…).

Além desses dois benefícios claros e imediatos, afirmo que isso também ajuda a incentivar as pessoas a escreverem mensagens de commit melhores.

Talvez eu esteja errado 🙂 Me avise na nossa Slack da Comunidade Vonage ou mande uma mensagem para a gente no X, antes conhecido como Twitter.

Recursos adicionais

Sistemas de design: lições da Vivid

Como os testes de software podem contribuir para a comunicação

Uma introdução ao Git

Compartilhar:

https://a.storyblok.com/f/270183/400x400/7bf76cb05c/yonatankra.png
Yonatan KraArquiteto de Software da Vonage

Yonatan já participou de alguns projetos incríveis tanto no meio acadêmico quanto no setor privado — desde C/C++, passando por Matlab, até PHP e JavaScript. Ex-CTO da Webiks e arquiteto de software na WalkMe. Atualmente, ele é arquiteto de software na Vonage e instrutor na Egghead.