Book cover

Página Principal | Modo Dark

Fundamentos de Manutenção de Software

Marco Tulio Valente

1 Conventional Commits

Manutenção, em suas várias formas (corretiva, evolutiva, refatoração, etc.), requer essencialmente mudanças de código, as quais são efetivadas por meio de commits. Neste apêndice, descreve-se uma convenção para escrita de mensagens de commits, chamada de Conventional Commits. Essas mensagens são importantes porque elas são parte do histórico de versões mantido por um repositório de código e, futuramente, poderão ser lidas por outros desenvolvedores.

Antes de apresentar essa convenção, queremos lembrar que todo git commit deve possuir uma mensagem que explica a mudança que está sendo realizada no repositório do projeto, tal como a seguir:

git commit -m "update"

No entanto, a mensagem acima, que usamos propositalmente como exemplo, é muito simples e vaga. Conventional Commits propõe então um formato padrão para escrita de mensagens de commits, com o objetivo de torná-las mais legíveis e também facilitar o seu processamento por ferramentas. Cada mensagem deve ter o seguinte formato:

<tipo>(escopo): <descrição>

[corpo]

[rodapé]

O campo <tipo> indica o tipo da mudança e pode ser:

<escopo> é um campo opcional que informa o módulo ou a parte do sistema que foi alvo da mudança. Por exemplo, (controlador).

Em seguida, <descrição> é uma breve descrição da mudança, em apenas uma linha. A descrição deve começar com um verbo no presente. Por exemplo, cria, atualiza, refatora, corrige, implementa, remove, envia, etc.

Opcionalmente, deve seguir uma linha em branco e depois uma série de linhas (<corpo>) que descrevem com mais detalhes a mudança. O <corpo> é opcional porque a mudança pode ser simples e a <descrição> já pode ser suficiente para explicá-la.

O [rodapé] é também opcional. Um rodapé comum é a mensagem BREAKING CHANGE:, a qual destaca que o commit inclui uma breaking change, tal como vimos no Capítulo 4. No entanto, em vez de indicar a breaking change no rodapé, pode-se acrescentar um ponto de exclamação (!) após o <tipo>. Por exemplo, feat! significa que estamos implementando uma feature e que ela introduz uma breaking change. O rodapé pode ser ainda usado para associar o commit a uma tarefa no sistema de gerenciamento de tarefas, como Jira, GitHub Issues, etc.

Uma implicação importante de Conventional Commits é que um commit deve realizar apenas um tipo de manutenção. Ou seja, não é possível ter um commit que corrige um bug e que implementa uma feature, por exemplo. Nesse caso, esse commit deve ser dividido em dois. De forma semelhante, não é recomendável ter um commit que implementa múltiplas vezes o mesmo tipo de manutenção. Por exemplo, o mesmo commit não deve corrigir dois bugs.

1.1 Exemplo: Fórum de Perguntas e Respostas

Mostra-se a seguir alguns exemplos de mensagens de commits, relativas a um fórum de perguntas e respostas. Ou seja, um sistema no qual um usuário pode fazer perguntas, que serão respondidas por outros usuários.

1. Implementação de uma nova feature.

feat(perguntas): adiciona um botão de like nas perguntas

2. Correção de um bug.

fix(respostas): corrige bug na contagem de visualizações de respostas

3. Atualização de documentação.

docs: atualiza documento com instruções de instalação

4. Implementação de uma feature, com uma breaking change.

feat(respostas)!: cria uma thread de respostas

Permite-se agora adicionar uma resposta em uma outra resposta,
criando-se assim uma thread de respostas.

BREAKING CHANGE: adição de parâmetro com o nível da resposta no
endpoint de criação de resposta.

1.2 Exemplo: Angular

Um dos primeiros sistemas a adotar Conventional Commits foi o Angular, que é um framework para implementação de frontends de aplicações Web. Seguem alguns exemplos de mensagens de commits desse projeto. Você vai perceber que Conventional Commits também permite outros tipos de mudanças, como test (implementação de testes) e build (mudanças no sistema de build).

docs: fix wrong line highlights

fix(language-service): Detect local project version on creation

feat(forms): introduce parse errors in signal forms

refactor(core): improve tree-shaking

feat(devtools): mark special element injector providers as internal

test(forms): submit behavior while validation is pending

build: update cross-repo angular dependencies

1.3 Considerações Finais

Como afirmado, Conventional Commits padroniza e torna mais claras as mensagens de commit, facilitando o entendimento das manutenções realizadas em um projeto. Ele também facilita a implementação de ferramentas para geração de changelogs, versionamento semântico e geração de notas de release.

Exercícios

1. Qual a relação entre Conventional Commits e Versionamento Semântico (tal como estudamos no Capítulo 4)?