Czy AI ma prawo odezwać się na PR-ze
Jest 15 czerwca. W kwietniu zeszłego roku przez dwa tygodnie prowadziłem notes z sugestiami Copilota w dwóch projektach testowych. Wyszło 41 wieloliniowych sugestii: 12 przyjętych bez zmian, 22 poprawione przed commitem i 7 odrzuconych po przeczytaniu. Zapisałem wtedy zdanie, które dziś czytam jak datę ważności: tyle wynosiło całe moje “AI review”, nie bot komentujący diff na GitHubie, tylko dyscyplina przy przyjmowaniu podpowiedzi. Taka recenzja odbywa się w buforze, zanim cokolwiek trafi do commita, i widzę ją wyłącznie ja.
Tamten wpis kończył się obietnicą, że rzeczy zapowiedziane 22 marca 2023 opiszę na własnym stacku i z własnymi liczbami, kiedy dostanę do nich dostęp. Podsumowania pull requestów do mnie nie przyszły, bo trafiły do planu, którego nie mam, i wracam do tego w następnej sekcji. Przyszło coś, czego w tamtym ogłoszeniu nie było: boty, które czytają diff z poziomu workflow i zostawiają komentarz pod pull requestem. Na nich mam dziś własny materiał: jeden syntetyczny pull request, cztery uwagi bota i moją decyzję przy każdej z nich.
Pytanie zmieniło przez to adres. Rok temu brzmiało: czy przyjąć szary tekst przed kursorem. Dziś brzmi: czy model ma prawo odezwać się na pull requeście, zanim kliknę merge, a jeśli tak, to w jakiej roli. Role są trzy i od ich rozróżnienia zależy cały ten wpis. Głos to komentarz albo etykieta, które ktoś przeczyta. Weto to wymagany status, który przy czerwonym wyniku blokuje merge. Podpis to zatwierdzenie, które liczy się do wymaganych recenzji.
Moja teza na czerwiec 2024 jest wąska i będę jej bronił do końca. “AI review” w moim QA to job albo karta na PR: podsumowanie z Copilot Enterprise albo bot typu CodeRabbit czy PR-Agent, przy czym PR-Agent chodzi wprost jako job w Actions. To nie jest ghost text z kwietnia 2023, bo komentarz leży na pull requeście i widzi go cały zespół, a nie tylko osoba z otwartym buforem. Model komentuje diff i dostaje głos. Nie dostaje weta ani podpisu. Wymaganym recenzentem i jedynym, kto klika merge, zostaje człowiek.
Stan warsztatu, żeby za rok było wiadomo, o czym mówię. Runner to @playwright/test w wersji 1.44.1 z 23 maja, czyli łatka na 1.44.0 z 6 maja, zamykająca cztery regresje. Obok speców w TypeScripcie trzymam w repozytorium z przykładami do bloga projekt testów API w C# na NUnit. Copilota opłacam w subskrypcji indywidualnej za 10 dolarów miesięcznie, tej samej od czerwca 2022, a czat mam w stabilnym VS Code od 29 grudnia, kiedy wszedł w ogólną dostępność. W maju zeszłego roku ten sam czat wymagał Insidersa, rozszerzenia Nightly i miejsca na waitliście.
Reszta tła mieści się w kilku zdaniach. Copilot Enterprise jest w ogólnej dostępności od 27 lutego i nie ma go na moim koncie. Code scanning autofix jest od 20 marca w publicznej becie. CodeRabbit i PR-Agent działają od lipca zeszłego roku. Copilot Workspace jest od 29 kwietnia w technical preview za waitlistą i do tego wpisu nie wnosi nic, bo jest drogą od zgłoszenia do zmiany, a nie recenzentem pull requestów. Za botem może stać GPT-4o z 13 maja albo Claude 3 z 4 marca, oba przez API i żaden nie jest nowością czerwca. Edytor Cursor nadal nie jest moim codziennym narzędziem, a w tym wpisie i tak stałby po drugiej stronie granicy, bo to kanał w IDE.
Czego tu nie będzie. Nie będzie zdania, że Copilot sam recenzuje pull requesty jako wymagany recenzent, bo takiej funkcji nie mam do włączenia i nie znam jej z żadnego changelogu. Nie będzie autofixa opisanego jako produkt w ogólnej dostępności, bo jest betą. Nie będzie przepisanej checklisty z kwietnia 2023, bo w buforze nadal obowiązuje i nie mam w niej nic do poprawienia. Nie będzie diffu z pull requesta klienta ani logu z firmowego pipeline’u. Będzie syntetyczny workflow pr-agent.yml, syntetyczny pull request ze specem Playwrighta i testem NUnit, wycinek z komentarzy bota, jedna przyjęta uwaga i trzy skreślenia.
Co jest na github.com bez bota trzeciego
Zacznę od tego, co GitHub daje sam, bez instalowania czegokolwiek obok, bo tu pomyłek w rozmowach jest najwięcej.
27 lutego Copilot Enterprise wszedł w ogólną dostępność z trzema funkcjami: czatem na github.com, bazami wiedzy i podsumowaniami pull requestów. Kosztuje 39 dolarów za użytkownika miesięcznie i jest planem dla organizacji na GitHub Enterprise Cloud. Moja subskrypcja za 10 dolarów nie zawiera żadnej z tych trzech rzeczy. Zdanie “Copilot recenzuje mi PR-y” skleja więc dwa cenniki w jeden i nie jest prawdziwe w żadnym z nich, bo także w Enterprise żadna z tych funkcji nie jest recenzentem.
Changelog z 27 lutego mówi to zresztą wprost, tylko trzeba go przeczytać do końca zdania. Punkt o pull requestach obiecuje szybszą recenzję: podsumowanie, które od 27 lutego jest bardziej uporządkowane, z częścią “Summary” z ogólnym obrazem i częścią “Outline”, która przechodzi przez kod, oraz czat, który wyjaśnia diff. Cel jest nazwany jako pomoc dla recenzenta, żeby szybciej wszedł w temat i miał więcej czasu na własne uwagi. To jest opis narzędzia dla recenzenta, nie recenzenta.
Te dwie funkcje różnią się kanałem i to jest dla mnie ważniejsze niż ich jakość. Podsumowanie generuje się na żądanie z poziomu pola opisu i ląduje w opisie pull requesta, gdzie autor może je poprawić albo wyrzucić. To jest karta na PR-ze z mojej tezy: tekst, który widzi każdy, kto otworzy pull request. Czat o diffie działa inaczej. Ktoś musi go otworzyć i zadać pytanie, a odpowiedź dostaje pytający, nie zespół. Z punktu widzenia procesu to nadal rozmowa jednej osoby, tylko przeniesiona z edytora na stronę.
Ani podsumowanie, ani czat nie mają statusu na liście checków. Nie da się ich wpisać do ochrony gałęzi jako wymaganych, nie ma czego zaczerwienić i nie ma czego zablokować. W lutowym changelogu nie ma recenzenta. Jest autor szkicu opisu i rozmówca na żądanie. Nie traktuję tego jako zarzutu wobec produktu, tylko jako jego dokładny opis, i to ten opis rozstrzyga, gdzie te funkcje mogą stać w moim procesie.
Do takiej decyzji nie potrzebuję dostępu, bo nie zależy ona od jakości tekstu. Rok temu, czekając na Copilot for PRs, zapisałem, że wygenerowany opis pull requesta jest opisem, nie werdyktem: streszczenie odpowiada na pytanie “co się zmieniło”, a review na pytanie “czy to jest bezpieczne i czy testy to złapią”. Podsumowanie z Enterprise czytałbym dokładnie tak, jak spis treści diffu, który oszczędza minutę na orientację i nie zdejmuje ze mnie ani jednego pliku do przeczytania. Ryzyko też zostaje to samo, które opisałem wtedy: gładkie streszczenie na górze pull requesta kusi, żeby przeczytać streszczenie zamiast diffu.
Job w Actions: boty, które już są
Drugi kanał jest starszy od Enterprise i nie zależy od planu GitHuba. Pipeline znaczy tu trzy konkretne rzeczy: token, workflow i komentarz pod diffem. Nie okno w VS Code i nie panel na stronie.
CodeRabbit wystartował na Product Hunt 10 lipca 2023 jako usługa SaaS, którą instaluje się na repozytorium i która komentuje pull requesty. CodiumAI ogłosiło PR-Agenta jako projekt open source 24 lipca 2023. PR-Agent chodzi jako GitHub Action w moim własnym workflow i reaguje też na komendy wpisane w komentarzu, takie jak /review i /describe. Różnica między nimi, która mnie interesuje, nie dotyczy jakości komentarza, bo jej nie porównywałem. Dotyczy drogi, którą przebywa diff. W SaaS diff wychodzi do usługi dostawcy. W Actions wychodzi z mojego runnera prosto do API modelu, na moim kluczu. W tym demo używam PR-Agenta z jednego powodu: cały przebieg mieści się w pliku YAML, który mogę pokazać, i w sekrecie, który sam kontroluję.
Ta sama droga jest powodem, dla którego żadnego z tych botów nie instaluję po cichu na repozytorium klienta. Diff klienta wysłany do cudzego API to decyzja tego samego rodzaju co sekret wklejony do okna czatu, a w notatce o czacie z maja 2023 zapisałem, że takiej decyzji nie podejmuje się po cichu. Najpierw rozmowa i zgoda, potem workflow.
Syntetyczny job, bez prawdziwego tokena i bez nazwy organizacji, wygląda u mnie tak:
# .github/workflows/pr-agent.yml
name: pr-agent
on:
pull_request:
types: [opened, reopened, ready_for_review]
issue_comment:
jobs:
pr-agent:
if: ${{ github.event.sender.type != 'Bot' }}
runs-on: ubuntu-22.04
permissions:
issues: write
pull-requests: write
contents: read
steps:
# tag przypina jednolinijkowy Dockerfile, nie kod bota
- uses: Codium-ai/pr-agent@v0.22
env:
OPENAI_KEY: ${{ secrets.OPENAI_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}Szkielet pochodzi z dokumentacji PR-Agenta. Triggery i warunek na nadawcę zostawiłem bez zmian. Job startuje na nowym, ponownie otwartym albo oznaczonym jako gotowy do recenzji pull requeście oraz na każdym komentarzu, w którym może być komenda, a warunek na nadawcę pilnuje, żeby bot nie odpowiadał sam sobie. Zmieniłem trzy rzeczy. Po pierwsze uprawnienia: dokumentacja daje akcji contents: write, ja daję read, bo ten job ma komentować, a nie commitować, a wariant z GitHub App w tej samej dokumentacji prosi o dostęp do treści repozytorium tylko do odczytu. Po drugie runner: zamiast ubuntu-latest wpisałem ubuntu-22.04, z tego samego przyzwyczajenia, z którego przy równoległych testach pisałem, że ubuntu-latest jest aliasem, który kiedyś przesunie się bez mojego udziału. Po trzecie tag zamiast @main, i ta zmiana wymaga osobnego akapitu, bo nie robi tego, co obiecuje.
Najpierw jednak, co bot robi po starcie. Na nowym pull requeście akcja domyślnie uruchamia trzy narzędzia: opis zmiany, recenzję i propozycje poprawek. Narzędzie do opisu dokłada do opisu autora streszczenie i przegląd zmian, zostawia jego tytuł i dorzuca etykietę z typem zmiany. Recenzja w konfiguracji z 13 czerwca ma stałe pola. Szacuje wysiłek recenzji w skali od jednego do pięciu, odpowiada tak albo nie na pytanie, czy pull request dodaje albo aktualizuje odpowiednie testy, ocenia ryzyko bezpieczeństwa i wypisuje kluczowe miejsca do sprawdzenia. Zakłada przy tym etykietę z szacowanym wysiłkiem, a przy uwadze o bezpieczeństwie drugą. Automatyczne zatwierdzanie ma domyślnie wyłączone i tak zostaje. Po kolejnym pushu bot milczy, dopóki nie napiszę w komentarzu /review.
Teraz tag. Pułapkę znalazłem, czytając action.yaml, a nie README. Akcja jest obrazem Dockera budowanym z pliku, który ma jedną linię: FROM codiumai/pr-agent:github_action. To jest ruchomy tag w Docker Hubie. Przypięcie uses: do v0.22 z maja przypina więc ten jednolinijkowy plik, a nie kod, który czyta mój diff. Model też nie jest przypięty po mojej stronie. W configuration.toml z 13 czerwca domyślnie stoi gpt-4-turbo-2024-04-09 i ta wartość zmienia się razem z obrazem, a nie razem z moim repozytorium. Za botem w tym demo stoi klucz OpenAI. Równie dobrze mógłby to być Claude 3 albo GPT-4o wpisany wprost do konfiguracji, i żadna z tych zmian nie ruszyłaby ani jednego zdania w tym wpisie, bo są to zdania o uprawnieniach, a nie o inteligencji.
Z tego wynika rzecz ważniejsza niż sam YAML. Ten job jest niedeterministyczny z natury, bo odpowiada model językowy, i nieprzypięty z konstrukcji, bo kod i domyślny model przychodzą z ruchomego obrazu. We wrześniu 2022 zapisałem, że do koszyka pull requesta wpuszczam tylko to, co jest szybkie i deterministyczne, a wymagany check ma być mały i stabilny. Bot oblewa ten warunek dwa razy, zanim napisze pierwsze zdanie. Dla komentarza mi to nie przeszkadza. Dla bramki dyskwalifikuje.
Autofix to nie review testów
Trzeci kanał też zostawia sugestię na pull requeście i właśnie dlatego trzeba go odgrodzić od dwóch poprzednich.
Od 20 marca code scanning autofix jest w publicznej becie dla klientów GitHub Advanced Security. Kiedy CodeQL zgłasza alert na pull requeście, autofix proponuje poprawkę wygenerowaną z pomocą Copilota, z wyjaśnieniem, a człowiek ją przyjmuje, poprawia albo odrzuca. Komunikat z 20 marca wymienia cztery języki: JavaScript, TypeScript, Javę i Pythona. To jest beta, nie produkt w ogólnej dostępności, i nie będę zgadywał, kiedy to się zmieni.
Miejsce tej funkcji jest jasne i jest nim bezpieczeństwo. To sąsiad listopadowych podstaw testów bezpieczeństwa, a nie recenzent zestawu testów. W listopadzie zapisałem, że injection po stronie mojego stacku zamyka głównie ORM z parametryzowanymi zapytaniami i review kodu. Autofix siedzi w tym samym miejscu procesu: przy alercie z analizy statycznej, jako propozycja łatki do przeczytania. Czytam ją tak samo jak każdy inny diff, z jedną dodatkową ostrożnością. Tu łatwiej o pośpiech, bo propozycja przychodzi z pieczątką narzędzia bezpieczeństwa.
Recenzją testów to natomiast nie jest i tu przebiega granica, którą chcę mieć zapisaną. CodeQL szuka podatności, a nie sensu asercji. Spec Playwrighta z asercją na nagłówek, który widać na każdej stronie, sprawdza niewiele, ale nie jest podatnością i nie wygeneruje alertu, więc autofix nie ma czego poprawiać. Test NUnit logujący się kontem współdzielonym z całym projektem też nie jest podatnością. Beta nie oceni, czy expect(login.error).toHaveText(...) coś sprawdza, bo nikt jej o to nie pyta. To pytanie zadaje recenzent, a w czerwcu 2024 recenzentem jest u mnie człowiek, z botem z poprzedniej sekcji w roli głosu doradczego.
Jak wpinam, żeby nie skłamać gate
Zasada mieści się w dwóch zdaniach. AI dostaje prawo do komentarza i etykiety. Wymagane zostają testy i zatwierdzenie przez człowieka, czyli dokładnie to, co było wymagane, zanim pojawił się bot.
Brzmi jak oczywistość, więc pokażę, dlaczego nią nie jest, na jednym syntetycznym pull requeście z repozytorium z przykładami do bloga. Nie ma w nim ani linii z projektu klienta. Tytuł brzmi “Złe hasło: komunikat w UI i 401 z API”, a zmiany są w trzech plikach. Page object e2e/pages/LoginPage.ts dostaje lokator error oparty na roli alert. Spec e2e/auth/login.spec.ts dostaje scenariusz złego hasła na koncie z fixture’a user, który zakłada je przed testem i usuwa po nim:
test('złe hasło zostawia na formularzu z komunikatem', async ({ page, user }) => {
const login = new LoginPage(page)
await login.open()
await login.signIn(user.email, 'zle-haslo')
await expect(login.error).toHaveText('Nieprawidłowe hasło')
await expect(login.submit).toBeVisible()
})Projekt API dostaje w api-tests/Auth/LoginTests.cs test NUnit na to samo zachowanie piętro niżej:
[Test]
public async Task Login_WithWrongPassword_Returns401()
{
var response = await _api.LoginAsync(TestUsers.Default.Email, "zle-haslo");
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.Unauthorized));
}Bot odpowiedział dwoma komentarzami, recenzją i propozycjami poprawek. Wycinam z nich to, co dotyczy testów, bez tabeli HTML i bez emoji:
PR Reviewer Guide
Estimated effort to review [1-5]: 2
Relevant tests: No
Security concerns: No
Key issues to review:
Possible flakiness: LoginTests.cs logs in with the shared
TestUsers.Default account, so tests running in parallel may
interfere with each other. Consider adding [Retry(3)].
PR Code Suggestions
e2e/auth/login.spec.ts: toHaveText('Nieprawidłowe hasło') couples
the test to UI copy. Use toBeVisible() on login.error to make the
test less brittle.W tym wycinku liczę cztery uwagi, bo akapit o niestabilności zawiera dwie: diagnozę i lekarstwo. Jedną przyjąłem, trzy skreśliłem. Zacznę od przyjętej, bo uczciwość wobec bota też jest częścią recenzji.
Przyjęte: konto współdzielone. Diagnoza jest trafna. TestUsers.Default to jedno konto dla całego projektu API, a w syntetycznej aplikacji złe hasło zmienia stan konta, bo aplikacja liczy nieudane próby. Przy równoległych klasach ten test podbija licznik na koncie, na którym logują się inne testy. W październiku 2021 wspólną bazę nazwałem zabójcą numer trzy i napisałem, że dwa plasterki liczące na to samo konto testowe będą sobie kasować dane pod nogami. Dwie klasy uruchomione równolegle w jednym procesie robią dokładnie to samo. Lokalnie na jednym wątku test przechodzi i runner niczego nie zgłasza. Poprawka to własny użytkownik na test, zakładany w setupie i usuwany po teście, tak jak robi to fixture user w specu obok. Rok temu ten sam wzorzec dopisywałem ręcznie do sugestii Copilota, bo Copilot nie znał mojego sprzątania.
Skreślenie pierwsze: “Relevant tests: No”. Pull request składa się z page objectu i dwóch plików z testami. Bot ma w diffie spec Playwrighta i test NUnit, a na pytanie, czy pull request dodaje odpowiednie testy, odpowiada, że nie. Ten sam bot w opisie zmiany oznaczył przy tym pull request etykietą typu Tests. Nie wiem, skąd wzięła się odpowiedź w recenzji. Podejrzewam, że model potraktował page object jak kod produkcyjny, a specy jak coś obok, ale to zgadywanie i nie sprzedaję go jako diagnozy. Sprawdzenie zajęło pięć sekund, bo wystarczyło spojrzeć na listę zmienionych plików. Groźne jest co innego. To pole wygląda jak fakt, a nie jak opinia, i ma kształt, pod który łatwo podpiąć automat: etykietę “brak testów”, przypomnienie na Slacku albo, w najgorszym wariancie, status. Pole, które myli się na pull requeście złożonym z samych testów, uczy zespół, żeby go nie czytać, a w dniu, w którym będzie miało rację, nikt już na nie nie spojrzy.
Skreślenie drugie: [Retry(3)]. To jest dalszy ciąg przyjętej uwagi i najlepiej pokazuje, czym jest ten kanał. W jednym akapicie bot podał trafną diagnozę i złe lekarstwo. Ponowienie nie usuwa wspólnego stanu, tylko zamienia jedyny sygnał o nim w zielony wynik po drugiej próbie. Ponawianie nie jest izolacją, napisałem przy organizacji testów w xUnit i NUnit, a we wrześniu 2022 dodałem wersję dla bramki: test, który wymaga trzech prób, żeby się w niej zmieścić, po prostu do niej nie należy. Autorowi zmiany, który chce mieć zielony pull request przed końcem dnia, ta sugestia wyda się rozsądna. Dlatego skreśla ją ktoś, kto odpowiada za politykę bramki, a nie ktoś, kto chce zamknąć zadanie.
Skreślenie trzecie: toBeVisible() zamiast toHaveText(). Tę propozycję uważam za najgroźniejszą z trzech, bo jest sformułowana jak dbałość o jakość. “Mniej kruchy test” znaczy tu test, który przejdzie przy każdym komunikacie w kontenerze z rolą alert: przy “Konto zablokowane”, przy “Błąd serwera” i przy każdym innym tekście, który ktoś tam kiedyś wstawi. Kryterium mówi, że złe hasło zostawia użytkownika na formularzu i pokazuje komunikat o treści “Nieprawidłowe hasło”, więc treść jest wymaganiem, a nie ozdobą. Jeżeli ktoś zmieni ten tekst, test ma paść i ktoś ma zdecydować, czy zmiana była celowa. W kwietniowym notesie sprzed roku najczęstszym powodem poprawki albo odrzucenia była asercja zbyt szeroka albo zawsze prawdziwa: dziewięć wskazań przy 29 poprawionych i odrzuconych sugestiach. Rok temu podsuwał mi ją ghost text. Dziś podsuwa ją recenzent i robi to w imię stabilności. Pierwsze pytanie z mojej checklisty brzmi “czy ten test może paść”, a bot zaproponował zmianę, po której test będzie padał rzadziej, niż powinien.
Najważniejsza obserwacja z tego pull requesta nie dotyczy treści, tylko koloru. Gdybym przyjął wszystkie trzy skreślone uwagi, pipeline zostałby zielony. [Retry(3)] kompiluje się bez słowa, toBeVisible() przechodzi na obecnej wersji aplikacji, a pole “Relevant tests” nikogo nie blokuje. Rok temu część złych sugestii łapał kompilator albo pierwszy przebieg: atrybut z innej wersji frameworka kompilator odrzucał od razu, a selektor, którego nie ma w aplikacji, wychodził przy pierwszym uruchomieniu. Złe rady recenzenta nie dają czerwonego. Dają zielony zestaw, który sprawdza mniej. Tego nie złapie żaden runner i dlatego zatwierdzenie zostaje przy człowieku, który zna kryterium.
Okablowanie wynika z tych trzech skreśleń wprost. W repozytorium z przykładami jestem sam, więc recenzentem, którego nie da się pominąć, i jedynym, kto merguje, jestem ja. Wymaganego zatwierdzenia tam nie ustawiam, bo GitHub nie pozwala autorowi zatwierdzić własnego pull requesta. W repozytorium zespołu ta sama zasada ma postać czterech ustawień:
- Ochrona
mainwymaga pull requesta i jednego zatwierdzenia przez człowieka, a nowy commit unieważnia wcześniejsze zatwierdzenie. - Wymagane statusy to joby z testami, czyli to, co we wrześniu 2022 nazwałem bramką pull requesta. Joba
pr-agentna tej liście nie ma. - W ustawieniach Actions zostaje wyłączona opcja “Allow GitHub Actions to create and approve pull requests”. GitHub dodał ją w 2022 roku właśnie po to, żeby przez Actions nie dało się wprowadzić do chronionej gałęzi zmiany, której nie przejrzała inna osoba.
- Etykiety bota są informacją. Nie słucha ich żadna automatyzacja, ani auto-merge, ani przydzielanie recenzentów.
Jeden efekt uboczny tego układu traktuję jako argument, a nie koszt. Kiedy API modelu ma gorszy dzień albo na kluczu skończy się limit, job pr-agent świeci na czerwono i nikt nie czeka. Rok temu napisałem, że podsumowanie wpięte jako required check dałoby mi pierwszą awarię pipeline’u w dniu, w którym cudze API ma zły dzień. Ten scenariusz wyłącza się jedną decyzją i jest to decyzja z listy powyżej.
Do tego jeden nawyk, który nie jest ustawieniem. W wątku pull requesta odpisuję jedną linią na każdą uwagę bota: przyjęte z commitem albo skreślone z powodem. Tutaj wyszła jedna linia “przyjęte” i trzy “skreślone”. Kosztuje to minutę, a następny recenzent nie musi zgadywać, czy ktoś ten komentarz w ogóle przeczytał.
Na koniec tej sekcji wracam do podsumowania 2023. W grudniu napisałem, że w moim CI nie ma joba “LLM”, i spisałem cztery warunki, po których poznaję, że narzędzie weszło do zespołu, a nie do hype’u: nazwane zadanie, miejsce w procesie, wiersz w pipelinie albo świadomy powód, dla którego go nie ma, i człowiek, który odpowiada za wynik. Bot z tego wpisu jest pierwszym modelem, który w repozytorium z przykładami dostał własny job. Ma nazwane zadanie, bo komentuje diff i szkicuje opis. Ma miejsce w procesie, przed recenzją człowieka, a nie zamiast niej. Ma wiersz w pipelinie, bez prawa do bramki. Ma właściciela, bo każdą jego uwagę ktoś przyjmuje albo skreśla, podpisując się pod tym w wątku. Cztery na cztery, pod warunkiem że trzeci punkt czyta się dokładnie: wiersz w pipelinie to nie to samo co miejsce na liście wymaganych checków.
Podsumowanie
Review w CI to w czerwcu 2024 nowy kanał, a nie nowy recenzent. Komentarz modelu leży tam, gdzie widzi go zespół, czyli na pull requeście, a nie w buforze jednej osoby. Ownership merge’a zostaje ludzki. Copilot Workspace, w technical preview od 29 kwietnia, nie jest recenzentem pull requestów i w tym obrazku niczego nie zmienia.
Trzy zdania, które chcę móc przeczytać za rok. Copilot Enterprise od 27 lutego daje podsumowanie pull requesta i czat o diffie, oba na żądanie, oba bez statusu na liście checków i oba poza moją subskrypcją za 10 dolarów. PR-Agent w Actions, przypięty tagiem v0.22, który przypina jednolinijkowy Dockerfile, a nie kod bota, zostawił na syntetycznym pull requeście cztery uwagi, z których przyjąłem jedną, a skreśliłem trzy: “Relevant tests: No”, [Retry(3)] i toBeVisible(), przy czym każda ze skreślonych zostawiłaby pipeline zielony. Code scanning autofix jest betą CodeQL od 20 marca, siedzi w bezpieczeństwie i nie recenzuje testów.
Czego z tego nie wynika. Nie wynika, że nigdy nie zrobię z bota wymaganego statusu, bo wąska, przypięta i powtarzalna reguła może kiedyś na to zasłużyć; zatwierdzenie i merge zostają przy człowieku niezależnie od tego. Nie wynika, że wracam do samego Tab, bo checklista z kwietnia 2023 nadal działa w buforze, a bot na pull requeście jest drugim kanałem, nie zamiennikiem pierwszego. Nie wynika też, że Copilot recenzuje pull requesty jako osobny produkt, bo takiej funkcji nie mam do włączenia.
W grudniu chciałem, żeby odpowiedź na pytanie “gdzie w tym procesie jest AI” nadal dała się powiedzieć w jednym zdaniu i żeby to zdanie zawierało czasownik “recenzuję”. W czerwcu brzmi ono tak: model komentuje diff w osobnym, niewymaganym jobie, a ja recenzuję diff razem z jego komentarzem i sam klikam merge.
Warunek, po którym poznam, że temat dojrzał, formułuję tak. Bot może dostać wymagany status w dniu, w którym jego kod i model są przypięte do wersji, dwa przebiegi na tym samym pull requeście dają te same uwagi, nie twierdzi, że brakuje testów, kiedy spec leży w diffie, i ani razu nie proponuje ponowienia albo osłabienia asercji jako sposobu na stabilność. Nawet wtedy dostanie weto, a nie podpis. Do tego czasu jego komentarz jest głosem doradczym, a merge podpisuję ja.

