Projeto final: configurando um fluxo completo com hooks, CI e proteção de branches
1. Visão geral do fluxo de trabalho
1.1. Objetivos do projeto final: integridade, automação e colaboração
Este projeto final consolida todos os conceitos essenciais do Git em um fluxo de trabalho profissional. O objetivo é criar um ambiente onde cada commit, push e merge seja validado automaticamente, garantindo que o código mantenha qualidade, segurança e consistência. A integração entre hooks locais, CI (Integração Contínua) e proteção de branches forma uma barreira contra erros humanos e acelera a colaboração em equipe.
1.2. Estrutura do repositório exemplo
Vamos considerar um repositório com a seguinte estrutura de branches:
main # branch de produção, protegida contra pushes diretos
release/v1.0 # branch de release, protegida, com CI obrigatório
feature/* # branches de desenvolvimento, sem proteção
hotfix/* # correções urgentes baseadas em main
1.3. Ferramentas envolvidas
- Git hooks locais: scripts executados automaticamente em eventos como commit e push
- GitHub Actions: serviço de CI integrado ao repositório remoto
- Proteção de branches: regras configuradas no GitHub para bloquear operações inseguras
2. Configuração de hooks locais para qualidade de código
2.1. Hook pre-commit: lint automático e verificação de formatação
Crie o arquivo .git/hooks/pre-commit com o seguinte conteúdo:
#!/bin/bash
echo "Executando lint e formatação..."
npx eslint . --fix
npx prettier --check .
if [ $? -ne 0 ]; then
echo "Erro: Código não está formatado corretamente. Execute 'npx prettier --write .'"
exit 1
fi
Torne o hook executável:
chmod +x .git/hooks/pre-commit
2.2. Hook commit-msg: validação de padrão de mensagens (conventional commits)
Crie .git/hooks/commit-msg:
#!/bin/bash
COMMIT_MSG=$(cat "$1")
PATTERN="^(feat|fix|docs|style|refactor|test|chore)(\([a-z]+\))?: .{1,50}"
if ! [[ "$COMMIT_MSG" =~ $PATTERN ]]; then
echo "Erro: Mensagem de commit não segue o padrão conventional commits."
echo "Exemplo válido: feat(login): adiciona autenticação por token"
exit 1
fi
2.3. Hook pre-push: execução de testes rápidos antes do envio ao remoto
Crie .git/hooks/pre-push:
#!/bin/bash
echo "Executando testes antes do push..."
npm test -- --bail
if [ $? -ne 0 ]; then
echo "Erro: Testes falharam. Corrija antes de fazer push."
exit 1
fi
3. Implementação de CI com GitHub Actions
3.1. Pipeline básico: instalação de dependências e execução de testes
Crie .github/workflows/ci.yml:
name: CI Pipeline
on:
push:
branches: [ main, release/*, feature/* ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm ci
- run: npm test
3.2. Validação de lint e análise estática em cada push
Adicione ao mesmo arquivo ci.yml:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: npm ci
- run: npx eslint .
- run: npx prettier --check .
3.3. Jobs condicionais: build e deploy apenas para branches protegidas
build-and-deploy:
needs: [test, lint]
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: npm run build
- run: echo "Deploy simulado para produção"
4. Proteção de branches no repositório remoto
4.1. Configuração de regras de proteção para main e release
No GitHub, vá para Settings > Branches > Add rule e configure:
Branch name pattern: main
- [x] Require a pull request before merging
- [x] Require approvals (1)
- [x] Dismiss stale pull request approvals when new commits are pushed
- [x] Require status checks to pass before merging
- [x] Require branches to be up to date
- [x] Include administrators
Repita para release/*.
4.2. Exigência de pull requests com revisão obrigatória
As mesmas regras garantem que nenhum código seja mesclado sem revisão de pelo menos um colega.
4.3. Bloqueio de pushes diretos e exigência de status checks (CI)
Marque também:
- [x] Restrict who can push to matching branches
- [x] Allow force pushes (apenas para administradores, com cautela)
5. Integração entre hooks locais, CI e proteção de branches
5.1. Sincronizando validações locais com as do CI
Mantenha os mesmos scripts de lint e teste tanto nos hooks quanto no CI. Use arquivos de configuração compartilhados (.eslintrc.json, .prettierrc). Assim, o que falha no hook local também falhará no CI.
5.2. Uso de git-secrets ou hooks customizados para segurança
Instale git-secrets e configure-o:
git secrets --install
git secrets --register-aws
git secrets --add 'api_key|password|token'
Adicione ao pre-commit:
git secrets --scan
if [ $? -ne 0 ]; then
echo "Erro: Possível segredo encontrado no código."
exit 1
fi
5.3. Exemplo prático: fluxo completo de uma feature até o merge
- Crie uma branch
feature/nova-funcionalidadea partir demain - Faça commits com mensagens padronizadas (validadas pelo hook
commit-msg) - O hook
pre-commitexecuta lint automaticamente - Ao fazer push, o hook
pre-pushexecuta testes - O CI roda lint e testes novamente no remoto
- Abra um Pull Request para
main - A proteção de branches exige revisão e status checks aprovados
- Após aprovação, o merge é realizado
6. Boas práticas e troubleshooting
6.1. Gerenciamento de hooks compartilhados via core.hooksPath ou template
Configure um diretório central de hooks:
git config --global core.hooksPath ~/.git-hooks
Crie ~/.git-hooks/pre-commit com os scripts desejados. Assim, todos os repositórios usam os mesmos hooks.
6.2. Como pular hooks temporariamente (com cautela) e depurar falhas
Para pular hooks em situações excepcionais:
git commit --no-verify -m "fix: correção emergencial"
git push --no-verify
Para depurar, adicione set -x no início do script hook e execute manualmente:
bash .git/hooks/pre-commit
6.3. Atualização das regras de proteção e CI conforme a equipe cresce
- Revise periodicamente as regras de proteção
- Adicione novos status checks (ex: cobertura de testes mínima)
- Considere usar
CODEOWNERSpara revisão automática
7. Conclusão e próximos passos
7.1. Recapitulação dos benefícios do fluxo completo
Com hooks locais, CI e proteção de branches, você obtém:
- Código sempre formatado e sem erros básicos
- Mensagens de commit padronizadas
- Testes executados antes de qualquer merge
- Segurança contra pushes diretos e vazamento de segredos
7.2. Extensões possíveis: integração com code review automatizado
Futuras melhorias incluem:
- SonarQube para análise estática aprofundada
- GitHub CodeQL para segurança
- Deploy automático após merge em main
7.3. Referência aos artigos vizinhos sobre reescrita de histórico e migração
Este projeto final é a culminação de conceitos como reescrita de histórico com rebase interativo e migração de repositórios, que permitem manter o histórico limpo e organizado.
Referências
- Git Hooks Documentation — Documentação oficial do Git sobre todos os tipos de hooks disponíveis e como configurá-los.
- GitHub Actions: Understanding GitHub Actions — Guia completo da Microsoft sobre CI/CD com GitHub Actions.
- GitHub: Managing a branch protection rule — Tutorial oficial para configurar regras de proteção de branches.
- Conventional Commits Specification — Especificação oficial do padrão de mensagens de commit utilizado no hook
commit-msg. - Git Secrets: Preventing Committing Secrets — Repositório oficial da AWS com ferramenta para detectar senhas e tokens em commits.
- Atlassian: Git Hooks Tutorial — Tutorial prático da Atlassian sobre hooks locais e seu uso em equipes.
- GitHub: About protected branches — Visão geral sobre os tipos de proteção disponíveis no GitHub.