Conversazioni sulle PR
Una pull request è già il luogo in cui avviene la conversazione sul codice. Le
conversazioni sulle PR la rendono una superficie su uno spazio di lavoro di
Control Center, allo stesso modo in cui un
ponte di chat rende tale Slack:
@menziona il bot della GitHub App del server su una PR, rispondi all’interno
dei suoi thread di revisione oppure aggiungi l’etichetta ai-review, e il
lavoro avviene nello spazio di revisione della PR — con la stessa attribuzione
e gli stessi guardrail di qualsiasi cosa digitata nell’app. Anche un commento è
vincolato all’appartenenza; l’etichetta no, perché non ha un autore. Le
risposte del bot tornano su GitHub, nel canale in cui è stata posta la domanda.
Tre decisioni danno forma alla funzionalità, e ciascuna è la stessa decisione che il ponte di chat ha preso per la chat, riformulata per una forge: in quale direzione scorre la connessione, cosa autorizza un commento che arriva dall’esterno e a chi è attribuito ciascun lato.
Il polling è il trasporto
Sezione intitolata “Il polling è il trasporto”L’unico canale push di GitHub per un’app è un webhook, e un webhook richiede un URL in ingresso — l’unica cosa che questa superficie non richiede mai, di proposito. La scoperta è quindi una scansione: all’incirca ogni minuto, una ricerca con alias per ogni installazione dell’app chiede a GitHub le PR che menzionano il bot (o il suo slug breve) e le PR aperte che portano l’etichetta di revisione, le PR che hanno già uno spazio di revisione vedono leggere i propri thread di commenti, e tutto viene confrontato per id del commento con quanto visto alla scansione precedente.
Vale la pena dare un nome alle conseguenze progettuali:
- La latenza è un intervallo di scansione, non un evento. La conferma 👀 arriva entro circa un minuto. Nulla di urgente vi dipende.
- Esattamente una volta, per commento. Gli id dei commenti sono unici in tutto GitHub; ciascuno viene registrato nel momento in cui è classificato come idoneo, prima che qualsiasi cosa agisca su di esso. Un crash può perdere la gestione di un commento, ma non può mai attivarlo due volte.
- Il tempo offline viene recuperato, non riprodotto. L’insieme degli elementi visti è persistito, quindi un riavvio consegna ciò che è arrivato mentre era inattivo. L’unica eccezione è la primissima scansione in assoluto: senza alcuna memoria con cui confrontare, tutto ciò che è in sospeso viene registrato in silenzio — un operatore che ha etichettato venti PR prima che questo server esistesse non deve ritrovarsi con venti revisioni in esecuzione.
- L’etichetta è un insieme, non un evento. La ricerca segnala la presenza dell’etichetta, quindi una PR etichettata si attiva una volta sola, per sempre. Riaggiungere un’etichetta dopo averla rimossa è invisibile alla scansione; una menzione è la via per rieseguire.
La ricerca viene eseguita una volta per account di installazione sul client di quel proprietario, perché un token di installazione vede solo i repository della propria installazione — un’unica credenziale a livello di server mancherebbe silenziosamente ogni PR sotto le altre installazioni dell’app.
È l’appartenenza ad autorizzare, non il commento
Sezione intitolata “È l’appartenenza ad autorizzare, non il commento”Un commento a una PR arriva portando poco più del login di un autore — un’identità esterna non autenticata finché non viene dimostrato il contrario. Il bot la risolve rispetto a un indice inverso dei membri dello spazio di lavoro e dei loro account GitHub collegati, ricostruito con un TTL perché le persone accedono e vengono invitate mentre il server è in esecuzione.
Negare in caso di dubbio somiglia a una scala, e ogni gradino risponde nel thread in cui ha rifiutato:
- Un login sconosciuto — non collegato, o collegato da qualcuno che non è membro di questo spazio di lavoro — riceve l’indicazione di accedere e di assicurarsi di appartenervi
- Un membro in sola lettura (
vieweroguest) riceve l’indicazione che il suo ruolo non può avviare lavoro
I due casi di login sconosciuto condividono una sola risposta: l’indice inverso restituisce solo un membro di questo spazio di lavoro, quindi un account non collegato e un non membro collegato sono lo stesso mancato riscontro. Nessuno di essi procede. Un commento non viene mai attribuito a qualcuno che non lo ha inviato, e le parole di un estraneo non entrano mai in uno spazio di lavoro che non può vedere.
L’etichetta ai-review non ha un autore da risolvere, quindi non risale questa
scala. Aggiungerla avvia la revisione nello spazio di lavoro che ha già
collegato il repository.
Due identità, di proposito
Sezione intitolata “Due identità, di proposito”Ciascun lato della conversazione porta un’identità diversa, e la differenza è la funzionalità:
- Su GitHub, il bot è il server. Ogni commento, reazione e risposta pubblicati dal ponte viaggia sul token di installazione dell’app. Nessuno ha cliccato nulla in un client, quindi nulla prende in prestito l’account di una persona — la stessa regola che tiene i webhook e il polling lontani dalle credenziali umane.
- Nello spazio, la domanda è tua. Il messaggio è attribuito al membro in cui l’autore si è risolto, e l’esecuzione dell’agente avviene per suo conto: i commit lo vedono come coautore, e il selettore dell’autonomia e i guardrail delle azioni dello spazio si applicano esattamente come a un messaggio digitato nell’app. Le scritture sulla forge provenienti dall’esecuzione escono comunque come l’app — la stessa regola del punto precedente — non sul token personale del membro.
Pubblicare i risultati della revisione di nuovo su GitHub resta una decisione di una persona, presa in Control Center. Una menzione può avviare una revisione; solo un essere umano la pubblica.
La protezione anti-loop e il nome breve
Sezione intitolata “La protezione anti-loop e il nome breve”Tutto ciò che è stato creato da un account bot viene scartato prima che venga
eseguito qualsiasi controllo — il nostro in particolare, e ogni suffisso
[bot], così nemmeno il bot di revisione di un’altra app può svegliare il
nostro. Senza questo, le risposte stesse del bot arriverebbero come nuovi
commenti e lo riattiverebbero all’infinito.
Il suffisso [bot] è anche il motivo per cui esiste la forma breve. GitHub
fissa il login di un account app a <slug>[bot], non offre alcun completamento
automatico per esso e non risolve mai @slug nell’app — quindi accettare lo
slug nudo è una decisione del nostro matcher, e scoprirlo richiede una corsia
di ricerca sul commento in testo grezzo anziché l’indice delle menzioni di
GitHub. Il costo viene dichiarato invece che nascosto: un utente umano che
condivide lo slug dell’app si rivolge al bot con ogni menzione in forma breve
di se stesso. Nomi di app distintivi rendono la collisione ipotetica.
Cosa non viene offerto di proposito
Sezione intitolata “Cosa non viene offerto di proposito”- Nessuna pubblicazione automatica. I risultati arrivano nello spazio di revisione; pubblicare su GitHub è un’azione separata, umana
- Nessuna identità approssimativa. L’autore si risolve in esattamente un membro oppure viene rifiutato — non esiste un’attribuzione basata su congetture
- Nessun webhook della GitHub App. Questa superficie non ne registra mai uno, quindi non c’è alcun URL in ingresso da esporre per i commenti delle PR. Gli altri webhook del prodotto (pipeline, sincronizzazione dei ticket) sono una configurazione separata e opzionale.
Vedi anche
Sezione intitolata “Vedi anche”- Parla con Control Center da una PR GitHub: la guida pratica per tutto questo
- Ponti di chat: le stesse tre decisioni, prese per la chat
- Crea la GitHub App: da dove viene l’identità del bot
- Multigiocatore — identità, appartenenza e presenza: i principali e i ruoli attraverso cui si risolve un login
- Guardrail: cosa è consentito fare all’agente che risponde
- Usa la revisione basata sull’IA: la pipeline che una menzione o un’etichetta avvia