← Todo el material
Curso Intermedio 23 de agosto de 2026

Deploy de Agentes — Módulo 9: GitHub a nivel enterprise — checks obligatorios y evaluación de brechas

Noveno módulo del Curso de Deploy de Agentes: cómo una empresa blinda el merge a main. Branch protection, required status checks, CODEOWNERS y environments; y los guardianes de brechas — Dependabot, CodeQL, secret scanning y el quality gate de SonarQube Cloud como required check.

☰ Índice del contenido

Noveno módulo del Curso de Deploy de Agentes, y cierre del bloque intermedio. En el Módulo 8 montamos CI: un robot que corre lint, tests y evals en cada PR y marca verde o rojo. Pero ese verde todavía es una sugerencia. Nada impide que alguien con prisa mergee en rojo, o que suba una dependencia con una vulnerabilidad conocida, o que pegue una API key en el código. En una empresa, “confiar en que nadie lo haga” no es una política. Este módulo es cómo se blinda de verdad: convertir cada check en un muro obligatorio y sumar guardianes automáticos que buscan las brechas que los tests no ven.

La tesis del módulo

El check que no bloquea, no protege. El salto de proyecto personal a enterprise no es tener más tests: es que ni tests, ni escaneos de seguridad, ni el quality gate, ni la revisión humana sean opcionales. Todo se vuelve required check + branch protection, y a main no llega nada que no haya pasado por todos.

Frente 1: blindar el merge

Aquí GitHub deja de ser un lugar donde guardas código y pasa a ser el guardia de la puerta de main.

Branch protection rules — reglas de protección de rama: configuración que le prohíbe a main (u otra rama) recibir cambios que no cumplan ciertos requisitos. Se activan en Settings → Branches y son la base de todo lo demás. Sin ellas, cualquiera con permiso de escritura puede pushear directo a main o mergear un PR en rojo.

Required status checks — checks obligatorios: los mismos jobs del Módulo 8 (lint, test, eval, build), pero marcados como requeridos. Si están en rojo o ni siquiera corrieron, el botón de merge queda gris. El check pasó de “aviso” a “muro”.

CODEOWNERS — dueños de código: un archivo que declara quién debe revisar los cambios en cada parte del repo. Si tocas src/agents/, GitHub pide automáticamente la aprobación del equipo dueño de esa carpeta antes de dejar mergear. Vive en .github/CODEOWNERS:

# .github/CODEOWNERS
# Cada línea: patrón de archivos  seguido de  sus dueños.
# El último patrón que calza gana. Los dueños se piden como
# reviewers automáticos en cualquier PR que toque esos
# archivos.

# Dueño por defecto de todo el repo:
*                       @equipo/plataforma

# El core del agente lo revisa el equipo de IA:
/src/agents/            @equipo/ia
/src/prompts/           @equipo/ia

# Infra y despliegue, el equipo de DevOps:
/infra/                 @equipo/devops
/.github/               @equipo/devops
*.tf                    @equipo/devops

# Los secretos y la config sensible, dos pares de ojos senior:
/config/secrets.example @ana-lead @felipe-briceno

Required reviewers — cuántas aprobaciones humanas hacen falta antes de mergear (típico: una o dos), y si esa aprobación se invalida cuando llega un commit nuevo. Combinado con CODEOWNERS, garantiza que la persona correcta miró el cambio.

Environments — entornos: en GitHub un environment (por ejemplo production) puede exigir aprobación manual antes de que un deploy corra contra él. Es el freno humano final: el CI puede estar todo verde, pero soltar a producción requiere que alguien apriete el botón. Lo veremos en acción en los módulos de nube.

Merge queue — cola de merge: cuando muchos PRs quieren entrar a main a la vez, la merge queue los integra de a uno, re-corriendo los checks sobre el estado real que tendrá main tras cada merge. Evita el clásico “los dos PRs pasaban por separado, pero juntos rompen main”.


  PR listo
    │
    ▼
 ┌───────────────────────────┐
 │  branch protection en main│
 │  exige, todo junto:       │
 │   · required status checks│
 │   · aprobación CODEOWNERS │
 │   · sin commits sin firmar│
 └───────────────────────────┘
    │
    ▼
 ┌───────────────────────────┐
 │  merge queue integra de a │
 │  uno y re-corre los checks│
 └───────────────────────────┘
    │
    ▼
  MERGE A MAIN

