Pętla feedbacku

Szablon prośby o funkcję, który staje się changelogiem

5 min czytania

Szablon prośby o funkcję to formularz z czterema pytaniami: co osoba próbuje zrobić, co ją powstrzymuje, co próbowała zamiast tego, i jak chce zostać poinformowana, gdy będzie gotowe. Wszystko inne, co zwykle pojawia się na jednym, selektory priorytetu, szacunki wysiłku, punktacje wartości biznesowej, jest dla zespołu odbierającego prośbę, i jest wypełniane błędnie przez osobę wysyłającą.

Uporządkowane prośby to zły test dla szablonu. Właściwy: sześć miesięcy później, gdy funkcja zostaje wydana, czy ktoś może znaleźć prośbę, zrozumieć ją, i poinformować osobę, która ją napisała? Większość szablonów jest zaprojektowana pod przyjmowanie. Ten jest zaprojektowany pod dzień, w którym pętla się zamyka.

Co powinien zawierać szablon prośby o funkcję?

Powinien zawierać cel, blokadę, obejście, i drogę powrotną do proszącej osoby. Cztery pola, w tej kolejności, każde odpowiada na pytanie, które zespół zada później.

PolePytanie, na które odpowiada późniejDlaczego jest w formularzu
Co próbujesz zrobić?Czy zbudowana funkcja była tą potrzebną?Cel przetrwa każdą konkretną propozycję
Co cię dziś powstrzymuje?Jak wygląda “gotowe”?Nazywa lukę bez narzucania poprawki
Co robisz zamiast tego?Jak pilne jest to naprawdę?Bolesne obejście to silniejszy sygnał niż selektor priorytetu
Jak powinniśmy cię poinformować?Kto dostaje wiadomość “wydane”?Pole, które najczęściej pomijają szablony

To, co jest celowo pominięte: proponowane rozwiązanie jako pole obowiązkowe (mile widziane jako komentarz, błędne jako ramowanie), selektor priorytetu (każda osoba zgłaszająca wybiera wysoki), i jakikolwiek szacunek wysiłku lub wartości (zadanie zespołu, po triażu). Szablon proszący o rozwiązanie dostaje prośby o przyciski; szablon proszący o cel dostaje prośby o rezultaty, a o rezultatach pisze się wpis changelogu.

Szablon

To szablon issue GitHuba, którego używamy, jako formularz. Wklejcie go do .github/ISSUE_TEMPLATE/feature_request.yml, a wyrenderuje się jako strukturalny formularz na stronie nowego issue. Prośby zgłoszone przez niego lądują jako issue z tymi samymi polami co te zgłoszone z widgetu feedbacku, co ma znaczenie dla następnej sekcji.

name: Feature request
description: What you are trying to do, and what stops you.
labels: ["feature-request"]
body:
  - type: textarea
    id: goal
    attributes:
      label: What are you trying to do?
      description: >-
        The outcome, not the button. "Export a month of invoices as one
        PDF" beats "add a PDF export".
    validations:
      required: true
  - type: textarea
    id: blocker
    attributes:
      label: What stops you today?
      description: >-
        Where the product runs out. An error, a missing option, a limit.
    validations:
      required: true
  - type: textarea
    id: workaround
    attributes:
      label: What do you do instead?
      description: >-
        The spreadsheet, the script, the manual step. "Nothing, I gave
        up" is a valid answer.
  - type: input
    id: contact
    attributes:
      label: How should we tell you when it ships?
      description: >-
        An email address, or leave blank to be notified only on this
        issue.

Dwa szczegóły wykonują pracę. labels: ["feature-request"] oznacza, że prośba jest klasyfikowana przy tworzeniu zamiast czekania, aż ktoś ją triaguje. A ostatnie pole istnieje, ponieważ “damy ci znać” to obietnica, a obietnica potrzebuje adresu.

Jakie etykiety powinna nieść prośba o funkcję?

Prośba o funkcję powinna nieść jedną etykietę na to, czym jest, jedną na to, jak pilna jest, i jedną na to, skąd pochodzi. Trzy etykiety, trzy osie, i każda jest czytana przez inną czytelniczkę.

EtykietaWartościKto ją czyta
Rodzajfeature-request, bugKto decyduje, do której kolejki trafia
Priorytetpriority:low, priority:medium, priority:highKto planuje następny cykl
Źródłofrom-widget, from-form, from-supportKto mierzy, skąd pochodzą prośby

Widget stosuje pierwsze dwie osie i from-widget, gdy zgłasza zgłoszenie jako issue; from-form i from-support to propozycje dla próśb, które przychodzą innymi drogami. Etykiety widgetu to rodzaj (bug lub feature-request, decydowany przez klasyfikator wyłącznie na podstawie wiadomości), priorytet (spokojny, konkretny raport awarii jest wysoki; duplikat czegoś, o co już pytano, jest niski; wszystko, co choćby sugeruje problem bezpieczeństwa, to bug i wysoki, niezależnie od sformułowania), i from-widget. Te same trzy osie działają dla próśb, które przychodzą ręcznie przez powyższy szablon, i o to chodzi: prośba to prośba, niezależnie skąd weszła.

