Revisiones de Código Automáticas con CODEOWNERS
Configura CODEOWNERS en GitHub, evita fallos silenciosos y exige revisión con patrones, permisos y protección de ramas correctos.
Un archivo CODEOWNERS es un archivo de texto plano en tu repositorio que mapea patrones de rutas a propietarios — usuarios o equipos de GitHub — y solicita automáticamente una revisión de esos propietarios cada vez que un pull request modifica una ruta coincidente. Cumple dos funciones a la vez: enruta las revisiones a las personas correctas sin necesidad de mencionarlas manualmente, y documenta quién es responsable de qué. El problema es que CODEOWNERS falla silenciosamente. Un orden incorrecto de patrones, un equipo sin miembros o un propietario sin acceso de escritura no genera ningún mensaje de error — la solicitud de revisión simplemente no se dispara, y el PR se fusiona sin los ojos que tenías previstos.
Esta guía explica cómo configurarlo correctamente en pocos minutos y dedica la mayor parte del tiempo a las trampas: la regla de última coincidencia que silenciosamente anula tus reglas específicas, y los fallos de permisos, equipos vacíos y rama predeterminada que hacen que CODEOWNERS parezca configurado mientras no hace nada.
Puntos Clave
- CODEOWNERS funciona con última coincidencia gana: cuando varios patrones coinciden con un archivo, solo la última línea coincidente asigna propietarios — coloca las reglas generales al inicio y las anulaciones específicas al final.
- El archivo debe estar en la rama base del PR, pesar menos de 3 MB, usar mayúsculas y minúsculas correctas y contener sintaxis válida; cualquier línea inválida se omite silenciosamente.
- CODEOWNERS por sí solo no bloquea fusiones — también debes habilitar “Require a pull request before merging” y “Require review from Code Owners” en un ruleset o en una regla de protección de rama.
- Un propietario sin acceso de escritura es ignorado silenciosamente, y un equipo propietario debe ser visible y tener acceso de escritura aunque cada miembro ya lo tenga individualmente.
- GitHub CODEOWNERS no soporta la negación con
!— patrones como!README.mdson rechazados como inválidos.
¿Qué hace un archivo CODEOWNERS?
CODEOWNERS designa a individuos o equipos responsables de rutas específicas en un repositorio. Cuando alguien abre un pull request que modifica una ruta coincidente, GitHub solicita automáticamente una revisión de los propietarios listados. El mismo formato de archivo funciona en GitHub, GitLab y Bitbucket; los ejemplos aquí están orientados principalmente a GitHub.
Con una proporción creciente de PRs creados por agentes de IA, una regla CODEOWNERS en rutas sensibles — auth/, **/migrations/, configuración de CI — garantiza que un propietario humano siga revisando los cambios del agente antes de que se integren.
Discover how at OpenReplay.com.
¿Cómo se configura y aplica CODEOWNERS?
Coloca el archivo en .github/CODEOWNERS. GitHub busca en .github/, luego en la raíz del repositorio y después en docs/, y utiliza el primer CODEOWNERS que encuentra, por lo que una única ubicación canónica evita confusiones. Escribe una regla por línea con el formato patrón @propietario, luego confírmalo en tu rama predeterminada.
# .github/CODEOWNERS
# Propietarios predeterminados para todo el repositorio
* @my-org/core-team
# Frontend y backend por área
/src/frontend/ @my-org/frontend-team
/src/backend/ @my-org/backend-team
# Tests y documentación
**/tests/ @my-org/qa-team
*.md @my-org/docs-team
# Las rutas sensibles tienen un propietario dedicado (colócalas al final)
/src/auth/ @my-org/security-team
Súbelo como cualquier otro archivo:
git add .github/CODEOWNERS
git commit -m "Add CODEOWNERS"
git push origin main
Confirmar el archivo solo solicita revisores — no bloquea nada. Para bloquear efectivamente las fusiones, habilita dos configuraciones juntas: Require a pull request before merging y Require review from Code Owners. Puedes configurarlas en los nuevos Rulesets (Settings → Rules → Rulesets) o en una regla de protección de rama clásica (Settings → Branches). Ambas opciones están disponibles; rulesets es la más reciente.
Patrones de sintaxis de CODEOWNERS que vale la pena conocer
El lenguaje de patrones sigue la mayoría de las reglas de gitignore. Estos cinco cubren casi todo:
* @core-team # valor predeterminado global
/api/ @backend-team # un directorio
*.ts @frontend-team # una extensión, a cualquier profundidad
**/tests/ @qa-team # directorio anidado en cualquier lugar
/security/ @sec-team @compliance-team # dos propietarios, una línea
Un glob de extensión no anclado como *.ts coincide con archivos de ese tipo en cualquier parte del repositorio — se comporta igual que **/*.ts. Una regla importante al listar varios propietarios: todos deben estar en la misma línea. Si los divides en varias líneas, el patrón solo asigna al último propietario mencionado. Cuando se requiere la revisión de propietarios de código, la aprobación de cualquiera de los propietarios listados satisface el requisito.
Un mito que hay que desmentir: a diferencia de .gitignore, GitHub CODEOWNERS no soporta la negación con !. Patrones como !README.md son rechazados como inválidos — la propia documentación de GitHub lista !, los rangos de caracteres [ ] y el escape \# como características de gitignore que no funcionan aquí. Para excluir una ruta, asígnale un propietario diferente o estructura las reglas de modo que ninguna coincida con ella (dejar la columna de propietario vacía en una línea posterior más específica elimina la propiedad de esa ruta).
La regla de última coincidencia gana (el error #1)
CODEOWNERS funciona con última coincidencia gana: cuando varios patrones coinciden con un archivo, solo la última línea coincidente asigna propietarios. El orden es el fallo más común. Coloca las reglas generales al inicio y las anulaciones específicas al final.
Este es el orden incorrecto — el comodín general queda al final y silenciosamente reclama todo:
# INCORRECTO — * es la última coincidencia, por lo que @core-team también es dueño de /src/auth/
/src/auth/ @security-team
* @core-team
Como * coincide con /src/auth/app.ts y aparece más adelante en el archivo, @security-team nunca es solicitado. Invierte el orden:
# CORRECTO — lo general primero, la anulación específica al final
* @core-team
/src/auth/ @security-team
Ahora un cambio en /src/auth/ solicita a @security-team, y todo lo demás recae en @core-team. Revisa el orden de los patrones cada vez que añadas una regla.
Por qué CODEOWNERS no se dispara silenciosamente
La mayoría de los reportes de “está configurado pero no ocurre nada” se deben a uno de estos casos. CODEOWNERS se lee desde la rama base del pull request, distingue mayúsculas de minúsculas, debe pesar menos de 3 MB y omite cualquier línea con sintaxis inválida — por lo que un archivo que parece correcto puede no disparar ninguna revisión.
| Síntoma | Causa | Solución |
|---|---|---|
| No se solicita ningún revisor | El archivo no está en la rama base del PR | Confirma CODEOWNERS en la rama a la que fusionas |
| Una regla específica nunca se dispara | Última coincidencia gana — un patrón posterior la anula | Mueve las reglas generales arriba y las específicas abajo |
| Una línea es ignorada, el resto funciona | Sintaxis inválida en esa línea — se omite silenciosamente | Abre el archivo en GitHub; un enlace “Syntax errors” señala las líneas incorrectas |
| El propietario está listado pero nunca es solicitado | El propietario no tiene acceso de escritura, o el usuario/equipo no existe | Otorga acceso de escritura; verifica el identificador |
| La fusión está bloqueada y nadie puede aprobar | Un equipo vacío es propietario de la ruta | Añade al menos un miembro al equipo |
| La ruta no coincide con nada | Ninguna regla la cubre | Añade una regla, o acepta la aprobación de cualquier colaborador con escritura |
| No hay solicitud en un PR borrador | Los PRs borrador no activan solicitudes de propietarios de código | Marca el PR como listo para revisión |
| La regla es ignorada en un archivo muy grande | Un CODEOWNERS de más de 3 MB no se carga | Consolida las entradas con comodines |
Dos detalles de permisos causan la mayoría de los fallos silenciosos. Las personas que designes como propietarios de código deben tener permisos de escritura — un propietario sin acceso de escritura es ignorado silenciosamente. Y cuando el propietario es un equipo, ese equipo debe ser visible y tener acceso de escritura, incluso si cada miembro ya lo tiene individualmente. Si nombras a un usuario o equipo que no existe o no tiene acceso, no se asigna ningún propietario de código — sin ninguna advertencia en el PR. GitHub sí muestra las líneas incorrectas: abre el archivo CODEOWNERS en la interfaz del repositorio para ver los errores resaltados, que también están disponibles a través de la API REST.
Más allá de la asignación estática: auto-asignación de equipos y Actions
CODEOWNERS mapea rutas a propietarios de forma estática. Dos mecanismos lo amplían cuando eso no es suficiente.
La auto-asignación integrada de equipos evita que se notifique a todo el equipo. En Organization → Teams → equipo → Settings → Code review, habilita la auto-asignación: cada vez que se solicita al equipo, la solicitud al equipo completo se elimina y se asigna a un subconjunto de miembros en su lugar. Elige round robin, que rota según la solicitud menos reciente, o load balance, que nivela el total de solicitudes recientes de cada miembro. Ten en cuenta una interacción: cuando la protección de rama requiere un propietario de código, la solicitud al equipo no puede eliminarse, por lo que la solicitud individual aparece además de la del equipo.
Recurre a GitHub Actions solo cuando la asignación deba depender del diff o de una etiqueta — algo que CODEOWNERS no puede expresar. Un flujo de trabajo mínimo usando actions/checkout (última versión v7.0.0, publicada el 18 de junio de 2026) más una acción de asignación de revisores con el trigger pull_request básico:
name: Assign Reviewers
on:
pull_request:
types: [opened, ready_for_review]
permissions:
pull-requests: write
jobs:
assign:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0 # necesario para git diff entre ramas
# ...mapea aquí las rutas modificadas o etiquetas a revisores
Usa la escalera de decisión como guía, no como menú: CODEOWNERS para reglas estáticas de ruta→propietario, auto-asignación de equipos para distribuir la carga dentro de un equipo, Actions para lógica basada en cambios o etiquetas.
Comienza con un único .github/CODEOWNERS en tu rama predeterminada, ordénalo de lo general a lo específico, habilita “Require review from Code Owners”, luego abre un PR de prueba y confirma que se solicita al propietario esperado — esa única verificación detecta los fallos silenciosos antes de que lleguen a producción.
Preguntas Frecuentes
¿Cuál es la diferencia entre CODEOWNERS y la auto-asignación de revisiones de código de equipos en GitHub?
CODEOWNERS es un archivo estático que mapea patrones de rutas a propietarios y solicita una revisión cada vez que un PR modifica una ruta coincidente. La auto-asignación de equipos es una configuración de la organización que, una vez que se solicita a un equipo, reemplaza la solicitud al equipo completo por un subconjunto de miembros elegidos por round robin o load balance. Funcionan juntos: CODEOWNERS decide qué equipo es propietario de una ruta, y la auto-asignación decide qué miembros de ese equipo reciben la notificación.
¿Puedo excluir un archivo específico de una regla CODEOWNERS usando negación como en gitignore?
No. GitHub CODEOWNERS no soporta la negación, por lo que un patrón como '!README.md' es rechazado como inválido y la línea se omite silenciosamente. La documentación de GitHub lista la negación con '!', los rangos de caracteres '[ ]' y el escape '#' como características de gitignore que no funcionan aquí. Para excluir una ruta, añade una regla posterior más específica que le asigne un propietario diferente, o deja la columna de propietario vacía en esa línea específica para eliminar la propiedad.
¿Por qué no se solicitan propietarios de código en mi pull request aunque el archivo parece correcto?
La causa más común es que CODEOWNERS se lee desde la rama base del PR, por lo que un archivo presente solo en tu rama de funcionalidad nunca se activa. Otras causas silenciosas incluyen un propietario sin acceso de escritura, un equipo propietario que no es visible o no tiene acceso de escritura, un equipo vacío, un PR borrador (que nunca activa solicitudes de propietarios de código), un archivo de más de 3 MB, rutas con mayúsculas y minúsculas incorrectas, o una línea inválida que GitHub omite sin advertencia.
¿CODEOWNERS bloquea las fusiones por sí solo, o necesito protección de rama?
CODEOWNERS por sí solo solo solicita revisores; nunca bloquea una fusión. Para bloquear fusiones también debes habilitar dos configuraciones juntas: 'Require a pull request before merging' y 'Require review from Code Owners'. Configúralas en un ruleset en Settings, Rules, Rulesets, o en una regla de protección de rama clásica en Settings, Branches. Ambas opciones están disponibles, siendo rulesets la más reciente.