Publicado em

Como Automatizar Code Reviews com Gemini e GitHub Actions

Autores

AI Code Reviews on GitHub


Introdução

Você já deve ter ouvido falar de ferramentas como Code Rabbit, What the Diff e a mais nova BugBot do Cursor, que fazem o code review de pull requests com IA, certo? Mas você já se perguntou como será que elas funcionam por debaixo dos panos? Bom, eu já, e neste artigo vou lhe mostrar como criar um workflow para revisar suas PRs de forma automática simplesmente adicionando uma label nelas.


O que vamos criar?

Vamos criar uma GitHub Action que:

  • É acionada quando uma label ai-review é adicionada na PR
  • Lê os arquivos modificados ("diff" de código)
  • Envia o conteúdo para a API do Gemini com um prompt solicitando a revisão do código
  • Comenta automaticamente o resultado da IA na pull request

Pré-requisitos

Antes de começarmos, você vai precisar de:

  • Um repositório no GitHub com alguma PR aberta para testes
  • Acesso ao Google AI Studio para gerar uma chave da API do Gemini
  • Permissões para criar secrets e configurar workflows no seu repositório
  • Uma tesoura sem ponta (brincadeira)

Configurando os acessos e secrets

Obtendo a chave de API do Gemini

Antes de configurar o secret no GitHub, você precisa obter sua chave de API do Google AI Studio:

  1. Acesse o Google AI Studio

  2. Faça login com sua conta Google

  3. Clique em "Get API key" no canto superior direito

  4. Selecione "Create API key" para gerar uma nova chave Obter API Key do Gemini

  5. Copie a chave gerada (ela será exibida apenas uma vez)

  6. Guarde essa chave em um local seguro - você vai precisar dela no próximo passo


Criando o Secret GEMINI_API_KEY no GitHub

  1. Vá até o repositório no GitHub
  2. Acesse Settings > Secrets and variables > Actions
  3. Clique em "New repository secret"
  4. Nome: GEMINI_API_KEY
  5. Valor: cole a chave de API que você copiou no passo anterior Criar secret no GitHub

Criando a GitHub Action

Vamos construir o workflow passo a passo. Primeiro, crie um novo arquivo no seu repositório:

.github/workflows/ai-review.yml

Passo 1: Configurando o trigger

Começamos definindo quando nossa action deve ser executada. Queremos que ela rode apenas quando uma label específica for adicionada à PR:

name: Review Pull Request with Gemini

on:
  pull_request:
    types: [labeled] # Only trigger when labels are added

jobs:
  review:
    runs-on: ubuntu-latest
    if: github.event.label.name == 'ai-review'

Explicação:

  • types: [labeled] - A action só executa quando uma label é adicionada (não quando a PR é criada)
  • if: github.event.label.name == 'ai-review' - Só executa se a label for exatamente ai-review

Passo 2: Fazendo checkout do código

Precisamos baixar o código da PR para analisá-lo:

steps:
  - name: Checkout PR code
    uses: actions/checkout@v4
    with:
      fetch-depth: 0

Explicação:

  • fetch-depth: 0 - Baixa todo o histórico do git para podermos comparar com a branch base

Passo 3: Identificando arquivos modificados

Agora vamos descobrir quais arquivos foram alterados na PR:

- name: Get changed files
  id: files
  run: |
    # Fetch the base branch (usually main or master)
    git fetch origin ${{ github.event.pull_request.base.ref }}

    # Get changed files between base branch and current PR
    echo "CHANGED_FILES=$(git diff --name-only origin/${{ github.event.pull_request.base.ref }}...HEAD | grep '\.js\|\.ts\|\.tsx\|\.md\|\.css\|\.json\|\.yml\|\.yaml\|\.sh\|\.md' | tr '\n' ',' | sed 's/,$//')" >> $GITHUB_OUTPUT

Explicação:

  • git diff --name-only - Lista apenas os nomes dos arquivos modificados
  • grep - Filtra apenas arquivos de código/texto (excluindo imagens, binários, etc.)
  • tr '\n' ',' - Converte quebras de linha em vírgulas para facilitar o processamento

Passo 4: Lendo o conteúdo dos arquivos

