Przejdź do głównej zawartości

Rozmowy w PR

Pull request to już miejsce, w którym toczy się rozmowa o kodzie. Rozmowy w PR czynią z niego powierzchnię obszaru roboczego Control Center — tak samo jak most czatu czyni nią Slack: @wspomnij bota aplikacji GitHub serwera w PR, odpowiedz w jego wątkach recenzji albo dodaj etykietę ai-review, a praca wykona się w przestrzeni recenzji tego PR — z tą samą atrybucją i tymi samymi guardrailami co wszystko wpisane w aplikacji. Komentarz podlega dodatkowo bramce członkostwa; etykieta nie, bo nie ma autora. Odpowiedzi bota wracają na GitHuba, w tym samym wątku, w którym zadano pytanie.

Funkcję kształtują trzy decyzje, a każda z nich to ta sama decyzja, którą most czatu podjął dla czatu, wyrażona na nowo dla hosta kodu: w którym kierunku biegnie połączenie, co autoryzuje komentarz nadchodzący z zewnątrz oraz komu przypisywana jest każda ze stron.

Jedynym kanałem wypychania dla aplikacji na GitHubie jest webhook, a webhook potrzebuje przychodzącego adresu URL — czyli dokładnie tego, czego ta powierzchnia celowo nigdy nie wymaga. Odkrywanie polega więc na obchodzie: mniej więcej raz na minutę jedno wyszukiwanie z aliasem na każdą instalację aplikacji pyta GitHuba o PR-y wspominające bota (lub jego krótki slug) oraz o otwarte PR-y noszące etykietę recenzji; PR-y, które mają już przestrzeń recenzji, mają odczytywane wątki komentarzy, a wszystko jest porównywane po identyfikatorze komentarza z tym, co widziano podczas poprzedniego obchodu.

Konsekwencje tego projektu warto nazwać:

  • Opóźnienie to interwał obchodu, nie zdarzenie. Potwierdzenie 👀 pojawia się w ciągu mniej więcej minuty. Nic pilnego na nim nie polega.
  • Dokładnie raz, na komentarz. Identyfikatory komentarzy są unikalne w całym GitHubie; każdy jest zapisywany w chwili zakwalifikowania jako kwalifikujący się, zanim cokolwiek na nim zadziała. Awaria może zgubić obsługę komentarza, ale nigdy nie uruchomi go podwójnie.
  • Czas offline jest nadrabiany, a nie odtwarzany. Zbiór widzianych komentarzy jest utrwalany, więc restart dostarcza to, co nadeszło, gdy serwer był niedostępny. Jedyny wyjątek to pierwszy obchód w ogóle: bez pamięci, z którą można by porównywać, wszystko zaległe jest zapisywane po cichu — operator, który oznaczył dwadzieścia PR-ów, zanim ten serwer powstał, nie może po powrocie zastać dwudziestu uruchomionych recenzji.
  • Etykieta to stan, nie zdarzenie. Wyszukiwanie raportuje obecność etykiety, więc oznaczony PR uruchamia się tylko raz. Ponowne dodanie etykiety po jej usunięciu jest dla obchodu niewidoczne; drogą do ponownego uruchomienia jest wzmianka.

Wyszukiwanie działa raz na konto instalacji, na własnym kliencie tego właściciela, ponieważ token instalacji widzi tylko repozytoria swojej instalacji — jedno poświadczenie obejmujące cały serwer po cichu pomijałoby każdy PR w pozostałych instalacjach aplikacji.

Komentarz w PR przychodzi z niewiele więcej niż loginem autora — nieuwierzytelnioną tożsamością zewnętrzną, dopóki nie zostanie potwierdzona. Bot rozwiązuje go za pomocą indeksu odwrotnego członków obszaru roboczego i ich połączonych kont GitHub, odbudowywanego według TTL, ponieważ ludzie logują się i otrzymują zaproszenia, gdy serwer działa.

