Auto-merge: configurando merge automático com condições

1. Introdução ao Auto-merge no Git

O auto-merge é uma funcionalidade que permite que pull requests ou merge requests sejam mesclados automaticamente assim que todas as condições pré-definidas forem atendidas. Diferentemente do merge manual (onde um desenvolvedor precisa clicar em "merge" após verificar tudo) e do merge automático simples (que mescla sem validações), o auto-merge condicional executa a mesclagem apenas quando critérios específicos são satisfeitos.

Os cenários ideais para adoção do auto-merge incluem:
- Projetos com pipeline de CI maduro e confiável
- Equipes que realizam revisões frequentes e seguem políticas claras
- Repositórios com alta atividade de pull requests
- Automação de dependências (Dependabot, Renovate)

2. Pré-requisitos para habilitar auto-merge

Antes de configurar o auto-merge, é essencial estabelecer as proteções adequadas no repositório:

Branch protection rules: No GitHub, GitLab ou Bitbucket, configure regras de proteção para a branch de destino (geralmente main ou develop). Essas regras garantem que:
- Nenhum commit direto seja permitido
- Pull requests sejam obrigatórios para alterações
- Status checks sejam exigidos antes do merge

Status checks (CI): Configure gates obrigatórios como:

# Exemplo de configuração de status check no GitHub
Requer status checks para passar antes do merge:
- continuous-integration/jenkins
- continuous-integration/github-actions
- codecov/project

Required reviews: Defina o número mínimo de aprovações necessárias:

# Configuração típica
Número mínimo de revisores: 2
Revisão de code owners: Obrigatória

3. Como configurar auto-merge no GitHub

Via interface web: Ao criar um pull request, clique no botão "Enable auto-merge" disponível na página do PR. Selecione o método de merge desejado e confirme.

Via API REST do GitHub:

# Habilitar auto-merge via curl
curl -X POST \
  -H "Authorization: token SEU_TOKEN" \
  -H "Accept: application/vnd.github.v3+json" \
  https://api.github.com/repos/usuario/repo/pulls/42/merge \
  -d '{
    "merge_method": "squash",
    "commit_title": "feat: implementa nova funcionalidade",
    "auto_merge": true
  }'

Via GitHub CLI (gh):

# Habilitar auto-merge com gh
gh pr merge 42 --auto --squash --subject "feat: implementa nova funcionalidade"

Parâmetros disponíveis:
- merge_method: merge, squash ou rebase
- commit_title: título personalizado para o commit
- commit_message: mensagem detalhada (opcional)

4. Como configurar auto-merge no GitLab e Bitbucket

GitLab: A funcionalidade é chamada "Merge when pipeline succeeds". Para ativar:

# No GitLab, ao criar um merge request:
1. Acesse Settings > Merge requests
2. Marque "Merge when pipeline succeeds"
3. Opcional: configure "Remove source branch when merge"

Bitbucket: O auto-merge é configurado via "Merge checks":

# Configuração no Bitbucket:
1. Repository settings > Merge checks
2. Ative "Automatically merge pull requests"
3. Defina condições: aprovações mínimas, builds bem-sucedidos

Diferenças de comportamento:
- GitHub: auto-merge é ativado por PR e pode ser desativado individualmente
- GitLab: funciona como uma fila global de merge requests
- Bitbucket: requer configuração de merge checks específicos

5. Condições e gatilhos para o merge automático

O auto-merge só ocorre quando todas as condições são satisfeitas:

Status checks aprovados:

# Exemplo de verificação de status checks
Condições necessárias:
- CI pipeline: passed
- Test coverage: >= 80%
- Security scan: no vulnerabilities found

Aprovação de revisores:

# Configuração de revisão
Mínimo de aprovações: 2
Revisores específicos: @tech-lead, @senior-dev
Code owners review: required

Ausência de conflitos: O Git verifica automaticamente se há conflitos de merge. Se houver, o auto-merge não é executado até que sejam resolvidos.

