Vamos falar de um assunto técnico? No mundo do desenvolvimento de software, cada linha de código conta uma história. E nesse conto, os commits são os capítulos que narram a evolução do projeto. Mas, há uma prática que tem despertado a curiosidade e, às vezes, a confusão dos desenvolvedores: os Conventional Commits.
Então, se você já se perguntou o que são esses misteriosos commits, por que são tão importantes e como podem melhorar a eficiência do seu fluxo de trabalho, você veio ao lugar certo. Neste artigo, vamos desmistificar os Conventional Commits, revelando sua lógica subjacente, seu propósito e como podem revolucionar a forma como você e sua equipe colaboram no desenvolvimento de software.
Conventional Commits: o que são?
Durante o desenvolvimento de um software, uma das partes mais cruciais é o versionamento de código. Como manter um registro preciso de todas as alterações feitas no código? Como comunicar essas mudanças de forma eficaz para sua equipe e para outros interessados no projeto? É aqui que o padrão de Conventional Commits (CC) entra em cena como uma solução elegante para esse desafio comum.
CC é uma forma de estruturar e padronizar os commits, tornando-os mais organizados e fáceis de entender. Sua utilização também na geração de CHANGELOG automatizado e na análise de contribuições. Ao utilizar o padrão de CC, uma mensagem de commit é estruturada da seguinte forma:
`
<tipo>([escopo opcional]): <descrição>
[corpo opcional]
[rodapé opcional]
`
Como os tipos de commit apresentam mais especificações, vamos primeiro definir e detalhar as demais partes do commit, para logo mais abordá-los.
Escopo
O escopo é uma parte opcional, curta e de fácil compreensão, sempre sinalizada entre parênteses. Essa parte é muito importante em repositórios enormes ou projetos com várias features e mudanças paralelas.
Através dela, apresentamos um contexto adicional, indicando qual área específica do código esse commit irá alterar, ou seja, o escopo afetado, como (api), se é na camada de backend, (lang), se é na tradução, (ui), se é na interface gráfica etc. Esse escopo é importante para diminuir as responsabilidades da descrição.
Descrição
Juntamente com o tipo, a descrição é a parte mais importante do CC, sendo, portanto, obrigatória. É nessa parte que deve ser descrita, de maneira direta, sucinta e simplificada, o que foi realizado no commit. Por se tratar de um breve resumo, é recomendado que essa parte apresente, no máximo, 50 caracteres, para que não se estenda muito.
Convencionou-se também que as descrições não sejam iniciadas com maiúsculas, sejam escritas sem ponto final e que utilizem os verbos no imperativo. Apesar de parecer estranho, inicialmente, utilizar o imperativo presente para se referir a uma ação realizada no passado, mas a ideia aqui é descrever o que esse commit fará ao código preexistente. Por exemplo: “esse commit vai adicionar uma funcionalidade” ou “se mesclado, esse commit irá corrigir o CRUD de usuário”
Corpo
O corpo é a parte da mensagem de commit que apresenta detalhes adicionais sobre as alterações feitas no código. Apesar de ser opcional, seu uso é altamente recomendado quando as alterações são muito complexas ou precisam de uma contextualização com mais detalhes sobre a implementação.
Assim, quando presente, deve fornecer informações suficientes para que os outros desenvolvedores possam entender o que foi alterado e quais as motivações para essas mudanças, comparando-as com o código anterior. Da mesma forma que a descrição, também deve ser escrito utilizando o imperativo.
Rodapé
O rodapé também é uma parte opcional da mensagem de commit e adiciona informações sobre as alterações ocorridas. Geralmente, é colocado após o corpo da mensagem e é separado dele por uma linha em branco. É utilizado para incluir informações adicionais relacionadas a meta informações, como tarefas atreladas, números de ticket de suporte, links para relatórios de bugs ou outros recursos relacionados.
Além disso, pode conter uma seção crucial chamada BREAKING CHANGE para indicar mudanças que quebram a compatibilidade com o código anterior. Uma outra forma de indicar que o commit em questão apresenta breaking changes é a utilização de uma exclamação (!) após o tipo (ou escopo, se houver) do commit. Caso a exclamação seja utilizada, o commit deve conter um corpo para descrever as mudanças.
Tipos de Commits
O objetivo dos tipos em um commit é fornecer uma maneira padronizada de identificar a natureza da alteração realizada. Um ponto de atenção é que apenas um tipo pode ser utilizado por commit. Dessa forma, caso existam dúvidas de qual tipo utilizar, provavelmente esse commit deva ser separado em dois ou mais por se tratar de uma alteração grande demais.
Dito isso, vamos conhecer os tipos de commits mais comuns e entender como eles podem ser utilizados nos nossos projetos:
Feat
Vem de feature (recurso) e é utilizado quando um novo recurso ou funcionalidade é implementado no projeto, destacando essa adição. Um exemplo disso é o acréscimo de um novo endpoint em uma API.
Fix
Vem de bug fixes (correções de erros) e é utilizado para indicar a correção de um problema ou mal funcionamento do código, como a correção de um erro de validação de um formulário.
Style
Ao contrário do que se possa imaginar, esse tipo não diz respeito a alterações no CSS. Ele é utilizado para se referir a alterações ou formatações no estilo do código que não afetam o seu funcionamento. Ou seja, a remoção de espaços em branco, correção de ponto e vírgula, organização da indentação etc.
Refactor
Vem de code refactoring (refatoração de código), esse tipo indica a reestruturação do código preexistente sem alteração de sua funcionalidade, como ajustes após um code review.
Change
Significando alteração, esse tipo é utilizado quando são feitas mudanças na implementação de um recurso existente, como melhorar uma interface de usuário.
Perf
Vem de performance improvements (melhorias de desempenho), é utilizado quando são feitas alterações para melhorar a performance, como melhorias no desempenho dos algoritmos ou no tempo geral de execução do sistema.
Build
Vem do termo construir e é utilizado quando se faz alterações no sistema de compilação ou nas dependências externas do projeto, gerando impacto real ao sistema, como adicionar, remover ou atualizar dependências.
Chore
Traduzido por tarefa, esse tipo é utilizado para indicar mudanças relacionadas a manutenção técnica ou preventiva, que não modificam os arquivos src ou de teste. Diferente do build, essas alterações não modificam o código de produção, apenas as ferramentas, configuração e bibliotecas auxiliares. Como exemplos de usos, temos a alteração de uma dependência de desenvolvimento, adição de prettier, alterações no .gitignore ou nas regras do eslint.
Ci
Vem de continuous integrations (integrações contínuas) e é utilizado quando se faz alterações nos arquivos e scripts de configuração de CI (Travis, Circle, BrowserStack, SauceLabs). Por exemplo: atualizar configurações do pipeline de CI/CD.
Docs
Vem de documentation (documentação) e é utilizado quando são feitas alterações e atualizações na documentação armazenada no repositório, como alterar o README, por exemplo.
Deprecate
Significando depreciar, esse tipo é utilizado para sinalizar que uma funcionalidade existente está sendo descontinuada, mas ainda não será removida do produto para não quebrar integrações preexistentes. É uma maneira de incentivar os desenvolvedores a migrar para alternativas mais recentes.
Remove
De remover, é utilizado quando um recurso é removido, geralmente após um período de tempo marcado como deprecated. Remover um recurso é considerado um breaking change, sendo necessário incrementar o número da versão.
Revert
Significando reverter, é utilizado para indicar a remoção de um ou mais commits anteriores que foram incluídos acidentalmente ou causaram problemas sérios que exigiram sua remoção.
Security
Esse tipo é utilizado quando são feitas melhorias na segurança do produto ou resolver problemas de segurança relatados, como corrigir vulnerabilidade de injeção de SQL.
Test
Esse tipo de commit indica a criação, revisão ou alteração dos testes automatizados do projeto.
Colocando em prática
Dessa forma, com tudo que vimos até aqui sobre a utilização de Conventional Commits, nosso commit seria escrito da seguinte forma:
`<feat>(api): alterar funcionalidade de status da compra
Resolves: #1234
BREAKING CHANGE: Quando o status de uma compra for alterado, um e-mail de notificação será enviado ao cliente.`
ou
`<feat>(api)!: alterar funcionalidade de status da compra
Quando o status de uma compra for alterado, um e-mail de notificação será enviado ao cliente.
Resolves: #1234`
Agora que você já sabe como usar Conventional commits, vamos começar a padronizar nossos commits?