Probar gratis
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ónBeneficioEsfuerzo
Validación de nombresConsistenciaBajo
Auto-eliminar mergeadosRepo limpioBajo
Limpieza de obsoletosMenos desordenMedio
Reglas de protecciónQuality gatesBajo
CI por tipo de branchTests correctosMedio

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