Frente 2: evaluación de brechas

Los tests verifican que tu código haga lo que quieres. Los guardianes de brechas verifican lo que no quieres: dependencias vulnerables, agujeros de seguridad, credenciales filtradas, código sin cubrir. Corren solos, y en enterprise cada uno se vuelve un required check más.

Seguridad

Dependabot — el robot de dependencias de GitHub: vigila tus librerías y avisa (o abre PRs solo) cuando alguna tiene una vulnerabilidad conocida o quedó vieja. Se configura con .github/dependabot.yml:

# .github/dependabot.yml
version: 2
updates:
  # Dependencias de Python (pip / requirements).
  - package-ecosystem: "pip"
    directory: "/"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 5
    labels:
      - "dependencies"

  # Las propias actions del Módulo 8 también se actualizan.
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"

  # La imagen base del Dockerfile (Módulo 5).
  - package-ecosystem: "docker"
    directory: "/"
    schedule:
      interval: "weekly"

CodeQL / code scanning — análisis estático de seguridad, o SAST (static application security testing): lee tu código sin ejecutarlo y busca patrones peligrosos (inyección, manejo inseguro de datos, rutas de datos que terminan en un eval). CodeQL es el motor de GitHub para esto. Se activa con un workflow que usa las actions oficiales github/codeql-action:

# .github/workflows/codeql.yml
name: CodeQL
on:
  pull_request:
    branches: [main]
  schedule:
    - cron: "0 3 * * 1"   # además, un barrido semanal completo

jobs:
  analyze:
    runs-on: ubuntu-latest
    permissions:
      security-events: write   # para publicar los hallazgos
      contents: read
    steps:
      - uses: actions/checkout@v4
      - name: Inicializar CodeQL
        uses: github/codeql-action/init@v3
        with:
          languages: python
      - name: Analizar
        uses: github/codeql-action/analyze@v3

Secret scanning + push protection — escaneo de secretos: GitHub revisa el repo (y con push protection, cada push antes de aceptarlo) buscando cosas con forma de credencial: tokens, API keys, claves privadas. Con push protection activo, si intentas subir una key de OpenAI, el push se rechaza en el momento — la credencial nunca llega a quedar en el historial. Es la última línea contra el error más común y más caro.

Calidad y cobertura

Quality gate — puerta de calidad: un umbral de métricas de código que un PR debe superar para poder mergear. La herramienta enterprise clásica es SonarQube Server (autohospedado) o SonarQube Cloud (la versión en la nube, llamada SonarCloud hasta octubre de 2024). Mide, sobre el código nuevo del PR:

  • Cobertura mínima (por ejemplo, ≥ 80% del código nuevo cubierto por tests — de ahí que en el Módulo 8 subiéramos coverage.xml como artifact).
  • Code smells — señales de código difícil de mantener.
  • Security hotspots — puntos que un humano debe revisar por riesgo de seguridad.
  • Duplicación de código por encima de un porcentaje.

Si el PR no pasa el gate, Sonar reporta el check en rojo, y como está declarado required, el merge queda bloqueado. Alternativas enterprise del mismo nicho: Snyk (fuerte en dependencias y contenedores) y Checkmarx (SAST corporativo).


  PR
   │
   ▼
 ┌──────────────────────────────────────┐
 │  guardianes (todos required checks)  │
 │  ┌────────┐ ┌────────┐ ┌───────────┐ │
 │  │  tests │ │ CodeQL │ │ Sonar gate│ │
 │  └────────┘ └────────┘ └───────────┘ │
 │  ┌───────────────────┐ ┌───────────┐ │
 │  │ secret · push prot│ │  review + │ │
 │  │                   │ │ CODEOWNERS│ │
 │  └───────────────────┘ └───────────┘ │
 └──────────────────────────────────────┘
   │
   ▼
 ┌──────────────────┐     ┌──────────────────┐
 │ todos en verde   │ ──► │  merge permitido │
 └──────────────────┘     └──────────────────┘
   │
   ▼
 ┌──────────────────┐     ┌──────────────────┐
 │ uno en rojo      │ ──► │  merge bloqueado │
 └──────────────────┘     └──────────────────┘