Condições adicionais:
- Labels específicas (ex: auto-merge, ready-to-merge)
- Milestones definidos
- Branch de destino específica (ex: apenas main)
- Horário programado (algumas ferramentas permitem)

6. Estratégias de merge com auto-merge

Merge commit: Preserva o histórico completo com um commit de merge:

# Configuração
gh pr merge 42 --auto --merge
# Resultado: commit de merge com dois pais

Squash and merge: Combina todos os commits em um único commit (recomendado para features):

# Configuração
gh pr merge 42 --auto --squash --subject "feat: nova funcionalidade"
# Resultado: histórico linear e limpo

Rebase and merge: Rebaseia os commits do PR no topo da branch base:

# Configuração
gh pr merge 42 --auto --rebase
# Resultado: histórico linear sem commits de merge

Estratégia padrão: Configure no repositório:

# .github/repository-settings.yml
merge_method: squash
auto_merge_default: true

7. Boas práticas e armadilhas comuns

Evitar auto-merge em branches críticos:

# Proteção para branches críticos
Branches protegidas:
- main: auto-merge desabilitado
- release/*: requer aprovação manual
- develop: auto-merge permitido apenas com CI verde

Gerenciamento de fila de auto-merge: Quando múltiplos PRs têm auto-merge ativado, o Git processa em ordem. Para evitar conflitos em cadeia:
- Configure um limite máximo de PRs na fila
- Use merge trains (GitLab oferece essa funcionalidade)

Monitoramento de falhas: Se uma condição falhar após ativação do auto-merge:
- O PR permanece aberto com status "auto-merge ativado"
- Notificações são enviadas para o autor e revisores
- É necessário reativar o auto-merge após corrigir a falha

Uso combinado com Draft PRs: Não ative auto-merge em PRs marcados como Draft ou WIP (Work in Progress). Configure regras para ignorar esses estados.

8. Automatizando auto-merge com GitHub Actions e scripts

Workflow YAML para ativar auto-merge automaticamente:

# .github/workflows/auto-merge.yml
name: Auto-merge PR
on:
  pull_request_review:
    types: [submitted]
  check_suite:
    types: [completed]
  status: {}

jobs:
  auto-merge:
    runs-on: ubuntu-latest
    if: |
      github.event.review.state == 'approved' ||
      github.event.check_suite.conclusion == 'success'
    steps:
      - name: Enable auto-merge
        run: |
          gh pr merge ${{ github.event.pull_request.number }} \
            --auto --squash \
            --subject "Auto-merge: ${{ github.event.pull_request.title }}"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Gatilhos em eventos específicos:

# Gatilhos comuns para auto-merge
on:
  pull_request_review:  # Quando um revisor aprova
  check_suite:          # Quando CI completa
  status:               # Quando status checks mudam
  pull_request:         # Quando PR é atualizado
    types: [opened, synchronize]

Integração com bots de dependências:

# Configuração para Dependabot com auto-merge
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "weekly"
    # Ativar auto-merge para patches
    allow:
      - dependency-type: "development"
    labels:
      - "dependencies"
      - "auto-merge"

Script para auto-merge condicional:

#!/bin/bash
# auto-merge-conditional.sh

PR_NUMBER=$1
LABEL=$2

# Verificar se o PR tem a label necessária
if gh pr view $PR_NUMBER --json labels | grep -q "$LABEL"; then
  # Verificar se CI passou
  CI_STATUS=$(gh pr checks $PR_NUMBER --json state | jq -r '.[0].state')

  if [ "$CI_STATUS" == "SUCCESS" ]; then
    # Ativar auto-merge
    gh pr merge $PR_NUMBER --auto --squash
    echo "Auto-merge ativado para PR #$PR_NUMBER"
  else
    echo "CI ainda não passou para PR #$PR_NUMBER"
  fi
else
  echo "PR #$PR_NUMBER não possui a label $LABEL"
fi

Referências