7 min lectura • Guide 325 of 877
Automatizando la Gestión de Branches
La gestión manual de branches es propensa a errores y consume tiempo. Los flujos de trabajo automatizados de branches aseguran nomenclatura consistente, limpian branches obsoletas y refuerzan estándares del equipo. Esta guía cubre estrategias prácticas de automatización para gestión de branches.
Tipos de Automatización de Branches
| Automatización | Beneficio | Esfuerzo |
|---|---|---|
| Validación de nombres | Consistencia | Bajo |
| Auto-eliminar mergeados | Repo limpio | Bajo |
| Limpieza de obsoletos | Menos desorden | Medio |
| Reglas de protección | Quality gates | Bajo |
| CI por tipo de branch | Tests correctos | Medio |
Nomenclatura de Branches
Reforzando Convenciones
AUTOMATIZACIÓN DE NOMBRES DE BRANCH
═══════════════════════════════════
PATRÓN DE NOMENCLATURA:
─────────────────────────────────────
Formato estándar:
├── tipo/ticket-descripcion
├── Ejemplos:
│ ├── feature/AUTH-123-flujo-login
│ ├── bugfix/BUG-456-null-pointer
│ ├── hotfix/PROD-789-fix-pagos
│ └── chore/DEP-001-update-deps
└── Consistente, parseable
OPCIONES DE VALIDACIÓN:
─────────────────────────────────────
1. Hook pre-commit:
#!/bin/bash
branch=$(git rev-parse --abbrev-ref HEAD)
pattern="^(feature|bugfix|hotfix|chore)\/[A-Z]+-[0-9]+-"
if [[ ! $branch =~ $pattern ]]; then
echo "Nombre de branch inválido: $branch"
exit 1
fi
2. Check de CI:
- name: Validar nombre de branch
run: |
if [[ ! "$GITHUB_HEAD_REF" =~ ^(feature|bugfix|hotfix)/ ]]; then
echo "Nombre de branch inválido"
exit 1
fi
3. Hook pre-receive (server-side):
├── Bloquea branches inválidas en push
└── Enforcement más fuerte
ENLACE A TAREAS:
─────────────────────────────────────
Extraer ticket de branch:
├── Parsear nombre de branch
├── Enlazar PR a issue automáticamente
├── Actualizar estado de tarea
├── Cerrar tarea en merge
└── Trazabilidad completa
Auto-Limpieza
Gestionando Ciclo de Vida de Branches
AUTOMATIZACIÓN DE LIMPIEZA DE BRANCHES
══════════════════════════════════════
AUTO-ELIMINAR EN MERGE:
─────────────────────────────────────
Configuración GitHub:
├── Settings → General
├── "Automatically delete head branches"
├── Habilitar ✓
├── Branch eliminada cuando PR es mergeada
├── Sin limpieza manual
└── Repositorio limpio
GitLab:
├── Settings → Repository
├── "Enable auto-delete merged branches"
└── Mismo comportamiento
LIMPIEZA DE BRANCHES OBSOLETAS:
─────────────────────────────────────
Script para encontrar branches obsoletas:
#!/bin/bash
# Branches sin commits en 30+ días
DAYS_OLD=30
CUT_DATE=$(date -d "$DAYS_OLD days ago" +%Y-%m-%d)
echo "Branches obsoletas (sin commits desde $CUT_DATE):"
for branch in $(git branch -r | grep -v HEAD); do
last_commit=$(git log -1 --format=%ci $branch | cut -d' ' -f1)
if [[ "$last_commit" < "$CUT_DATE" ]]; then
echo " $branch (último commit: $last_commit)"
fi
done
Script de Limpieza Automática
SCRIPT DE LIMPIEZA PROGRAMADA
═════════════════════════════
#!/bin/bash
# cleanup-stale-branches.sh
# Configuración
DAYS_OLD=60
DRY_RUN=true # Cambiar a false para eliminar realmente
echo "Buscando branches sin actividad en $DAYS_OLD días..."
for branch in $(git branch -r --merged origin/main | grep -v HEAD | grep -v main); do
last_commit=$(git log -1 --format=%ci "$branch" | cut -d' ' -f1)
cut_date=$(date -d "$DAYS_OLD days ago" +%Y-%m-%d)
if [[ "$last_commit" < "$cut_date" ]]; then
branch_name=$(echo "$branch" | sed 's/origin\///')
if [ "$DRY_RUN" = true ]; then
echo "[DRY RUN] Eliminaría: $branch_name"
else
git push origin --delete "$branch_name"
echo "Eliminado: $branch_name"
fi
fi
done
PROGRAMACIÓN (cron):
─────────────────────
# Ejecutar todos los lunes a las 3am
0 3 * * 1 /scripts/cleanup-stale-branches.sh
Protección de Branches
Configuración de Reglas
REGLAS DE PROTECCIÓN DE BRANCHES
════════════════════════════════
BRANCH: main / master
─────────────────────
PROTECCIONES HABILITADAS:
├── ✓ Require pull request before merging
│ └── Required approving reviews: 1
├── ✓ Require status checks to pass
│ ├── ci/tests
│ ├── ci/lint
│ └── ci/security-scan
├── ✓ Require branches to be up to date
├── ✓ Require conversation resolution
├── ✓ Require signed commits
├── ✗ Allow force pushes (NUNCA en main)
└── ✗ Allow deletions (NUNCA en main)
BRANCH: develop
───────────────
PROTECCIONES HABILITADAS:
├── ✓ Require pull request before merging
│ └── Required approving reviews: 1
├── ✓ Require status checks to pass
│ └── ci/tests
├── ✗ Require signed commits (opcional)
└── ✗ Allow deletions
Automatización de Branch Protection vía API
CONFIGURACIÓN VIA GITHUB API
════════════════════════════
#!/bin/bash
# setup-branch-protection.sh
REPO="owner/repo"
BRANCH="main"
TOKEN="ghp_xxxx"
curl -X PUT \
-H "Authorization: token $TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/$REPO/branches/$BRANCH/protection" \
-d '{
"required_status_checks": {
"strict": true,
"contexts": ["ci/tests", "ci/lint"]
},
"enforce_admins": true,
"required_pull_request_reviews": {
"required_approving_review_count": 1
},
"restrictions": null
}'
BENEFICIOS:
├── Reproducible en nuevos repos
├── Versionable (Infrastructure as Code)
├── Consistente entre proyectos
└── Auditable
CI/CD por Tipo de Branch
Configuración de Workflows Diferenciados
WORKFLOWS POR TIPO DE BRANCH
════════════════════════════
FEATURE BRANCHES:
─────────────────
├── Tests unitarios
├── Linting
├── Build
└── No deploy
DEVELOP BRANCH:
───────────────
├── Tests completos
├── Linting
├── Build
├── Deploy a staging
└── Tests E2E en staging
MAIN BRANCH:
────────────
├── Tests completos
├── Linting
├── Build
├── Security scan
├── Deploy a producción
└── Smoke tests
HOTFIX BRANCHES:
────────────────
├── Tests críticos
├── Build
├── Deploy inmediato
└── Notificación al equipo
Ejemplo GitHub Actions
# .github/workflows/ci.yml
name: CI Pipeline
on:
push:
branches: [main, develop, 'feature/**', 'hotfix/**']
pull_request:
branches: [main, develop]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Tests
run: npm test
deploy-staging:
needs: test
if: github.ref == 'refs/heads/develop'
runs-on: ubuntu-latest
steps:
- name: Deploy to Staging
run: ./deploy.sh staging
deploy-production:
needs: test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Deploy to Production
run: ./deploy.sh production
Métricas de Gestión de Branches
DASHBOARD DE BRANCHES
═════════════════════
ESTADO ACTUAL:
┌─────────────────────────────────────────┐
│ Total branches: 47 │
│ ├── feature/*: 28 │
│ ├── bugfix/*: 12 │
│ ├── hotfix/*: 2 │
│ └── otros: 5 │
│ │
│ Branches obsoletas (>30 días): 8 │
│ PRs abiertos: 15 │
│ Branches sin PR: 6 │
└─────────────────────────────────────────┘
TENDENCIA SEMANAL:
┌─────────────────────────────────────────┐
│ Branches creadas: 12 │
│ Branches eliminadas: 18 │
│ Branches mergeadas: 14 │
│ Tiempo promedio de vida: 4.2 días │
└─────────────────────────────────────────┘
Mejores Prácticas
MEJORES PRÁCTICAS
═════════════════
✓ Usa convenciones de nombres consistentes
└── Todos siguen el mismo patrón
✓ Habilita auto-delete en merge
└── Sin branches huérfanas
✓ Limpia branches obsoletas regularmente
└── Script semanal/mensual
✓ Protege branches críticas
└── main, develop siempre protegidas
✓ Diferencia CI por tipo de branch
└── Tests apropiados para cada contexto
✓ Enlaza branches a tareas
└── Trazabilidad completa
Anti-Patrones
ANTI-PATRONES A EVITAR
══════════════════════
✗ Sin convención de nombres
└── Caos y confusión
✗ Branches que nunca se eliminan
└── Cientos de branches obsoletas
✗ main sin protección
└── Push directo = riesgo
✗ Mismo CI para todos los branches
└── Deploy accidental a producción
✗ Sin revisión de PRs
└── Código sin revisar en main
Soluciones Relacionadas
- Automatizando Procesos de Code Review - PRs automatizados
- Pipelines CI/CD - Integración continua
- Git Workflow para Equipos - Flujos de trabajo
- Integración Git con GitScrum - Sincronización