Adoriamo l’automazione. La usiamo per alimentare la nostra infrastruttura, per ridurre i carichi di lavoro a zero e—sempre più spesso—per diminuire l’attenzione umana necessaria a rilasciare codice di alta qualità. Un ambito che ancora ci sembrava ostinatamente manuale erano le revisioni delle pull request. Tra Cursor come nostro IDE, ChatGPT/Codex per il prototipo e gemini-cli per controlli rapidi, i nostri workflow locali erano veloci—ma la CI aspettava ancora un umano.
Così ci siamo posti una domanda semplice: potevamo lasciare che un modello di linguaggio ampio leggesse il diff, individuasse problemi e commentasse direttamente sulla PR?
Si è scoperto: sì. Sono bastate poche righe di colla con GitHub Actions per ottenere revisioni utili e strutturate su ogni pull request.
Non volevamo sostituire gli umani. Volevamo un primo passaggio che:
Se un cambiamento va bene, vogliamo che il bot lo dica semplicemente e si faccia da parte.
@google/gemini-cli dentro la CI per eseguire il passo di revisione automatizzato.gh) per commentare sulla PR.Ecco l’Action completa che stiamo eseguendo. Inseriscila in .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 così possiamo fare diff affidabili contro il branch base della PR.
Toolchain Rust installa rustfmt e clippy perché i nostri repo spesso includono codice Rust; questi strumenti girano anche in altri punti della pipeline, ma mantenere la configurazione qui evita sorprese.
Node è richiesto per gemini-cli.
Installiamo @google/gemini-cli globalmente nel runner.
Creiamo un file diff:
git diff origin/${{ github.base_ref }} > pr.diff
Così il modello vede solo le modifiche in revisione.
Pipiamo il prompt dentro gemini (la CLI legge @pr.diff inline come riferimento file) e catturiamo l’output markdown del modello in review.md.
Aggiungiamo la review al Riepilogo del Job ($GITHUB_STEP_SUMMARY) così è visibile nell’interfaccia delle Actions.
Commentiamo sulla PR usando gh pr comment … --body-file review.md.
Gli output di LLM sono validi quanto le istruzioni che ricevono. Il nostro mantiene le cose pratiche:
Abbiamo iterato un po’ per arrivare a questo. Le modifiche più incisive sono state: insistere su riferimenti file/linea e vietare testi extra.
Su una PR tipica vediamo sezioni come:
Se tutto va bene, otteniamo una frase singola: “Looks good.” Perfetto—è proprio quello che vogliamo.
GEMINI_API_KEY e GITHUB_TOKEN nei secrets del repo o dell’organizzazione. Mantieni gli scope stretti. L’Action imposta permissions: write-all perché pubblica un commento; restringi se la tua policy lo richiede.git diff origin/${{ github.base_ref }} fornisce il contesto corretto. Se il tuo workflow scarica solo il commit di merge, assicurati che il branch base sia disponibile o adatta a github.event.pull_request.base.sha.pull_request_target con un rafforzamento attento, o limitare la revisione dietro certi label.pull_request (non su ogni push).Le revisioni automatiche rendono gli umani più selettivi nell’attenzione. Passiamo meno tempo su “rinomina questa variabile” e più su architettura, flussi di dati e confini di sicurezza. Questo significa:
È anche sorprendentemente bravo a garantire la coerenza. Un LLM non dimentica il pattern di gestione errori concordato tra servizi o la nostra struttura log preferita; applica quei controlli uniformemente su ogni PR.
Questo schema funziona con quasi ogni modello o CLI. Alcune estensioni facili:
gh lo supporta) per feedback ancora più puntuale.ai-review, o aggiungi automaticamente un label needs-attention se compaiono riscontri ad alta priorità.Niente di tutto ciò sostituisce un umano che approva un merge. È un filtro leggero che si ripaga dal primo giorno.