Code review automatizado com Danger JS

Rebeca Lopes
7 min readOct 19, 2021

--

Automatize suas reviews e não perca mais tempo com o básico

Mas afinal o que é um code review?

Bom, para falarmos sobre code review automatizado, primeiro temos que voltar um pouco e entender o que é e como se faz um code review.

A definição ao pé da letra nada mais é do que “revisão de código”. A revisão de código consiste em pessoas do seu time que irão revisar o seu código antes da sua PR(Pull Requests) ser aprovada para merge. O time pode estabelecer certos padrões a serem respeitados sempre que uma PR for enviada.

Como fazer um code review ?

Lembrando que review de código não é para humilhar a pessoa que fez a PR, ou de alguma forma desmerecer o trabalho da pessoa. A review é utilizada para manter o código o mais conciso e padronizado possível. Revisores de código precisam se preocupar em entender o que a pessoa escreveu no código, e caso seja necessário alterar algo no código para um melhor entendimento ou para deixa-lo mais clean, irão fazer comentários construtivos junto ao código e deixar exemplos de como seria uma melhor implementação daquele mesmo código.

Exemplo de comentário em code review

Veja no exemplo acima, não foi apenas informado que algo poderia ser melhor, também foi deixado um exemplo de código. Claro, isso depende de cada pessoa, eu gosto de sempre exemplificar e não apenas dizer algo como: “este código pode ser melhorado”, e nem ao menos dizer o que de fato pode ser melhorado nele.

O que observar em um code review?

Algumas questões podem ser observadas em um code review:

  • Designer Patterns: se o projeto possui padrões de código que devem ser seguidos
  • Clean Code: legibilidade de código, manutenibilidadede código, nome de variaveis, escopo de funções, padrões SOLID, etc
  • Arquitetura: cada projeto possui uma arquitetura única e é importante que o time siga a arquitetura implementada
  • Lógica: a lógica de um código é muito subjetiva, cada programador e programadora possui uma, mas sempre podemos verificar se aquele lógica implementada pode ser otimizada
  • Testes: ao trabalharmos com códigos que possuem testes, é imprescindível que testes sejam criados e/ou corrigidos de acordo com o código feito
  • Versionamento: se trabalha com versionamento de pacotes e/ou CHANGELOG.MD é sempre importante mantê-los atualizados
  • Nome e descrição da PR: se o time mantém um padrão para nome de PRs e o que estiver escrito na descrição da PR, é importante manter esse padrão

Existem, muitas outras verificações que seu time pode fazer em code reviews, listei essas que são as mais básicas.

Automatizando review com Danger JS

Agora que já entendemos o que é um code review, e como pode ser feito, vamos ver agora como podemos automatizar esse processo de olhar código e comentar o que precisa ser feito.

Imagine que você tenha um time diversificado de senioridades, e de pessoas que acabaram de entrar na equipe. Certamente as pessoas mais juniores e/ou que são recente na equipe podem não ter ainda assimilado todo o padrão do time, e impreterivelmente enviarão PRs despadronizadas, e está tudo bem, é assim mesmo, o code review existe para isso.

Agora, imagina ter que dar conta de coisas básicas como nome e descrição de PRs e/ou averiguar se testes foram criados para determinada função e você ainda possui outras revisões a serem feitas. Por isso, automatizar certas revisões é a melhor saída, assim podemos nos preocupar com uma revisão mais focada na qualidade do código.

Configurando Danger JS no projeto

Danger JS é uma lib que instalamos no projeto e que irá ler um arquivo dangerfile.js e executar algumas verificações no processo de CI.

Primeiro passo é instalar o danger js. Na raiz do projeto execute:

yarn add danger -D

Após instalado você irá criar um arquivo chamado dangerfile.js é nesse arquivo que iremos colocar nossas regras de validação que serão lidas ao enviarmos nossas PRs.

Primeira coisa que fazemos nesse arquivo é importar algumas funções de dentro do danger

import { danger, warn, fail } from "danger"

A função danger é usada para fazermos a ligação entre git e commits. Já a warn e fail serão utilizas para informar o que deve ser alterado no código ou estrutura. Veja o exemplo de uso abaixo:

const componentsFiles = danger.git.fileMatch("packages/shared/components/src/ui-components/**"
)

No exemplo acima, foi criada uma constante que receberá algumas informações referente a modificações nos arquivos que estão dentro da pasta ui-components. As informações que o danger pode nos fornecer basicamente são essas:

  • Created: se foi criado algum arquivo novo dentro dessa pasta
  • Deleted: se foi deletado algum arquivo dentro dessa pasta
  • Edited: se foi editado algum arquivo dentro dessa pasta
  • Modified: é a junção de criado e editado, portanto verifica se algum arquivo dentro da pasta foi criado ou editado

Com essas informações já conseguimos verificar a seguinte situação:

Foi criado um novo componente, mas não foi criado para ele teste de componentes

Se seu time estabeleceu que todo componente novo deve ser criado os testes, então podemos automatizar essa verificação com danger. Veja como é simples:

