Skip to content
jesusprodriguez.com

github-pr-review

GitHub: revisar una pull request

Reviewing a PR starting from the blast radius —what else breaks if this breaks— and moving on to security, contracts and coverage.

stack:
GitHub
task:
Review
version:
v1.0.0
updated:
size:
5.4 KB
read:
4 min
license:
CC-BY-4.0

When it fires

Before merging anything that touches a shared library, an API contract or the data schema.

description: Revisa una pull request de GitHub o una merge request de GitLab midiendo primero el radio de impacto - qué más se rompe si esto se rompe - y después seguridad, cambios de contrato y cobertura. Úsala antes de mergear algo que toca una librería compartida, un contrato de API o el esquema de la base de datos, o cuando una PR sea demasiado grande para leerla de arriba abajo.

  • Blast radius
  • Security sweep
  • Reversible migrations
  • A test that fails without the fix

How you ask for it

> Review PR 312: it touches the shared library and I want to know what else breaks.

Say this to the agent as it is: the skill loads itself from its description, you do not have to name it.

How to install one

/plugin marketplace add https://jesusprodriguez.com/skills/marketplace.json
/plugin install ingenieria@jprodriguez-toolkit

The native route, and the only one that updates itself: add the marketplace once and `/plugin marketplace update` brings in new versions. Skills get their own namespace (`azure-devops:azure-pr-review`).

The whole file

This is exactly what you download: no summaries, nothing trimmed.

Heads-up: the skill file itself is written in Spanish. Agents read it fine and answer in your language, but the prose below is not translated.

GitHub: revisar una pull request

Un cambio de cinco líneas en una utilidad compartida puede romper veinte servicios. Uno de quinientas en un componente de interfaz, ninguno. El tamaño del diff no es la medida del riesgo; el radio de impacto sí.

Por eso el orden de esta revisión no es el del diff: es el del riesgo.

1. Contexto antes que código

PR=123
gh pr view $PR --json title,body,labels,milestone
gh pr checks $PR                 # si la CI está roja, no revises todavía
gh pr diff $PR --name-only
gh pr diff $PR > /tmp/pr-$PR.diff

En GitLab: glab mr view, glab mr diff.

Lee la issue enlazada antes que el código. Sin saber qué se pretendía, la mitad de tus comentarios serán falsos positivos sobre decisiones deliberadas.

Y mira la lista de ficheros antes de abrir ninguno: 40 ficheros con 38 de traducciones y 2 de lógica son una PR de 2 ficheros.

2. Radio de impacto

Por cada fichero tocado, tres preguntas:

# ¿Quién importa esto?
grep -rl "from ['\"].*modulo-cambiado" src/ --include="*.ts"

# ¿Cruza la frontera de un servicio?
gh pr diff $PR --name-only | cut -d/ -f1-2 | sort -u

# ¿Toca contratos compartidos?
gh pr diff $PR --name-only | grep -E "types/|interfaces/|schemas/|models/"
NivelQué lo provoca
CRÍTICOLibrería compartida, modelo de datos, middleware de auth, contrato de API
ALTOServicio del que dependen otros, configuración compartida, variables de entorno
MEDIOCambio interno de un servicio, función de utilidad
BAJOComponente de interfaz, tests, documentación

El nivel decide cuánto miras, no si apruebas.

3. Seguridad

Un barrido sobre el diff encuentra lo evidente. Lo que encuentre, se verifica a mano: son pistas, no veredictos.

D=/tmp/pr-$PR.diff

grep -nE "(password|secret|api_key|token|private_key)\s*=\s*['\"][^'\"]{8,}" $D
grep -nE "AKIA[0-9A-Z]{16}" $D                      # claves de AWS
grep -n  "dangerouslySetInnerHTML\|innerHTML\s*=" $D # XSS
grep -nE "\beval\(|\bexec\(" $D
grep -nE "md5\(|sha1\(" $D                          # hash inseguro
grep -nE "path\.join\(.*req\.|readFile\(.*req\." $D  # path traversal
grep -n  "query\|execute\|raw(" $D | grep -E '\$\{|f"|%s'  # SQL por interpolación

Si aparece un secreto, el comentario no es «quítalo»: es «rótalo, ya está en el historial». Borrarlo en un commit posterior no lo borra de ningún sitio.

Y lo que ningún grep ve: secretos que se filtran por un mensaje de error o una traza de log. Búscalos leyendo, no buscando.

4. Cambios que rompen a otros

# Rutas o tipos eliminados
grep "^-" $D | grep -E "router\.(get|post|put|delete|patch)\(|^-\s*(export\s+)?(interface|type) "

# Migraciones destructivas
grep -E "DROP TABLE|DROP COLUMN|ALTER.*NOT NULL|DROP INDEX" $D

# Variables de entorno nuevas: ¿están en producción?
grep "^+" $D | grep -oE "process\.env\.[A-Z_]+" | sort -u

Tres preguntas que se olvidan siempre:

  • ¿La migración es reversible? ¿Bloquea la tabla mientras corre?
  • ¿El despliegue admite versión antigua y nueva a la vez, o hay una ventana en la que la mitad de las instancias falla?
  • Una configuración nueva sin valor por defecto: el entorno que no la tenga arranca bien y falla en la primera petición.

5. Cobertura

gh pr diff $PR --name-only | grep -vE "\.test\.|\.spec\.|__tests__" | wc -l
gh pr diff $PR --name-only | grep -E  "\.test\.|\.spec\.|__tests__" | wc -l

La pregunta no es «¿hay tests?», es: ¿existe un test que falle sin este arreglo? Si el bug puede volver sin que nadie se entere, la PR no está terminada.

Señales: función pública nueva sin test; tests borrados sin borrar el código que cubrían; caminos de auth o de pagos con cobertura parcial.

6. El informe

Radio de impacto: ALTO — toca lib/auth, usada por 5 servicios
Seguridad: 1 hallazgo (medio)
Tests: +2% de cobertura
Rompe compatibilidad: no detectado

--- BLOQUEANTE ---
1. Inyección SQL en src/db/users.ts:42
   Interpolación directa en el WHERE.
   Arreglo: db.query("SELECT * WHERE id = $1", [userId])

--- DEBERÍA ARREGLARSE ---
2. POST /api/admin/reset sin comprobación de rol

--- SUGERENCIAS ---
3. N+1 en src/services/reports.ts:88 — findUser() dentro de un map()

--- BIEN ---
- La migración trae su down()
- El flujo nuevo de auth está bien cubierto

Reglas de tono

  • Comenta el código, nunca a la persona: «esto se rompe si X», no «no has tenido en cuenta X».
  • Separa siempre bloqueante de sugerencia. Un revisor que no prioriza obliga al autor a adivinar, y adivinar mal.
  • Todos los comentarios en una sola ronda. Ir soltándolos a goteo alarga la PR días y agota a quien la escribió.
  • Si está bien, dilo y aprueba. Inventar pegas para justificar la revisión es la forma más rápida de que dejen de pedírtelas.
  • Si una PR es demasiado grande para revisarla bien, el comentario correcto es «pártela», no una aprobación con la vista gorda.