Conversas de PR
Uma pull request já é o sítio onde acontece a conversa sobre código. As conversas
de PR transformam-na numa superfície de um espaço de trabalho do Control Center,
tal como uma ponte de chat transforma o
Slack numa: mencione com @ o bot da GitHub App do servidor numa PR, responda
dentro das respetivas threads de revisão ou adicione a etiqueta ai-review, e o
trabalho acontece no espaço de revisão da PR — sujeito à mesma atribuição e às
mesmas barreiras que qualquer coisa escrita na aplicação. Um comentário está
também condicionado pela pertença; a etiqueta não, porque não tem autor. As
respostas do bot voltam para o GitHub, no canal onde a pergunta foi feita.
Três decisões moldam a funcionalidade, e cada uma é a mesma decisão que a ponte de chat tomou para o chat, reformulada para uma forge: em que direção corre a ligação, o que autoriza um comentário que chega do exterior e a quem é atribuído cada lado.
A sondagem é o transporte
Secção intitulada “A sondagem é o transporte”O único canal de push que o GitHub oferece a uma aplicação é um webhook, e um webhook precisa de um URL de entrada — exatamente a única coisa de que esta superfície nunca precisa. Por isso, a descoberta é uma varredura: a cada minuto, mais ou menos, uma pesquisa com alias por instalação da aplicação pede ao GitHub as PRs que mencionam o bot (ou o respetivo slug curto) e as PRs abertas que têm a etiqueta de revisão, as PRs que já têm um espaço de revisão têm as suas threads de comentários lidas, e tudo é comparado por id de comentário com o que foi visto na varredura anterior.
Vale a pena nomear as consequências de conceção:
- A latência é um intervalo de varredura, não um evento. O reconhecimento 👀 chega dentro de cerca de um minuto. Nada de urgente depende disso.
- Exatamente uma vez, por comentário. Os ids de comentário são únicos em todo o GitHub; cada um é registado no momento em que é classificado como elegível, antes de qualquer ação sobre ele. Uma falha pode perder o tratamento de um comentário, nunca acioná-lo duas vezes.
- O tempo offline é recuperado, não reproduzido. O conjunto de comentários já vistos é persistido, pelo que um reinício entrega o que chegou enquanto o servidor estava em baixo. A única exceção é a primeira varredura de sempre: sem memória com que comparar, tudo o que está pendente é registado em silêncio — um operador que etiquetou vinte PRs antes de este servidor existir não pode voltar e encontrar vinte revisões a correr.
- A etiqueta é um conjunto, não um evento. A pesquisa comunica a presença da etiqueta, pelo que uma PR etiquetada dispara uma vez, e uma só. Voltar a adicionar uma etiqueta depois de a remover é invisível para a varredura; uma menção é a via de repetição.
A pesquisa corre uma vez por conta de instalação, no cliente do próprio proprietário dessa conta, porque um token de instalação só vê os repos da sua própria instalação — uma única credencial a nível de servidor deixaria passar em silêncio todas as PRs sob as outras instalações da aplicação.
A pertença autoriza, não o comentário
Secção intitulada “A pertença autoriza, não o comentário”Um comentário numa PR chega com pouco mais do que o login do autor — uma identidade externa não autenticada até prova em contrário. O bot resolve-a com base num índice inverso dos membros do espaço de trabalho e das respetivas contas GitHub ligadas, reconstruído de acordo com um TTL porque há pessoas que iniciam sessão e são convidadas enquanto o servidor corre.
Falhar de forma fechada assemelha-se a uma escada, e cada degrau responde na thread em que recusou:
- Um login desconhecido — não ligado, ou ligado por alguém que não é membro deste espaço de trabalho — é instruído a iniciar sessão e a confirmar que pertence ao espaço
- Um membro só de leitura (
viewerouguest) é informado de que o seu papel não pode iniciar trabalho
Os dois casos de login desconhecido partilham uma única resposta: o índice inverso só devolve um membro deste espaço de trabalho, pelo que uma conta não ligada e um não membro ligado são a mesma falha. Nenhum deles avança. Um comentário nunca é atribuído a alguém que não o enviou, e as palavras de um estranho nunca entram num espaço de trabalho que não conseguem ver.
A etiqueta ai-review não tem autor para resolver, pelo que não sobe esta
escada. Adicioná-la inicia a revisão no espaço de trabalho que já tem o
repositório ligado.
Duas identidades, de propósito
Secção intitulada “Duas identidades, de propósito”Cada lado da conversa transporta uma identidade diferente, e essa diferença é a funcionalidade:
- No GitHub, o bot é o servidor. Todos os comentários, reações e respostas que a ponte publica usam o token de instalação da aplicação. Ninguém clicou em nada num cliente, pelo que nada pede emprestada a conta de uma pessoa — a mesma regra que mantém os webhooks e a sondagem fora das credenciais humanas.
- No espaço, a pergunta é sua. A mensagem é atribuída ao membro em que o autor foi resolvido, e a execução do agente corre em nome dele: os commits indicam-no como coautor, e o seletor de autonomia e as barreiras de ação do espaço aplicam-se exatamente como a uma mensagem escrita na aplicação. As escritas na forge feitas pela execução continuam a sair como a aplicação — a mesma regra do ponto anterior —, e não com o token pessoal do membro.
Publicar os resultados da revisão de volta no GitHub continua a ser uma decisão de uma pessoa, tomada no Control Center. Uma menção pode iniciar uma revisão; só um ser humano publica uma.
A proteção contra ciclos e o nome curto
Secção intitulada “A proteção contra ciclos e o nome curto”Tudo o que é da autoria de uma conta de bot é descartado antes de qualquer
barreira ser avaliada — a nossa especificamente, e todos os sufixos [bot], para
que o bot de revisão de outra aplicação também não possa acordar o nosso. Sem
isto, as respostas do próprio bot chegariam como novos comentários e voltariam a
acioná-lo para sempre.
O sufixo [bot] é também a razão pela qual a forma curta existe. O GitHub fixa o
login de uma conta de aplicação em <slug>[bot], não oferece preenchimento
automático para ele e nunca resolve @slug para a aplicação — por isso, aceitar
o slug isolado é uma decisão do nosso comparador, e descobri-lo exige uma via
de pesquisa de texto de comentário em bruto, em vez do índice de menções do
GitHub. O custo é declarado em vez de atenuado: um utilizador humano que partilhe
o slug da aplicação endereça o bot em todas as menções curtas a si próprio. Nomes
de aplicação distintos tornam a colisão hipotética.
O que deliberadamente não é oferecido
Secção intitulada “O que deliberadamente não é oferecido”- Sem publicação automática. Os resultados ficam no espaço de revisão; publicar no GitHub é uma ação separada e humana
- Sem identidade difusa. O autor é resolvido para exatamente um membro ou é recusado — não existe atribuição por tentativa
- Sem webhook da GitHub App. Esta superfície nunca regista nenhum, pelo que não há um URL de entrada para expor a comentários de PR. Os outros webhooks do produto (pipelines, sincronização de tickets) são uma configuração separada e opcional.
Ver também
Secção intitulada “Ver também”- Falar com o Control Center a partir de uma PR do GitHub: o guia prático para tudo isto
- Pontes de chat: as mesmas três decisões, tomadas para o chat
- Criar a GitHub App: de onde vem a identidade do bot
- Multijogador — identidade, pertença e presença: as identidades e os papéis pelos quais um login é resolvido
- Barreiras: o que o agente que responde pode fazer
- Usar revisão com IA: o pipeline que uma menção ou etiqueta inicia