Jeszcze jedna konwencja: widget usuwa adres e-mail osoby zgłaszającej z treści issue przed jego zgłoszeniem, ponieważ issue żyje w repozytorium, które może być publiczne, i zastępuje go referencją zgłoszenia. Adres nie trafia do issue; osoba zgłaszająca śledzi wynik w samym widgecie. Zróbcie to samo z polem kontaktowym, jeśli wasz tracker jest widoczny dla ludzi spoza zespołu.

Jak prośba o funkcję staje się wpisem changelogu?

Prośba o funkcję staje się wpisem changelogu, gdy pull request zamyka issue, a wpis przygotowany z tego pull requesta linkuje z powrotem. Mechanizmem są własne słowa kluczowe zamykania GitHuba: PR, którego opis mówi Fixes #142, zamyka issue 142 przy merge’u. Jeśli wasze wpisy changelogu są przygotowywane ze zmergowanych pull requestów, szkic może nieść ze sobą numer issue, a wpis wie, kto pytał.

To powód, dla którego szablon pyta o cel zamiast o rozwiązanie. Gdy wpis jest pisany, cel to zdanie, którego potrzebuje piszący: “Możesz teraz eksportować miesiąc faktur jako jeden PDF” to wpis changelogu. “Dodano eksport PDF” to komunikat commita. Narzędzia do changelogu, które przygotowują wpisy z pull requestów, mogą wykonać zbieranie i link; sformułowanie wciąż potrzebuje osoby, a ta osoba potrzebuje celu.

Co się dzieje, gdy jest wydane?

Proszący jest informowany, z linkiem do wpisu. W naszej konfiguracji dzieje się to automatycznie dla próśb, które przyszły przez widget: komentarz mówiący “Shipped — <tytuł wpisu>” z linkiem do opublikowanego wpisu, zamieszczony na issue, gdy tylko osoba zatwierdzi wpis, a widget pokazuje zgłaszającemu ten sam wpis. Issue założone ręcznie z tego szablonu nie dostaje automatycznego komentarza; tę pętlę zamknijcie sami, według tej samej zasady. Komentarz jest celowo zamieszczany przy zatwierdzeniu, a nie przy merge’u: komentarz mówiący, że coś jest na żywo, zanim tak jest, to złamana obietnica ze znacznikiem czasu. Każda prośba jest powiadamiana co najwyżej raz; drugie zatwierdzenie tego samego wpisu nie produkuje drugiego komentarza.

Jeśli robicie to ręcznie, ta sama zasada obowiązuje. Nie zamykajcie pętli z pull requesta. Zamknijcie ją z opublikowanego wpisu, i zamknijcie raz. Kanał i widget niosą ten sam wpis do wszystkich, którzy nie pytali, czyli większości; komentarz jest dla tych, którzy pytali.

Dlaczego większość szablonów prośby o funkcję zawodzi

Są zaprojektowane, by ułatwić triaż, i to im się udaje, kosztem jedynego momentu, który ma znaczenie dla proszącej osoby. Szablon z dwunastoma polami dostaje mniej próśb, a te, które dostaje, pochodzą od ludzi z cierpliwością do wypełnienia dwunastu pól, co nie jest tą samą populacją co ta, która potrzebuje funkcji. Szablon z czterema polami, z których jedno to “jak się z tobą skontaktować”, dostaje więcej próśb i może uhonorować wszystkie z nich.

FAQ

Czy szablon prośby o funkcję powinien pytać o priorytet? Nie. Pytajcie zamiast tego o obejście. “Eksportuję do arkusza kalkulacyjnego i wpisuję ponownie co piątek” mówi więcej o priorytecie niż rozwijana lista, którą osoba zgłaszająca ustawiła na wysoki.

Czy proszący powinni proponować rozwiązanie? Mogą, w wolnym tekście. Nie czyńcie z tego ramowania. Prośby napisane jako rozwiązania są trudniejsze do łączenia ze sobą i trudniejsze do przekształcenia w wpis changelogu.

Czy prośby o funkcje powinny pojawiać się na publicznej roadmapie? Po zaplanowaniu, tak: etykieta na tym samym issue umieszcza je w kolumnie zaplanowane, a proszący może zobaczyć, jak się porusza. Artykuł publiczna roadmapa to mechanizm.

Jak radzić sobie z duplikatami? Połączcie nową prośbę z istniejącym issue i oznaczcie niskim priorytetem; nie zamykajcie jej. Każdy duplikat to o jedną osobę więcej do poinformowania, gdy zostanie wydane. Przy automatycznym komentarzu Changeloop ta osoba dowie się tylko wtedy, gdy pull request wymienia też jej issue (Fixes #142, fixes #187).

Gdzie powinien żyć szablon? W repozytorium, które przyjmie pull request, żeby słowo kluczowe zamykania działało. Prośba w oddzielnym trackerze musi zostać połączona ręcznie przy merge’u, i to ten krok jest pomijany.


Twierdzenia techniczne w tym artykule nie zostały niezależnie zweryfikowane. Jeśli coś się nie zgadza, daj nam znać, a poprawimy to.

Powiązane w changeloop: Dokumentacja dla deweloperów, Porównanie narzędzi do changeloga

changeloop
Zespół, który tworzy changelog zamykający pętlę. Użytkownicy o coś proszą, Twój zespół to dostarcza, proszący się dowiaduje.