Los guardianes y qué brecha cubre cada uno

GuardiánQué revisaBrecha que cierraCómo bloquea
Branch protectionQue se cumplan los requisitos de la ramaPush directo o merge en rojo a mainEs la regla base: sin ella, nada de lo demás es obligatorio
Required status checksQue lint/test/eval/build estén verdesMergear con CI fallandoBotón de merge gris hasta que pasen
CODEOWNERS + reviewersQue la persona correcta aprobóCambio sin revisión de quien sabeFalta la aprobación requerida
DependabotDependencias vulnerables o viejasLibrería con CVE conocidoAbre PR de fix; su check puede ser required
CodeQL (SAST)Patrones inseguros en el códigoInyección y agujeros de seguridadAlerta de seguridad = check rojo
Secret scanningCredenciales en el códigoAPI key o token filtradoPush protection rechaza el push
Quality gate (Sonar)Cobertura, smells, duplicaciónDeuda técnica y código sin testsGate rojo = required check rojo

El patrón enterprise, en una frase de sistema

La pieza que amarra todo es simple de enunciar y estricta de aplicar: cada guardián se declara como required check, y branch protection exige que todos estén verdes. El resultado es que llegar a main deja de depender de la buena voluntad de nadie.


 Para mergear a main, TODO esto debe estar VERDE:

   [tests]  [evals]  [CodeQL]  [Sonar gate]
   [secret scan]  [review CODEOWNERS]

 Falta uno ──► el merge no existe como opcion.

Cuidado con los checks “opcionales por comodidad”. El error clásico es marcar el quality gate como informativo “mientras el equipo se acostumbra”. Un check que no bloquea se ignora en la primera semana ocupada. O es required, o no cuenta.

Cuidado con abrirle branch protection a los admins. Si dejas la casilla “los administradores pueden saltarse esto”, tu muro tiene una puerta trasera con las llaves puestas. En enterprise, include administrators va activado: la regla vale para todos.

Errores comunes

  • Confundir “el check corre” con “el check bloquea”. Correr en CI (Módulo 8) es la mitad; volverlo required status check en branch protection es la otra mitad. Sin la segunda, el rojo es decorativo.
  • Poner CODEOWNERS sin exigir la revisión. El archivo CODEOWNERS solo sugiere reviewers si no marcas “require review from Code Owners” en la protección de rama. Ambas cosas, o no sirve.
  • Tratar Dependabot como spam. Sus PRs de actualización se sienten ruido hasta el día que uno de ellos parcha la vulnerabilidad que te habría costado el incidente. Se revisan, no se cierran en masa.
  • Creer que SAST reemplaza a los tests. CodeQL busca patrones inseguros; no verifica que tu agente responda bien. Son guardianes de brechas distintas: seguridad vs comportamiento.
  • Fijar el quality gate sobre todo el código y no sobre el nuevo. Un repo viejo nunca alcanzará 80% global de golpe. Sonar mide por defecto el código nuevo del PR — así el estándar sube commit a commit sin frenar al equipo.

La frase para llevarse

“En un proyecto personal, la calidad depende de que te acuerdes. En enterprise, depende de que el sistema no te deje olvidarlo: a main no llega nada que no haya pasado por todos los guardianes.”

Qué viene

Cierra el bloque intermedio. Empieza el bloque de infraestructura y nube con el Módulo 10: Terraform desde cero — describir la infraestructura como código para que crear los servidores, redes y permisos de tu agente sea tan repetible y revisable como el código que ya blindamos.

Material relacionado

DeployCI/CDGitHub ActionsDevOpsSeguridadSonarQube

Preguntas sobre este curso

Regístrate gratis para hacer preguntas y guardar tu progreso.

✉ Entérate de lo nuevo

Recibe un aviso cuando publique nuevos cursos, workshops o investigaciones. Sin spam.