Executando verificação de segurança...
2

Como automatizar revisões de código com o Danger JS

Com o Google CloudBuild como exemplo

O que é Danger JS?

Danger JS é uma ferramenta de construção de código aberto que permite aos desenvolvedores de software automatizar tarefas comuns de revisão de código. Usando o Danger JS, podemos executar automaticamente um conjunto de regras em relação ao seu Pull Request (PR) e deixar um comentário de revisão de código.

Ele automatiza comentários de revisão de código repetitivos e triviais como:

Este PR é grande, considere dividi-lo para que possamos analisá-lo efetivamente.

ou

Atualize o arquivo changelog.

Isso ajuda os desenvolvedores a se concentrarem na revisão do problema que o PR está tentando resolver, em vez de se distrair com as tarefas de revisão de código.

Cuide automaticamente das tarefas de revisão de código.

Um código de exemplo

Para entender melhor como funciona, vamos pegar um caso de uso comum como exemplo: E se quisermos deixar um comentário se um pull request for muito grande?

Você pode escrever uma função JS usando Danger JS para realizar este caso de uso:

const reviewLargePR = () => {
    const bigPRThreshold = 300;
    if (danger.github.pr.additions + danger.github.pr.deletions > bigPRThreshold) {
        warn(`:exclamation: Pull Request size seems relatively large. If Pull Request contains multiple changes, split each into separate PR for faster, easier review.`);
    }
}

Se o número de linhas alteradas em uma solicitação pull for maior que o bigPRThresholdvalor arbitrário, deixe um comentário de “aviso” na solicitação pull.

Configurando o Danger JS

Abaixo, resumi as etapas envolvidas na configuração do Danger JS em seu CI.

  • Instale o Danger executando yarn add danger —dev ou npm install --save-dev danger.
  • Crie um arquivo de dangerfile e inclua-o na pasta raiz do seu repositório. Pode ser dangerfile.ts ou dangerfile.js.
  • Configure um bot GitHub e/ou gere um token GitHub com acesso suficiente para comentar, aprovar ou rejeitar uma solicitação pull.
  • Consulte esta lista de instruções de configuração que você precisará seguir dependendo do CI que usar.

E se meu CI não for compatível?

Por exemplo, se você deseja usar o Danger JS no CI interno da sua empresa ou no Google Cloud Build. O Google Cloud Build não é um CI compatível no momento da redação.

Temos duas opções para isso:

  • Contribua com o Danger.
  • Use o “modo manual” do Danger , que é o que abordaremos nas próximas seções.

1. Escreva seu Dangerfile

Comece instalando o danger. Usaremos npm para nosso exemplo.

npm install --save-dev danger

Importe o que precisamos do nosso pacote Danger.

import {danger, warn, markdown} from 'danger';

Crie nosso dangerfile.ts. Vamos implementar as seguintes funções:

  • reviewLargePR() Igual ao nosso exemplo de código anterior
  • ensurePRHasAssignee() Reprovar o PR se não houver um cessionário.

nosso dangerfile.ts:

import {danger, warn, fail} from 'danger';
const reviewLargePR = () => {
    const bigPRThreshold = 300;
    if (danger.github.pr.additions + danger.github.pr.deletions > bigPRThreshold) {
        warn(`:exclamation: Pull Request size seems relatively large. If Pull Request contains multiple changes, split each into separate PR for faster, easier review.`);
    }
}
const ensurePRHasAssignee = () => {
    // Always ensure we assign someone, so that our Slackbot can do its work correctly
    if (danger.github.pr.assignee === null) {
    fail("Please assign someone to merge this PR, and optionally include people who should review.")
  }
}
reviewLargePR();
ensurePRHasAssignee();

2. Teste localmente usando o danger-pr

Podemos testar nosso dangerfile localmente usando danger-pr.js. Isso não deixará um comentário na solicitação pull. Ele imprimirá os comentários de PR esperados no terminal. Esta opção nos permite depurar dangerfile localmente sem enviar comentários em um PR real.

Execute o seguinte comando na pasta raiz do seu repositório, na mesma pasta que dangerfile.ts:

# Your GitHub API token
export DANGER_GITHUB_API_TOKEN=<yourtoken>
node_modules/danger/distribution/commands/danger-pr.js https://github.com/danger/danger-js/pull/1192

Em nosso exemplo acima, estamos usando um PR público para o repositório GitHub do Danger JS.. No momento em que escrevo, este PR tem cerca de 7.000~ linhas alteradas. Este número é “grande” de acordo com as regras do nosso Dangerfile.

