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.
| Pole | Pytanie, na które odpowiada później | Dlaczego 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ę.
| Etykieta | Wartości | Kto ją czyta |
|---|---|---|
| Rodzaj | feature-request, bug | Kto decyduje, do której kolejki trafia |
| Priorytet | priority:low, priority:medium, priority:high | Kto planuje następny cykl |
| Źródło | from-widget, from-form, from-support | Kto 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.