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 cantidad de atención humana necesaria para entregar código de alta calidad. Un lugar que seguía siendo obstinadamente manual eran las revisiones de pull request. Entre Cursor como nuestro IDE, ChatGPT/Codex para prototipado y gemini-cli para comprobaciones rápidas, nuestros flujos de trabajo locales eran rápidos—pero la CI todavía esperaba a un humano.
Así que nos hicimos una pregunta simple: ¿podríamos dejar que un modelo de lenguaje grande lea el diff, detecte problemas y comente directamente en el PR?
Resultó que: sí. Solo hicieron falta unas pocas líneas de pegamento en GitHub Actions para obtener revisiones útiles y estructuradas en cada pull request.
No intentábamos reemplazar a los humanos. Queríamos una primera pasada que:
Si un cambio está bien, queremos que el bot simplemente lo diga y se aparte.
@google/gemini-cli dentro de CI para ejecutar el paso de revisión automatizada.gh) para comentar en el PR.Here’s the full Action we’re running. Drop it into .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 que podamos comparar (diff) con la rama base del PR de forma fiable.
Toolchain de Rust instala rustfmt y clippy porque nuestros repositorios a menudo incluyen código Rust; eso se ejecuta en otras partes de la canalización, pero mantener la configuración del toolchain aquí evita sorpresas.
Node es necesario para el 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 bajo revisión.
Pasamos el prompt a gemini (el CLI lee @pr.diff en línea como referencia de archivo) y capturamos la salida en markdown del modelo en review.md.
Adjuntamos la revisión al Job Summary ($GITHUB_STEP_SUMMARY) para que sea visible en la UI de Actions.
Comentamos en el PR usando gh pr comment … --body-file review.md.
Las salidas del LLM solo son tan buenas como las instrucciones. La nuestra 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: “Se ve bien.” Perfecto—eso es exactamente lo que queremos.
GEMINI_API_KEY y GITHUB_TOKEN en los secretos del repo u organización. Mantén los scopes restringidos. La Action establece permissions: write-all porque publica un comentario; restringe esto si tu política lo requiere.git diff origin/${{ github.base_ref }} da el contexto correcto. Si tu flujo descarga solo el commit de merge, asegúrate de que la rama base esté disponible o ajusta a github.event.pull_request.base.sha.pull_request_target con endurecimiento cuidadoso, o condicionar 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 “cambia el nombre de esta variable” y más tiempo en arquitectura, flujos de datos y límites de seguridad. Eso significa:
También es sorprendentemente bueno en consistencia. Un LLM no olvidará el patrón acordado de manejo de errores entre servicios ni nuestra estructura de logs preferida; aplica esas comprobaciones de forma uniforme en cada PR.
Este patrón funciona con casi cualquier modelo o CLI. Unas extensiones fáciles:
failed para bloquear merges hasta que se aborden.gh lo soporta) para feedback aún más directo.ai-review, o añadir automáticamente una etiqueta needs-attention cuando aparecen hallazgos de alta prioridad.Nada de esto reemplaza a un humano aprobando un merge. Es un filtro ligero que se paga por sí mismo desde el primer día.