Nossa saída mostrará que o PR é grande:

3. Execute com danger-ci usando o “Modo Manual”

Danger pode oferecer suporte a CIs que não estão em sua lista de suporte atual usando seu “modo manual”.

Executando o comando Danger-ci

Agora que nosso dangerfile funciona como esperado, vamos executar usando danger-ci localmente. Este comando deixará um comentário no PR que especificamos.

ℹ️ Certifique-se de ter configurado o acesso GitHub necessário ao executar o comando CI.

Defina as variáveis de ambiente

Podemos ativar o modo manual definindo as variáveis de ambiente necessárias.

Defina o nome do seu CI:

# Substitua pelo nome do CI não suportado, por exemplo, CloudBuild
export DANGER_MANUAL_CI=<UNSUPPORTED_CI_NAME>

Especifique seu repositório GitHub:

# Substitua por seu repositório GitHub   
export DANGER_MANUAL_GH_REPO=<githuborg/githubrepo>

Defina seu token de acesso à API do GitHub caso ainda não o tenha feito:

# Substitua por seu token de API do GitHub   
export DANGER_GITHUB_API_TOKEN=<yourtoken>

Execute o comando Danger CI

Agora que definimos as variáveis de ambiente necessárias👆, execute o comando danger-ci:

DANGER_MANUAL_PR_NUM=<Número PR> node_modules/danger/distribution/commands/danger-ci.js