Domyślna odmowa układa się w drabinę, a każdy jej szczebel odpowiada w wątku, w którym odmówił:

  • Nieznany login — niepołączony albo połączony przez kogoś, kto nie jest członkiem tego obszaru roboczego — dowiaduje się, że powinien się zalogować i upewnić, że należy do tego obszaru roboczego
  • Członek z uprawnieniami tylko do odczytu (viewer lub guest) dowiaduje się, że jego rola nie może rozpoczynać pracy

Oba przypadki nieznanego loginu mają jedną wspólną odpowiedź: indeks odwrotny zwraca wyłącznie członka tego obszaru roboczego, więc konto niepołączone i połączone, lecz nienależące do niego, to ta sama sytuacja braku trafienia. Żaden z nich nie przechodzi dalej. Komentarz nigdy nie jest przypisywany komuś, kto go nie wysłał, a słowa obcego nigdy nie trafiają do obszaru roboczego, którego nie widzi.

Etykieta ai-review nie ma autora do rozwiązania, więc nie wspina się po tej drabinie. Jej dodanie rozpoczyna recenzję w obszarze roboczym, który już ma połączone repozytorium.

Każda strona rozmowy ma inną tożsamość i właśnie ta różnica jest funkcją:

  • Na GitHubie bot jest serwerem. Każdy komentarz, reakcja i odpowiedź publikowane przez most jadą na tokenie instalacji aplikacji. Nikt nic nie kliknął w kliencie, więc nic nie pożycza konta osoby — ta sama zasada, która trzyma webhooki i odpytywanie z dala od ludzkich poświadczeń.
  • W przestrzeni pytanie należy do Ciebie. Wiadomość jest przypisywana członkowi, na którego rozwiązano autora, a uruchomienie agenta przebiega w jego imieniu: commity mają go jako współautora, a suwak autonomii przestrzeni i guardraile działań obowiązują dokładnie tak samo jak w przypadku wiadomości wpisanej w aplikacji. Zapis do hosta kodu z tego uruchomienia i tak wychodzi jako aplikacja — zgodnie z zasadą z powyższego punktu — a nie na osobistym tokenie członka.

Publikowanie ustaleń recenzji z powrotem na GitHuba pozostaje decyzją człowieka, podejmowaną w Control Center. Wzmianka może rozpocząć recenzję; publikuje ją wyłącznie człowiek.

Wszystko autorstwa konta bota jest odrzucane, zanim zadziała jakakolwiek bramka — naszego w szczególności, a także każdego z sufiksem [bot], więc bot recenzencki innej aplikacji również nie obudzi naszego. Bez tego własne odpowiedzi bota przychodziłyby jako nowe komentarze i wyzwalały go w nieskończoność.

Sufiks [bot] jest też powodem, dla którego istnieje forma skrócona. GitHub ustala login konta aplikacji na <slug>[bot], nie oferuje dla niego autouzupełniania i nigdy nie rozwiązuje @slug na aplikację — przyjmowanie samego sluga jest więc decyzją naszego mechanizmu dopasowującego, a jego wykrywanie wymaga surowego pasa wyszukiwania po tekście komentarza, a nie indeksu wzmianek GitHuba. Koszt jest nazwany wprost, a nie wygładzony: człowiek, który ma taki sam slug jak aplikacja, zwraca się do bota każdą krótką wzmianką o samym sobie. Wyróżniające się nazwy aplikacji czynią tę kolizję hipotetyczną.

  • Brak automatycznej publikacji. Ustalenia trafiają do przestrzeni recenzji; publikacja na GitHubie to osobne działanie człowieka
  • Brak przybliżonej tożsamości. Autor rozwiązuje się na dokładnie jednego członka albo zostaje odrzucony — nie ma przypisania opartego na zgadywaniu
  • Brak webhooka aplikacji GitHub. Ta powierzchnia nigdy go nie rejestruje, więc nie ma przychodzącego adresu URL, który trzeba by wystawiać na potrzeby komentarzy w PR. Pozostałe webhooki produktu (potoki, synchronizacja zgłoszeń) to osobna, opcjonalna konfiguracja.