Nos encanta la automatización. La usamos para potenciar nuestra infraestructura, para escalar cargas de trabajo hasta cero y —cada vez más— para reducir la atención humana necesaria para entregar código de alta calidad. Un lugar que aún parecía terco y manual eran las revisiones de pull requests. Entre Cursor como nuestro IDE, ChatGPT/Codex para prototipos y gemini-cli para revisiones rápidas, nuestros flujos locales eran veloces—pero la CI todavía esperaba por un humano.
Así que hicimos una pregunta sencilla: ¿podríamos dejar que un modelo de lenguaje grande lea el diff, detecte problemas y comente directamente en el PR?
Resulta que: sí. Solo tomó unas pocas líneas de pegamento en GitHub Actions para obtener revisiones estructuradas y útiles en cada pull request.
No queríamos reemplazar humanos. Queríamos un primer filtro que:
Si un cambio está bien, queremos que el bot simplemente lo diga y se haga a un lado.
@google/gemini-cli dentro de CI para ejecutar el paso de revisión automatizada.gh) para comentar en el PR.Aquí está la Action completa que estamos ejecutando. Colócala en .github/workflows/gemini-pr.yml:
name: gemini-pr
on:
workflow_dispatch:
pull_request:
jobs:
build:
permissions: write-all
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: 'true'
fetch-depth: 0
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
components: rustfmt, clippy
cache: false
- uses: actions/setup-node@v4
with:
node-version: 20
- name: install gemini
run: |
npm install -g @google/gemini-cli
- name: gemini
run: |
echo "merging into ${{ github.base_ref }}"
git diff origin/${{ github.base_ref }} > pr.diff
echo $PROMPT | gemini > review.md
cat review.md >> $GITHUB_STEP_SUMMARY
gh pr comment ${{ github.event.pull_request.number }} --body-file review.md
env:
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PROMPT: >
please review the changes of @pr.diff (this pull request) and suggest improvements or provide insights into potential issues.
do not document or comment on existing changes, if everything looks good, just say so.
can you categorise the changes and improvesments into low, medium and high priority?
Whenever you find an issue, please always provide an file and line number as reference information. if multiple files are affected, please provide a list of files and line numbers.
provide the output in markdown format and do not include any other text.
Checkout con fetch-depth: 0 para poder hacer diff con la rama base del PR de manera fiable.
Rust toolchain instala rustfmt y clippy porque nuestros repos a menudo incluyen código Rust; esos se ejecutan en otra parte de nuestro pipeline, pero mantener la configuración aquí evita sorpresas.
Node es requerido para gemini-cli.
Instalamos @google/gemini-cli globalmente dentro del runner.
Creamos un archivo diff:
git diff origin/${{ github.base_ref }} > pr.diff
Esto asegura que el modelo vea solo los cambios en revisión.
Pipeteamos el prompt hacia gemini (la CLI lee @pr.diff inline como referencia de archivo) y capturamos la salida markdown del modelo en review.md.
Añadimos la revisión al Resumen del Job ($GITHUB_STEP_SUMMARY) para que sea visible en la UI de Actions.
Comentamos en el PR usando gh pr comment … --body-file review.md.
Los outputs del LLM son tan buenos como las instrucciones. El nuestro mantiene las cosas prácticas:
Iteramos un poco para llegar a esto. Los ajustes más impactantes fueron: insistir en referencias de archivo/línea y prohibir prosa adicional.
En un PR típico, vemos secciones como:
Si todo está bien, recibimos una línea: “Looks good.” Perfecto—eso es exactamente lo que queremos.
GEMINI_API_KEY y GITHUB_TOKEN en secretos del repo u organización. Mantén alcances estrictos. La Action establece permissions: write-all porque publica un comentario; restríngelo si tu política lo requiere.git diff origin/${{ github.base_ref }} da el contexto correcto. Si tu flujo solo obtiene el commit de merge, asegúrate que la rama base esté disponible o ajusta a github.event.pull_request.base.sha.pull_request_target con cuidado y endurecimiento, o guardar la revisión detrás de etiquetas.pull_request (no en cada push).Las revisiones automatizadas hacen que los humanos sean más selectivos con su atención. Pasamos menos tiempo en “renombrar esta variable” y más en arquitectura, flujos de datos y límites de seguridad. Eso significa:
También es sorprendentemente bueno para la consistencia. Un LLM no olvidará el patrón acordado de manejo de errores entre servicios o nuestra estructura preferida de logs; aplica esos controles uniformemente en cada PR.
Este patrón funciona con casi cualquier modelo o CLI. Algunas extensiones fáciles:
failed para bloquear merges hasta resolver.gh lo soporta) para feedback aún más directo.ai-review, o añade automáticamente una etiqueta needs-attention cuando aparecen hallazgos de alta prioridad.Nada de esto reemplaza la aprobación humana para un merge. Es un filtro ligero que se paga a sí mismo desde el primer día.