A variável de ambiente DANGER_MANUAL_PR_NUM é o número do PR do PR que queremos que o Danger revise. Por exemplo, se seu PR for: [https://github.com/danger/danger-js/pull/1192](https://github.com/danger/danger-js/pull/1192), a variável de ambiente será DANGER_MANUAL_PR_NUM=1192.

Um exemplo

ℹ️ Observe que temos a opção de escrever um script de shell que execute todos os comandos neste exemplo, em vez de executar os comandos um por vez.

Vamos pegar uma solicitação pull pública do GitHub que configurei como exemplo.

Vamos configurar nossas variáveis de ambiente:

# Substitua pelo nome do seu IC não suportado, por exemplo, CloudBuild   
export DANGER_MANUAL_CI=MyCI   
# Substitua pelo seu repositório GitHub   
export DANGER_MANUAL_GH_REPO=ardydedase/danger-example   
# Substitua pelo token da API do GitHub   
export DANGER_GITHUB_API_TOKEN=<yourtoken>

Em seguida, execute o comando danger-ci com o número do PR, que é 1, neste exemplo:

DANGER_MANUAL_PR_NUM=1 
node_modules/danger/distribution/commands/danger-ci.js

Em nosso exemplo, o PR falha porque não há nenhum usuário atribuído ao PR.

O comentário no PR do GitHub será:

☝️ Estou usando meu token GitHub pessoal para esta demonstração, então é meu nome de usuário que aparece no PR. Idealmente, devemos configurar um bot do GitHub.

Executaremos as mesmas etapas em nosso CI sem suporte: defina as variáveis de ambiente e execute o comando danger-ci. Abordaremos isso na próxima seção. 👇

4. Execute o Danger localmente com um CI não compatível (Google CloudBuild)

Depois de testar nosso dangerfile na Etapa 3, agora estamos prontos para configurar o Danger com nosso CI sem suporte.

Usaremos o Google CloudBuild como nosso CI em nosso exemplo porque:

  • No momento da redação deste artigo, o Google CloudBuild ainda não é um CI compatível com Danger JS.
  • Ele tem uma ferramenta CLI do Local Cloud Builder que podemos usar para testar nossa configuração de compilação YAML localmente.

Pré-requisitos do Google Cloud

Precisaremos de nossa ferramenta CloudBuild CLI instalada para testar nossa compilação Danger com o Google Cloud localmente. Por favor, consulte os documentos vinculados abaixo:

Arquivo de configuração do CloudBuild

Vamos criar nosso arquivo de configuração cloudbuild-local.yaml:

# Meant to be used locally for testing.
steps:
  - name: node:16
    env:
      - 'DANGER_MANUAL_CI=CloudBuild'
      - 'DANGER_MANUAL_GH_REPO=ardydedase/danger-example'
      # TODO: Replace with your own GitHub token
      # - 'DANGER_GITHUB_API_TOKEN=<REPLACE_WITH_YOUR_GH_TOKEN>'
    args:
      - '-c'
      - |
        echo "Running Danger build..."
        npm install
        # PR number is hardcoded for local testing
        DANGER_MANUAL_PR_NUM=1 node_modules/danger/distribution/commands/danger-ci.js
    id: danger-code-review
    waitFor:
      - '-'
    entrypoint: bash

ℹ️ Substitua o GITHUB_API_TOKENpelo seu token.

Quando executamos cloud-build-local, dryruné ativado por padrão, a menos que especifiquemos o contrário. Isso nos dá a opção de verificar a sintaxe de nossa compilação, economizando tempo para testar. Vamos começar executando o comando cloud-build-local abaixo para garantir que nosso arquivo de configuração não tenha nenhum erro de sintaxe:

cloud-build-local --config=./cloudbuild-local.yaml .

Se o comando acima for bem-sucedido, a saída será:

Vamos agora definir o sinalizador dryrun como false para executar a compilação do danger localmente:

cloud-build-local --config=./cloudbuild-local.yaml --dryrun=false .

👆 O comando acima levará alguns minutos para ser concluído. O download da imagem do docker do nó levará mais tempo.

Uma compilação bem-sucedida mostrará uma saída semelhante abaixo:

E também deve deixar um comentário na PR:

5. Configuração do Google Cloud

Agora que nossa configuração local funciona conforme o esperado, podemos usar a mesma configuração em nossa configuração de produção do Cloud Build.

Configuração para ambiente de Produção

Nossa configuração de produção é quase a mesma, exceto que estamos recuperando o número PR do CloudBuild. Em vez de codificar, atribuiremos $_PR_NUMBER a DANGER_MANUAL_PR_NUM.

Nosso comando Danger CI será:

DANGER_MANUAL_PR_NUM=$_PR_NUMBER 
node_modules/danger/distribution/commands/danger-ci.js

Também devemos armazenar nosso token da API do GitHub no Gerenciador de segredos do Google Cloud ou em qualquer gerenciador de "segredos" que você esteja usando.

Se estivermos usando o gerenciador de segredos do Google, precisaremos atualizar nossa configuração de compilação para usá-lo:

availableSecrets:   
 secretManager:   
 - versionName: projects/$PROJECT_ID/secrets/<my-github-token>/versions/1   
 env: DANGER_GITHUB_API_TOKEN

Substitua <my-github-token> pelo seu nome secreto.

Nossa configuração de compilação usando o número $_PR_NUMBER e o segredo da solicitação pull do Secrets Manager. Arquivo danger-cloudbuild-prod.yaml:

steps:
  - name: node:16
    env:
      - 'DANGER_MANUAL_CI=CloudBuild'
      - 'DANGER_MANUAL_GH_REPO=ardydedase/danger-example'
    args:
      - '-c'
      - |
        echo "Running Danger build..."
        npm install
        # PR number is hardcoded for local testing
        DANGER_MANUAL_PR_NUM=$_PR_NUMBER node_modules/danger/distribution/commands/danger-ci.js
    id: danger-code-review
    waitFor:
      - '-'
    entrypoint: bash
    secretEnv:
      - DANGER_GITHUB_API_TOKEN    

availableSecrets:
  secretManager:
    - versionName: projects/$PROJECT_ID/secrets/<my-github-token-key>/versions/1
      env: DANGER_GITHUB_API_TOKEN  

Configurar a trigger do CloudBuild

A última etapa é configurar nossa trigger (gatilho) CloudBuild para garantir que funcione conforme o esperado.

No Google Cloud Console, criando um novo Trigger no CloudBuild:

Ao criar seu gatilho, certifique-se de selecionar "Pull request" como o evento. Isso dá ao nosso arquivo de configuração acesso a $_PR_NUMBER. Se não fizermos isso, $_PR_NUMBERretornará uma string vazia.

Escolha Repositório como o local para o nosso arquivo de configuração. Especifique o caminho para nosso arquivo de configuração de compilação.

Você pode deixar o restante dos campos de entrada como estão.

Isso é tudo que precisamos. Agora você tem uma boa configuração do Google CloudBuild com revisões de código automatizadas fornecidas pelo Danger JS!

ℹ️ Embora escrevamos nosso Dangerfile usando TypeScript ou JavaScript, o Danger JS pode funcionar com qualquer base de código, independentemente da linguagem de programação.

Você pode encontrar o repositório GitHub aqui para sua referência:

https://github.com/ardydedase/danger-example

Carregando publicação patrocinada...