Um (pequeno)guia para verificar o padrão de commits no git usando huksy 7.x: Parte 1
Olá pessoal, neste post irei criar um pequeno guia sobre como aumentar a qualidade do seu código através do uso do huksy 7.X para verificar o padrão do commit no hook commit-msg do git.
Mas antes precisamos conversar um pouco sobre o breaking change que aconteceu do husky 4.x para o 5.x
No husky versão 4.X no hook commit-msg do git, era possível ler as informações do commit através da variável de ambiente HUSKY_GIT_PARAMS “setada” pelo husky.
O valor da variável de ambiente HUSKY_GIT_PARAMS enviada pelo husky irá ter o caminho do arquivo gerado pelo git contendo a mensagem do commit.
Logo, podemos ler o conteudo deste arquivo gerado pelo git quando o hook de commit-msg é lançado, porém no husky 7.x temos o problema do desuso daesta variável de ambiente segundo a documentação oficial abaixo.
Environment variables:
HUSKY_SKIP_HOOKS
becomesHUSKY
.HUSKY_SKIP_INSTALL
is removed.HUSKY_GIT_PARAMS
is removed. Instead, Git parameters should be used directly in scripts (e.g.$1
).PATH
for locally installed tools is not automatically set anymore. You'll need to use your package manager to run them.
Logo, no husky 7.X devemos substituir a variável de ambiente HUSKY_GIT_PARAMS pelo argumento $1.
Para facilitar o entendimento irei colocar nesta primeira parte do post o uso do commitlint para analisar o padrão do commit e na segundo post irei mostrar como criar regras customizadas sem a necessidade do uso do commitlint para analisar o padrão dos commits.
1. Usando o framework commitlint
O commitlint tem como proposta ajudar na verificação na padronização do commit através de regras pré-estabecidas pelo framework ou através da criação de novas utilizando o conceito de plugins.
Uma das possibildades para facilitar a configuração das regras, seguindos as boas práticas sugeridas pelo site conventional commit pattern, é através do uso do plugin @commitlint/config-conventional no qual já vem com várias regras pré-configuradas usandos estas boas práticas.
Porém antes de tudo, o que precisamos fazer é criar um novo arquivo na raiz do projeto seguindo um dos padrões abaixo
.commitlintrc
.commitlintrc.json
.commitlintrc.yaml
.commitlintrc.yml
.commitlintrc.js
.commitlintrc.cjs
.commitlintrc.ts
commitlint.config.js
commitlint.config.cjs
commitlint.config.ts
commitlint
field inpackage.json
Fonte: https://github.com/conventional-changelog/commitlint#config
Em seguida colocar o conteúdo abaixo no arquivo, no qual vai seguir as regras do @commitlint/config-conventional.
module.exports = { extends: ['@commitlint/config-conventional'],}
Por fim, adicionar as dependências das bibliotecas no arquivo package.json e instala-las usando o comando yarn install ou npm install.
"devDependencies": { "@commitlint/cli": "16.1.0", "@commitlint/config-conventional": "16.0.0",}
Integrando com o husky 7.x
Para integrar o commitlint com o husky o que devemos fazer é criar um hook no evento commit-msg gerado pelo git, através do uso do comando abaixo que irá utilizar inclusive o novo argumento $1 explicado na seção breaking change.
O comando abaixo precisa apenas ser rodado uma única vez para o hook ser criado.
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'
Regras do commitlint
Algo importante que deve ser comentado é que você pode usar as regras pré-definidas do commitlint ou criar algumas customizadas.
Para mais detalhes sobre como usar as regras pré-definidas eu recomendo uma leitura na documentação oficial.
Basicamente vocẽ vai precisar adicionar uma nova regra pré-existente no arquivo criado no passo anterior seguindo a sintaxe abaixo.
Sintaxe:
- Level
[0..2]
:0
disables the rule. For1
it will be considered a warning for2
an error. - Applicable
always|never
:never
inverts the rule. - Value: value to use for this rule.
Fonte: https://github.com/conventional-changelog/commitlint/blob/master/docs/reference-rules.md
Exemplo:
Digamos que o nosso use case é que todo branch deva possuir um dos nomes abaixo.
- improv
- build
- chore
- ci
- docs
- feat
- fix
- perf
- refactor
- revert
- style
- test
Bem, para resolver este problema, tudo o que precisamos fazer é usar a rule pré-definida chamada type-enum e preencher os valores do nome esperado do branch no 3 item do array, conforme mostrado no código abaixo.
Para mais detalhes da configuração usada acima você pode dar uma olhada no meu repositório abaixo.
Pronto, todo vez que você rodar o commitlint ele irá verificar se o seu branch esta de acordo com a regra acima.
Regras customizadas no commitlint
No cenário onde você vai precisar criar suas regras customizadas é recomendável criar um novo plugin seguindo a documentação oficial.
Para exeplificar, digamos que precisamos verificar se o nome do branch tem o padrão de uma task do jira seguindo o padrão “project-number”, ou seja, “project-1020”.
Como iremos verificar este ponto? Uma boa alternativa seria usarmos regex como iremos ver a seguir.
Primeiro, vamos precisar criar o nosso regex para identificar o pattern do branch, conforme código abaixo.
/project-[0-9]+$/gm
Você pode usar o site https://regex101.com/ para testar o seu regex ou até mesmo criar um novo. Neste site tem uma documentação bem vasta que irá ajuda-lo a construir o regex que atenda as suas necessidades.
Em seguida vamos precisar criar um novo plugin com uma nova regra chamada type-enum/check-jira-branch-pattern que terá como objetivo verificar o padrão do branch do jira usando o regex, de acordo com o código abaixo.
Por ultimo, vamos precisar adicionar o parseOpts para o commitlint utilizar o hyphen como parte do parse do nome do branch, desabilitar a regra type-enum para não verificar o padrão do branch extendido da configuração @commitlint/config-conventioinal e finalmente usar a nossa nova regra, conforme descrito na linha 24 na propriedade Rules.
Com o intuito de facilitar o entendimento da criação de uma regra customizada no commitlint, eu convido vocẽs a lerem o fluxograma abaixo.
Logo, após a gente definir estas regras customizadas no nosso arquivo commitlint.config.js o commitlint irá utiliza-las para verificar se a mensagem do commit esta de acordo com o padrão regex “project-[número]” e caso tenha algo errado o framework irá expor os erros encontrados, consoante irei mostrar na próxima seção.
Testando as regras com o commitlint CLI
Um detalhe muito importante que me ajudou a testar as regras do meu commit foi através do uso do commitlint CLI.
Basicamente ele é um CLI que irá rodar e verificar se uma mensagem esta de acordo com as regras pré-definidas no arquivo de configuração que criamos acima.
Para rodar o commitlint CLI, é bem simples. Tudo o que precisamos fazer é rodar o comando abaixo em um terminal e para verificar se a nossa mensagem esta de acordo com o esperado.
echo "project-321: random message" | ./node_modules/.bin/commitlint
E caso a gente passe algo fora do padrão das regras, então o commitlint irá mostrar os erros encontrados.
echo "project-321E: random message" | ./node_modules/.bin/commitlint
Conclusão
Em síntese espero que esta primeira parte do post tenha ajudado vocês a entender um pouco do poder do commitlint tem em cojunto com o husky para verificar a padronização da mensagem dos commits e principalmente manter a qualidade no projeto.
Não esquecendo que irei escrever uma segunda parte deste post com o objetivo de mostrar como criar regras de verificação de mensagem de commit usando typescript puro sem o uso do commitlint.
Se você gostou do post não esqueça de apertar no 👏.