Status checks: integrando CI como gate de merge
1. O que são Status Checks e por que usá-los como gate de merge
Status checks são notificações automáticas que provedores de CI (Integração Contínua) enviam para plataformas Git como GitHub, GitLab e Bitbucket, informando o estado de execução de jobs específicos. Cada check pode ter status como pending, success, failure, error ou cancelled. Quando configurados como gate de merge, esses checks determinam se um pull request (PR) pode ser mesclado ao branch de destino.
No GitHub, por exemplo, checks aparecem na parte inferior de um PR. Há dois tipos principais:
- Checks obrigatórios: devem ser aprovados para que o merge seja liberado.
- Checks opcionais: não bloqueiam o merge, mas servem como indicadores visuais.
Benefícios de usar status checks como gate de merge:
- Qualidade garantida: código só entra no branch principal após passar por validações como testes, linting e build.
- Prevenção de quebras: evita que código defeituoso ou incompleto seja integrado.
- Rastreabilidade: cada commit fica associado a um histórico de checks, facilitando auditoria.
2. Configurando provedores de CI para expor status checks
GitHub Actions
No GitHub Actions, cada job pode expor status checks automaticamente. O campo conclusion define o resultado final. Exemplo de workflow:
name: CI Pipeline
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Tests
run: npm test
- name: Run Lint
run: npm run lint
Cada passo é um check individual. O status final do job é refletido no PR.
Jenkins
Para Jenkins com plugin GitHub, o commit status é atualizado via API. Exemplo de pipeline declarativa:
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'mvn clean install'
}
}
}
post {
success {
githubNotify(
status: 'SUCCESS',
description: 'Build passou',
context: 'Jenkins/Build'
)
}
failure {
githubNotify(
status: 'FAILURE',
description: 'Build falhou',
context: 'Jenkins/Build'
)
}
}
}
CircleCI
No CircleCI, o status é enviado automaticamente com base no resultado dos jobs. Exemplo de .circleci/config.yml:
version: 2.1
jobs:
test:
docker:
- image: cimg/node:20.0
steps:
- checkout
- run: npm test
workflows:
version: 2
build_and_test:
jobs:
- test
3. Habilitando status checks como proteção de branch
A configuração de proteção de branch é feita nas configurações do repositório. No GitHub:
- Acesse Settings > Branches > Branch protection rules.
- Clique em Add rule e especifique o branch (ex:
main). - Marque a opção Require status checks to pass before merging.
- Na lista exibida, selecione os checks que devem ser obrigatórios.
Para repositórios privados, as mesmas regras se aplicam. A diferença é que repositórios públicos podem ter proteções mais restritivas, como exigir checks de colaboradores externos.
4. Comportamento do merge com status checks habilitados
Quando checks obrigatórios estão configurados:
- O botão de merge fica desabilitado enquanto houver checks pendentes ou com falha.
- Novos pushes disparam reexecução automática dos checks, atualizando o status.
- Há diferenciação entre checks de CI (automáticos) e checks manuais (ex: "WIP" ou "Revisão necessária").
Exemplo visual no GitHub:
[✓] CI / build (pull_request) — success
[✓] CI / test (pull_request) — success
[✓] Lint check (pull_request) — success
[x] Security scan (pull_request) — failure
Neste caso, o merge está bloqueado até que o check de segurança seja aprovado.
5. Estratégias avançadas de status checks
Combinando múltiplos checks
É comum exigir que todos os checks de uma pipeline passem:
Checks obrigatórios:
- Build (Node.js)
- Testes unitários
- Testes de integração
- Análise de segurança (Snyk)
- Linting (ESLint)
Checks condicionais
Para ignorar checks em paths específicos (ex: documentação), use filtros no workflow:
on:
pull_request:
paths-ignore:
- 'docs/**'
- '*.md'
Timeouts e retry automático
Para evitar que checks lentos travem o fluxo, configure timeouts e retry:
jobs:
test:
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests
run: npm test
- name: Retry on failure
if: failure()
run: npm test -- --retry 2
6. Tratamento de falhas e notificações
Reexecução manual ou automática
No GitHub, é possível reexecutar checks falhados clicando em Re-run jobs. Para reexecução automática, use:
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Run tests
run: npm test
- name: Retry if flaky
if: failure()
run: npm test -- --retry 3
Notificações para desenvolvedores
Integrações com Slack, e-mail ou webhooks podem ser configuradas:
name: Notify on failure
on: [pull_request]
jobs:
notify:
runs-on: ubuntu-latest
steps:
- name: Send Slack notification
if: failure()
uses: slackapi/slack-github-action@v1.24.0
with:
payload: '{"text":"Pipeline falhou no PR ${{ github.event.number }}"}'
Políticas de bypass
Administradores podem ter permissão para ignorar checks (ex: merges forçados). Isso deve ser usado com moderação e registrado em logs.
7. Monitoramento e auditoria de status checks
O histórico de checks pode ser consultado via API do GitHub:
GET /repos/{owner}/{repo}/commits/{ref}/statuses
Para auditoria, é possível extrair métricas como:
- Taxa de aprovação: percentual de PRs que passam em todos os checks.
- Tempo médio de execução: quanto tempo os checks levam para concluir.
- Padrões de erro: checks que mais falham, indicando instabilidade.
Exemplo de consulta com curl:
curl -H "Authorization: token GITHUB_TOKEN" \
https://api.github.com/repos/owner/repo/commits/abc123/statuses
8. Boas práticas e armadilhas comuns
Não tornar todos os checks obrigatórios
Equilíbrio entre rigidez e agilidade. Checks opcionais podem ser úteis para análises de performance ou cobertura de código.
Evitar checks muito lentos
Checks que demoram mais de 30 minutos podem travar o fluxo de merge. Considere paralelizar jobs ou usar cache.
Documentar a pipeline de CI
Mantenha um arquivo CONTRIBUTING.md com a lista de checks esperados, facilitando a vida de novos contribuidores.
Exemplo de documentação:
## Status Checks Obrigatórios
- Build (Node.js 20)
- Testes unitários (Jest)
- Linting (ESLint)
- Análise de segurança (Snyk)
## Como reexecutar checks falhos
1. Acesse o PR no GitHub.
2. Clique em "Checks" na aba inferior.
3. Selecione "Re-run failed jobs".
Armadilhas comuns:
- Falsos positivos: checks que falham sem motivo real. Configure retry automático.
- Dependência externa: se um serviço externo falha, todos os checks podem falhar. Use fallback ou mock.
- Check único gigante: um único job que faz tudo. Prefira múltiplos checks pequenos e paralelos.
Seguindo essas práticas, a integração de CI como gate de merge se torna um aliado poderoso para manter a qualidade do código sem sacrificar a produtividade da equipe.
Referências
- GitHub Docs: About status checks — Documentação oficial sobre status checks e como configurá-los em pull requests.
- GitHub Docs: Branch protection rules — Guia completo sobre regras de proteção de branch, incluindo exigência de status checks.
- CircleCI Docs: Status and contexts — Como o CircleCI gerencia status checks e contextos para integração com GitHub.
- Jenkins Plugin: GitHub Branch Source — Plugin Jenkins que permite notificar status de commit para GitHub.
- Atlassian Docs: Git branch protection in Bitbucket — Tutorial sobre proteção de branch no Bitbucket, incluindo status checks como gate de merge.
- GitHub Blog: Required status checks best practices — Artigo técnico com melhores práticas para configurar checks obrigatórios em repositórios.
- GitLab Docs: Merge request status checks — Documentação oficial do GitLab sobre status checks em merge requests.