📝 Guia Definitivo para Estruturação de Commits
Saudações, povo do TabNews!
Venho essa noite lhes trazer mais uma pequena dose de conhecimento e curiosidade para vos ajudarem à aperfeiçoar o que já fazem de melhor!
Hoje vou falar a respeito dos commits, ou melhor, de como deixar seu commit mais padronizado e estruturado o possível.
O motivo de eu decidir trazer esse conteúdo hoje, se deve ao fato de uma amiga ter me enviado um print de algumas anotações dela sobre tipos diferentes de commit em alguma aula que ela estava tendo, e eu pensei "Nossa, realmente devem haver mais do que simples fixes por aí!", e fui me aprofundar no assunto.
Pois bem, vamos diretamente ao que nos interessa!
Formato do commit
Cada commit consiste em três elementos diferentes, sendo estes:
- Cabeçalho - Obrigatório, é basicamente o título do seu commit
- Corpo - Uma descrição mais extensa da informação o qual se pretende passar com seu commit
- Rodapé - Caso exista um ticket ou uma issue, você poderá informá-la aqui
Tanto o Corpo quando o Rodapé são opcionais, e até onde eu vejo geralmente não são muito utilizados.
Cabeçalho
O cabeçalho deve manter um padrão predefinido, contendo um tipo, um escopo (apenas quando cabível), e um título, e para uma leitura e compreensão mais rápida e simples, ele não deve passar de 50 caracteres.
{tipo}({escopo}): {titulo}
Exemplos:
fix(login redirect): prevent redirect to external url
feat(middleware): refuse connections from other hosts on production
refactor(markdown viewer): prepared for future viewer package change
fix: serve HomeOffline and remove SWR fetch
fix(query): performance with large offset
Esses exemplos foram selecionados da lista de commits do repositório oficial do TabNews.
Notaram como eles são simples e objetivos? Qualquer desenvolvedor que nunca tenha sequer visto o repositório antes na vida, ao ler esses commits já consegue ter uma mínima noção do que se trata o assunto, e esse é justamente o objetivo que quero atingir com este post!
Tipo
Aqui está a verdadeira inspiração responsável pela minha decisão de escrever essa publicação.
O tipo do commit diz praticamente tudo sobre ele, sendo este capaz de informar se esse commit é relacionado a uma correção em uma linha de código, uma adição de nova feature, melhorias e entre outros.
O tipo deverá ser um dos listados abaixo:
- build: alterações que afetam o sistema de build e/ou dependências externas
- static: alterações no conteúdo de arquivos estáticos (dados .css, .js, .json, imagens, entre outros...)
- ci: alterações em arquivos e scripts de configuração de CI*
- cd: alterações em arquivos e scripts de configuração para CD*
- docs: alterações na wiki e/ou documentação da aplicação
- feat: uma nova feature ou recurso
- fix: referente a uma correção de bug da aplicação
- perf: alteração de código que melhora o desempenho da aplicação e não altera a forma como o usuário utiliza a aplicação
- refactor: refatoração de código, que não corrige um bug e nem altera a forma como o usuário utiliza a aplicação, apenas reescreve o código de maneira melhor organizada e estruturada
- improve: alguma alteração de código que melhore o comportamento de um recurso já existente
- style: alterações que não afetam o significado do código (espaço em branco, formatação/identaçaõ, ponto e vírgula, entre outros...)
- test: adicionando novos testes ou corrigindo testes existentes (normalmente não precisa se utilizar fix neste segundo caso)
- revert: reverter para um commit anterior
Além desses temos claro o famoso merge, que está em um padrão de estrutura diferente porém é gerado pelo próprio GitHub e nós compreendemos a importância dele da mesma forma!
*Observação importante: Hoje eu não tenho pleno conhecimento do que se tratam o CI (Continuous Delivery) e CD (Continuous Deployment). Por tanto se alguém já tiver ou quiser fazer um post a respeito, informe nos comentários a URL do post e ficarei orgulhoso em aprender sobre e também anexar nos dois itens marcados ali em cima!
Sobre o revert
Se o commit reverte a um commit anterior, ele deve começar por revert:
, seguido pelo cabeçalho do commit revertido.
Se o corpo for utilizado, ele deve informar: Isso revert o commit {hash do commit}
Sobre o escopo
O escopo, de maneira bem resumida, é em quê exatamente você está trabalhando naquele commit, por exemplo um middlware, uma tela de login, um recurso específico, entre outros.
Sobre o título
O título deverá conter uma descrição resumida e sucinta da mudança, e o ideal é seguir as regrinhas listadas abaixo:
- Use o imperativo, e no tempo presente e nunca no passado, por exemplo: "mudança", "alteração", "implementação", e nunca "mudou", "alterou", "corrigiu", etc
- Não capitalize a primeira letra, mantenha tudo em minúsculo exceto quando se tratar de um nome próprio, de um sistema ou linguagem (por exemplo MySQL, PHP), nestes casos mantenha o padrão do nome do que você está utilizando. Por exemplo: substituição da integração com o banco de dados MySQL pelo PostgreSQL
- Não utilize ponto final (.)
- Quando for necessário se referir a uma localização, função ou campo específico da aplicação, é recomendável utilizar a tag
code
referente a plataforma que está sendo usada, no caso do GitHub são as três crases (```)
Abaixo segue um exemplo completo:
fix(controller): use cf-connecting-ip
header to get client ip first
Corpo
Uma descrição mais longa para seu commit pode ser fornecido logo após o título, em um campo separado, fornecendo informações contextuais adicoinais sobre o seu commit.
Quebre as linhas a pelo menos cada 72 caracteres, para uma melhor leitura.
Use essa descrição para explicar "o quê" e "por quê" essa alteração foi realizada, ao invés de "como".
Rodapé
O rodapé poderá ser fornecido abaixo de uma linha em branco após o corpo.
Você pode utilizar ele para referenciar um ticket no Jira, tarefa no Asana ou Perfex e outros helpdesks, ou mesmo uma issue no próprio GitHub, conforme o exemplo abaixo:
fixes issue #12
E por quê de tudo isso?
Essas são algumas possibilidades e vantagens que ganhamos ao realizar commits de maneira organizada e sucinta:
- Criação automatizada de CHANGELOGs
- Determina automaticamente um aumento de versionamento semântico com base nos tipos de commit utilizados
- Comunicar para outros colaboradores e interessados a natureza e motivo da alteração, de forma clara e padronizada
- Disparar processos de build e deploy
- Facilita a contribuição de outras pessoas em seus projetos, permitindo que eles explorem um histórico de commits mais estruturado e com uma melhor rastreabilidade e entendimento
Caso de sucesso
Um ótimo exemplo de caso de sucesso utilizando destes padrões, é o próprio TabNews, que na data dessa publicação conta oficialmente com 43 colaboradores
, sendo um repositório bem documentado e estruturado, de forma que todos os envolvidos saibam do que se trata cada novo commit que é enviado!
O TabNews é um fórum fantástico o qual tenho profunda admiração, pois não é um projeto feito 100% pelo nosso adorado Filipe Deschamps, mas sim uma ideia gigante que foi materializada pela própria comunidade e está crescendo cada dia mais, sendo hoje o primeiro site que eu abro durante o meu café da manhã para consumir notícias e conteúdos na área de tecnologia, e fico muito feliz de poder estar contribuindo com conteúdo de qualidade aqui dentro.
Muito obrigado a todos que leram até aqui. Espero que este conteúdo possa ser útil para alguém!
Este post está aberto a sugestões de melhoria e correções para se tornar o melhor informativo possível para a comunidade, basta deixar o seu pull request
aí no campo de respostas!
Vida longa e próspera! 🖖🏻