//Verificando o caminho da pasta onde estão os componentes
const componentsFiles = danger.git.fileMatch("packages/shared/components/src/ui-components/**")
//Verificando o caminho da pasta onde estão os testes para componentes
const componentsTestFiles = danger.git.fileMatch("packages/shared/components/__tests__/**")
//Criando a regra de validação
if (componentsFiles.modified && !componentsTestFiles.edited) {
warn("Ops! Houve mudanças nos arquivos de UI-components, mas não houve mudança nos Testes. Lembre-se: isso é OK caso seja uma refatoração 😅")}

No exemplo acima, simplesmente pegamos o caminho de onde estão os componentes e também o caminho onde estão os testes para os componentes. Então, na regra verificamos se houve alteração(edição e/ou criação) de um novo componente e não houve alteração nenhuma dentro da pasta de testes, iremos informar uma mensagem de warn para que a pessoa se atente a escrever os testes.

Podemos executar localmente para verificar se esta funcionando:

yarn danger local

No nosso exemplo, no projeto aqui de estudo, eu modifiquei um componente e não modifiquei os testes, ao rodar o comando acima é apresentado no terminal:

Perfeito! Está funcionando corretamente.

Agora vamos configurar regras para nossos package.json. Caso seu time utiliza o versiomento manual dos pacotes, poderá ocorrer de alguém sem querer versionar errado e mandar uma versão anterior a que deveria ser enviada. Vamos fazer a validação dessas versões da seguinte forma:

//Percorre todos os arquivos modificados e verifica quais incluem o "package.json"
danger.git.modified_files.forEach(file => {
if
(file.includes("package.json")) {danger.git.JSONDiffForFile(file).then(diff => {if (diff.version?.after < diff.version?.before) {
fail(`Ops! A versão(${diff.version.after}) do pacote em ${file} enviado é menor do que a versão(${diff.version.before}) do pacote anterior, verifique e evie a PR novamente ⛔`)}})}})

Veja que existe a função JSONDiffForFile ela é responsável por verificar o que foi alterado dentro de todos os packages.json do projeto.

Então podemos fazer a seguinte validação:

diff.version?.after < diff.version?.before

Caso a versão posterior seja menor do que a versão anterior, então o danger irá falhar o build da PR e informar qual pacote e quais versões foram enviadas:

fail(`Ops! A versão(${diff.version.after}) do pacote em ${file} enviado é menor do que a versão(${diff.version.before}) do pacote anterior, verifique e envie a PR novamente ⛔`)

Agora, podemos configurar também algumas regras de validação depois que a PR já foi criada, por exemplo, tamanho da PR e nome da PR.

//Defino qual nome a PR precisa ter
const hasPRCorrectTitle = danger.github.pr.title.includes("fix:") ||danger.github.pr.title.includes("WIP")
if (!hasPRCorrectTitle) { //Validação do nome
fail(`Ops! Titulo da PR esta incorreto. Um exemplo correto seria [BS-2802] ${danger.github.pr.title} ou fix: ${danger.github.pr.title}`)
}
//Defino qual o tamanho máximo a PR precisa ter entre linhas criadas e excluidas
const hasNumberOfLinesAddedInPRAllowed = danger.github.pr.additions + danger.github.pr.deletions > 1500
if (hasNumberOfLinesAddedInPRAllowed) { //Validação do tamanho
warn("Eita! Essa PR parece grande demais 😱. Se possivel divida a PR em duas ou mais partes e envie novamente")
}

ATENÇÃO: Essas verificações que são feitas somente após a PR ser criada, não poderá ser validada com o comando yarn danger local.

Exemplo de como ficará o comentário do danger no github na PR enviada:

Algumas considerações

Para que o danger possa ser implementado você precisa ter um pipeline de ações a ser executado. Na empresa onde trabalho foi integrado o danger com o teamCity, pois é a ferramenta que usamos para buildar o projeto e realizar o deploy. Mas você pode integrar facilmente com o github actions. Vou deixar aqui um exemplo de configuração:

name: "PR: Danger"on:pull_request:branches:- "hmg"jobs:    danger:    runs-on: ubuntu-latest    steps:      - uses: actions/setup-node@v2      - uses: actions/checkout@v2      - run: yarn install      - run: yarn danger ci        env:         GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Conclusão

Code reviews são impreensindíveis para a saúde do projeto. Se seu time não implementa essa boa prática, comece a repensar o quanto seu código precisa ter um cuidado maior. Caso seu time já possua essa boa prática, ótimo, vamos subir para um novo nível automatizando boa parte do que precisa ser revisado? Se sua resposta foi “sim”, então utilize o danger para essa automatização e tenha mais tempo para se preocupar com o que realmente importa: a qualidade em si do código.

Referências: https://danger.systems/js/

--

--

Rebeca Lopes

Frontend developer at Beta Learning. Currently works with technologies such as Javascript, CSS, VueJS, NuxtJS and studies others such as ReactJS and NextJS