Vamos ler o conteúdo de todos os arquivos modificados:

- name: Read file contents
  id: read
  run: |
    mkdir -p output
    CHANGED_FILES="${{ steps.files.outputs.CHANGED_FILES }}"
    if [ -z "$CHANGED_FILES" ]; then
      echo "No changed files found" > output/combined.txt
    else
      for file in $(echo "$CHANGED_FILES" | tr ',' '\n'); do
        if [ -f "$file" ]; then
          echo ">>>>> $file" >> output/combined.txt
          cat "$file" >> output/combined.txt
          echo -e "\n\n" >> output/combined.txt
        fi
      done
    fi

Explicação:

  • Criamos um arquivo combined.txt com todo o código modificado (toda a diff)
  • Cada arquivo é precedido por >>>>> nome_do_arquivo para identificação
  • Se não houver arquivos modificados, criamos um arquivo vazio

Passo 5: Enviando para a API do Gemini

Agora a parte mais interessante - vamos enviar o código para a IA analisar:

- name: Send to Gemini API
  id: gemini
  if: steps.files.outputs.CHANGED_FILES != ''
  env:
    GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
  run: |
    jq -n \
      --arg prompt "Você é um assistente que faz revisão de código. Dado o código abaixo, comente melhorias, problemas ou boas práticas que se aplicam. Código:" \
      --rawfile code output/combined.txt \
      '{
        "contents": [{
          "parts": [{
            "text": ($prompt + "\n\n" + $code)
          }]
        }]
      }' > request.json

    # Make the API request using the JSON file
    RESPONSE=$(curl -s -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:generateContent?key=${GEMINI_API_KEY}" \
      -H "Content-Type: application/json" \
      -d @request.json)

    # Extract the review text from response
    REVIEW_TEXT=$(echo "$RESPONSE" | jq -r '.candidates[0].content.parts[0].text // "Error processing API response"')

    echo "REVIEW<<EOF" >> $GITHUB_OUTPUT
    echo "$REVIEW_TEXT" >> $GITHUB_OUTPUT
    echo "EOF" >> $GITHUB_OUTPUT

Explicação:

  • jq -n - Cria um JSON com o prompt e o código
  • jq -r - Extrai o texto da resposta da IA
  • REVIEW<<EOF - Salva o resultado em uma variável de output do GitHub Actions

Passo 6: Comentando na PR

Finalmente, vamos postar o resultado da análise na própria pull request:

- name: Comment on PR
  if: steps.files.outputs.CHANGED_FILES != ''
  uses: peter-evans/create-or-update-comment@v4
  with:
    token: ${{ secrets.GITHUB_TOKEN }}
    issue-number: ${{ github.event.pull_request.number }}
    body: |
      🤖 **Revisão de Código do Gemini**
      ---
      ${{ steps.gemini.outputs.REVIEW }}

Explicação:

  • Usa a action peter-evans/create-or-update-comment para comentar na PR. Acesse a documentação para mais detalhes.
  • ${{ secrets.GITHUB_TOKEN }} - Token automático do GitHub para autenticação
  • ${{ github.event.pull_request.number }} - Número da PR atual

Arquivo completo

Aqui está o arquivo completo que você deve salvar como .github/workflows/ai-review.yml:

name: Review Pull Request with Gemini

on:
  pull_request:
    types: [labeled] # Only trigger when labels are added

jobs:
  review:
    runs-on: ubuntu-latest
    if: github.event.label.name == 'ai-review'

    steps:
      - name: Checkout PR code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Get changed files
        id: files
        run: |
          # Fetch the base branch (usually main or master)
          git fetch origin ${{ github.event.pull_request.base.ref }}

          # Get changed files between base branch and current PR
          echo "CHANGED_FILES=$(git diff --name-only origin/${{ github.event.pull_request.base.ref }}...HEAD | grep '\.js\|\.ts\|\.tsx\|\.md\|\.css\|\.json\|\.yml\|\.yaml\|\.sh\|\.md' | tr '\n' ',' | sed 's/,$//')" >> $GITHUB_OUTPUT

      - name: Read file contents
        id: read
        run: |
          mkdir -p output
          CHANGED_FILES="${{ steps.files.outputs.CHANGED_FILES }}"
          if [ -z "$CHANGED_FILES" ]; then
            echo "No changed files found" > output/combined.txt
          else
            for file in $(echo "$CHANGED_FILES" | tr ',' '\n'); do
              if [ -f "$file" ]; then
                echo ">>>>> $file" >> output/combined.txt
                cat "$file" >> output/combined.txt
                echo -e "\n\n" >> output/combined.txt
              fi
            done
          fi

      - name: Send to Gemini API
        id: gemini
        if: steps.files.outputs.CHANGED_FILES != ''
        env:
          GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
        run: |
          # Create the request JSON file to avoid argument list too long error
          jq -n \
            --arg prompt "Você é um assistente que faz revisão de código. Dado o código abaixo, comente melhorias, problemas ou boas práticas que se aplicam. Código:" \
            --rawfile code output/combined.txt \
            '{
              "contents": [{
                "parts": [{
                  "text": ($prompt + "\n\n" + $code)
                }]
              }]
            }' > request.json

          # Make the API request using the JSON file
          RESPONSE=$(curl -s -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:generateContent?key=${GEMINI_API_KEY}" \
            -H "Content-Type: application/json" \
            -d @request.json)

          # Extract the review text from response
          REVIEW_TEXT=$(echo "$RESPONSE" | jq -r '.candidates[0].content.parts[0].text // "Error processing API response"')

          echo "REVIEW<<EOF" >> $GITHUB_OUTPUT
          echo "$REVIEW_TEXT" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: Comment on PR
        if: steps.files.outputs.CHANGED_FILES != ''
        uses: peter-evans/create-or-update-comment@v4
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          issue-number: ${{ github.event.pull_request.number }}
          body: |
            🤖 **Revisão de Código do Gemini**
            ---
            ${{ steps.gemini.outputs.REVIEW }}

Bora testar

  1. Acesse a página de edição de labels do GitHub
https://github.com/SEU-USUARIO/SEU-PROJETO/issues/labels
  1. Crie a label "ai-review"

Criando a label "ai-review" no GitHub

  1. Acesse a PR no GitHub
  2. Adicione a label "ai-review" na sua PR

Adicionando a label "ai-review" na PR

  1. A Action será acionada e, em alguns instantes, um comentário com o review da IA aparecerá na sua PR

AI Code Reviews on GitHub

A partir dai, sempre que você precisar que a review seja refeita, basta remover e readicionar a label novamente.


Dicas e personalizações

  • Você pode ajustar o prompt enviado ao Gemini para focar em segurança, performance ou padrões específicos
  • Para evitar chamadas desnecessárias, limite os arquivos analisados por extensão (como apenas .js, .css, etc...)
  • Obviamente a Action pode ser adaptada para funcionar com outras IAs (Claude, GPT, Mistral...), só toma cuidado com a fatura do cartão! ⚠️
  • É muito fácil aplicar as correções sugeridas copiando o comentário da PR e colando no Cascade do Cursor, sem necessidade de habilitar o Max Mode como é o caso do BugBot

Conclusão

É possível integrar IA para realizar o code review diretamente no seu GitHub sem se comprometer com mais uma assinatura em seu cartão. É claro que nesse caso a responsabilidade de iterar e aprimorar a solução também fica por sua conta 😅.

O que aprendemos

Neste tutorial, você aprendeu a:

  • Configurar uma GitHub Action que responde a labels específicas
  • Identificar arquivos modificados em pull requests
  • Integrar com a API do Gemini para análise de código
  • Automatizar comentários em PRs

Próximos passos

Agora que você tem o básico funcionando você pode tentar:

  • Personalizar o prompt para focar em aspectos específicos do seu projeto
  • Adicionar filtros para diferentes tipos de arquivo
  • Integrar com outras IAs como Claude ou GPT
  • Criar workflows específicos para diferentes tipos de revisão

Recursos úteis

Lembre-se: a IA é uma ferramenta poderosa, mas não substitui a revisão humana. Use-a como um complemento para identificar possíveis problemas e melhorias, mas sempre mantenha o olho crítico sobre o código que está sendo revisado.

Vamoo! 🚀