DevOps

Protegendo Branches e Revisando Código com Pull Requests Já leu

7 min de leitura

Protegendo Branches e Revisando Código com Pull Requests
Em equipes sem processo de revisão, é comum encontrar código que foi direto para produção sem que nenhum outro par de olhos o

Em equipes sem processo de revisão, é comum encontrar código que foi direto para produção sem que nenhum outro par de olhos o tivesse lido. Bugs que poderiam ter sido detectados em segundos chegam a clientes. Vulnerabilidades de segurança passam despercebidas. Decisões de arquitetura questionáveis se acumulam silenciosamente.

O Pull Request — ou PR — é o mecanismo pelo qual uma mudança proposta é revisada, discutida e aprovada antes de ser integrada. Combinado com regras de proteção de branches, ele cria uma barreira de qualidade que não pode ser contornada — nem acidentalmente, nem intencionalmente.


Configurando Proteção de Branch no GitHub

As regras de proteção são configuradas em Settings → Branches → Add branch protection rule no repositório do GitHub.

As configurações mais importantes:

Require a pull request before merging — impede que qualquer pessoa faça push direto na branch protegida. Todo código precisa chegar via PR.

Require approvals — define quantas aprovações são necessárias antes que o PR possa ser mergeado. Para equipes pequenas, uma aprovação é suficiente. Para sistemas críticos, duas ou mais.

Require status checks to pass before merging — impede o merge se qualquer check de CI estiver falhando. Quando combinado com o GitHub Actions do artigo anterior, o pipeline de testes se torna uma porta obrigatória.

Require branches to be up to date before merging — garante que a branch do PR está atualizada com a branch destino antes do merge, evitando que código desatualizado passe nos testes mas quebre após o merge.

Include administrators — aplica as regras também aos administradores do repositório. Sem essa opção, administradores podem contornar todas as proteções.


Criando um Pull Request

O fluxo completo, do início ao merge:

# Cria e muda para uma nova branch
git checkout -b feature/adicionar-healthcheck

# Faz as alterações necessárias
cat > healthcheck.sh << 'EOF'
#!/bin/bash
curl -f http://localhost:3000/health || exit 1
EOF

chmod +x healthcheck.sh
git add healthcheck.sh
git commit -m "feat: adiciona script de healthcheck da aplicação"

# Envia a branch para o GitHub
git push origin feature/adicionar-healthcheck

Após o push, o GitHub exibe automaticamente um botão para criar o Pull Request. Alternativamente, pela linha de comando com o GitHub CLI:

# Instala o GitHub CLI se necessário
# sudo apt install gh

gh pr create \
  --title "feat: adiciona script de healthcheck" \
  --body "Adiciona script que verifica se a aplicação está respondendo na porta 3000." \
  --base main

Anatomia de um Bom Pull Request

Um PR bem escrito economiza tempo de todos. Os elementos essenciais:

Título — claro, conciso, seguindo a convenção de commits do projeto. feat: adiciona healthcheck é melhor que atualizações diversas.

Descrição — responde três perguntas: o que foi feito, por que foi feito, e como testar. Um template pode padronizar isso para toda a equipe.

Tamanho — PRs menores são revisados mais rapidamente e com mais qualidade. Um PR com 50 linhas recebe revisão cuidadosa. Um PR com 800 linhas recebe um clique em "Approve" e uma oração.

Para criar um template padrão de PR, cria-se o arquivo .github/pull_request_template.md no repositório:

## O que foi feito
<!-- Descreva brevemente as mudanças -->

## Por que foi feito
<!-- Contexto e motivação -->

## Como testar
<!-- Passos para validar as mudanças -->

## Checklist
- [ ] Testes adicionados ou atualizados
- [ ] Documentação atualizada se necessário
- [ ] Sem secrets ou informações sensíveis no código

Realizando uma Revisão de Código

Ao revisar um PR, o GitHub oferece três opções: Comment (comentário neutro), Approve (aprovação) e Request changes (solicitação de mudanças).

Boas práticas para quem revisa:

Comentários devem ser específicos e acionáveis. "Isso está errado" não ajuda. "Esse loop pode ser substituído por Array.map para maior legibilidade — veja linha 23" ajuda.

Distingue-se entre bloqueadores reais e sugestões. Um comentário que começa com nit: sinaliza que é uma observação menor, não um bloqueador para o merge.

Aprova-se o que está bom, não apenas o que é perfeito. Perfeccionismo em code review cria gargalos e desmotiva equipes.


Merge Strategies: Qual Escolher

O GitHub oferece três estratégias de merge, cada uma com implicações diferentes para o histórico:

Merge commit — preserva todos os commits da branch e adiciona um commit de merge. O histórico fica completo, mas pode ficar verboso.

main: A - B - C - M
               \  /
feature:        D - E

Squash and merge — comprime todos os commits da branch em um único commit na branch destino. O histórico fica limpo, mas perde-se a granularidade dos commits intermediários.

main: A - B - C - DE

Rebase and merge — reaplica os commits da branch sobre a ponta da branch destino, sem criar um commit de merge. Histórico linear, mas reescreve os hashes dos commits.

main: A - B - C - D' - E'

Para projetos que seguem Git Flow, o merge commit com --no-ff é o mais adequado — preserva a evidência de que aquele conjunto de commits veio de uma feature branch. Para projetos com deploy contínuo e PRs pequenos, squash and merge produz um histórico mais legível.


Automatizando Revisões com GitHub Actions

O pipeline do artigo anterior pode ser conectado diretamente ao processo de PR. Com a proteção de branch configurada para exigir que os checks passem, o GitHub Actions age como um revisor automático que valida antes de qualquer humano:

name: Validação de Pull Request

on:
  pull_request:
    branches: [ main ]

jobs:
  validar:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Verifica tamanho do PR
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          LINHAS=$(git diff origin/main...HEAD --stat | tail -1 | grep -o '[0-9]* insertion' | grep -o '[0-9]*')
          echo "Linhas adicionadas: $LINHAS"
          if [ "${LINHAS:-0}" -gt 500 ]; then
            echo "AVISO: PR muito grande. Considere dividir em partes menores."
          fi

      - uses: actions/setup-node@v4
        with:
          node-version: '20.x'
          cache: 'npm'

      - run: npm ci
      - run: npm run lint
      - run: npm test

Referências para Aprofundamento

Documentação oficial

Leitura técnica

  • Google Engineering Practices — Code Review — O guia interno do Google para revisão de código, aberto ao público. Cobre tanto a perspectiva de quem revisa quanto de quem tem o código revisado.
  • Conventional Commits — Especificação para mensagens de commit estruturadas, em português. Base para automação de changelogs e versionamento semântico — tema do próximo artigo.

Prática

Comentários

Mais em DevOps

Processos, Serviços e o Comando `systemctl`
Processos, Serviços e o Comando `systemctl`

Cada programa em execu&ccedil;&atilde;o no Linux &mdash; seja um servidor web...

Geradores de Senhas Seguras: Implementações em 5 Linguagens de Programação
Geradores de Senhas Seguras: Implementações em 5 Linguagens de Programação

A geração de senhas fortes é um dos pilares da segurança da informação. Uma s...

Trabalhando em Equipe com Git Flow
Trabalhando em Equipe com Git Flow

O Git oferece branches, mas n&atilde;o diz como us&aacute;-las. Em uma equipe...