Зачем: тикнуть чекбокс в критериях приёмки нужно при закрытии каждой задачи, а рецепта в доке не было. Наступили на это при закрытии #37: `tea issues edit --description` требует тело целиком строкой, но взять её неоткуда — вывод `tea issues <номер>` обёрнут и разрисован для терминала. Что: раздел «Правка тела issue — только через API» с рабочим рецептом (забрать сырой JSON, поправить body, вернуть через `-X PATCH -d @файл`) и разбором флагов `tea api`. Оттуда же общее правило: CLI удобен, пока команда создаёт объект или меняет его свойство, и мешает, как только надо изменить уже написанный текст. Ссылка из раздела про автозакрытие и запись в «Что проверено и когда». Проверка: рецепт снят живыми запросами при закрытии #37 — так проставлены чекбоксы тикета и пункт в чек-листе карты #4. `make config-test` зелёный. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
12 KiB
Issue tracker: Gitea
Задачи этого репозитория живут в Gitea на git.dementev.space
(ddmitry/clickstream-data-platform, это remote origin). Все операции —
через CLI tea, официальный клиент Gitea; по
устройству он близок к gh и glab. Логин и репозиторий tea определяет сам
по git remote в текущем каталоге.
Перед первым запуском
- Бинарник. Скачивается с
https://dl.gitea.com/tea/<версия>/(файлtea-<версия>-linux-amd64и.sha256рядом), кладётся в~/.local/bin/tea. Проверка:tea --version. - Вход.
tea logins add --name git.dementev.space --url https://git.dementev.space, токен передаётся переменнойGITEA_SERVER_TOKEN(не аргументом командной строки — он попадёт в историю оболочки). Логин уже добавлен и назначен по умолчанию, так чтоteaработает из любого каталога. - Скоупы токена:
read:user(без негоteaоткажется добавлять логин),write:issue,write:repository. Токен выпускается в UI: Settings → Applications. Нехватка скоупа выглядит не как «нет прав», а как невнятная ошибка или пустой ответ. - Прокси. Домен
dementev.spaceдолжен быть вNO_PROXY, иначе запросы уходят в прокси и виснут. В обычной оболочке это делаетproxy-clientиз~/dotfiles. Если переменная не подхватилась, короткий разовый префикс:NO_PROXY='*' tea ....
Команды
- Создать issue:
tea issues create --title "..." --description "...". Многострочное тело удобнее собрать heredoc'ом в переменную и подставить как--description "$BODY". - Прочитать issue:
tea issues <номер> --comments. - Список:
tea issues list --state open --output json --fields index,title,labels,assignees. Фильтры:--labels,--assignee,--keyword. - Комментарий:
tea comments add <номер> -d "...". - Метки:
tea issues edit <номер> --add-labels "..."/--remove-labels "...". Список меток репозитория —tea labels list, создать новую —tea labels create --name "..." --color "...". - Закрыть:
tea issues close <номер>. Комментария при закрытии команда не принимает — сначалаtea comments add, потомclose. - Взять в работу:
tea issues edit <номер> --add-assignees ddmitry. Сокращения вида@meвteaнет, имя пишется целиком. - Чего нет в CLI — через
tea api <path>: команда ходит в REST API Gitea уже с сохранённым токеном, напримерtea api repos/ddmitry/clickstream-data-platform/issues/18.
Правка тела issue — только через API
Тикнуть чекбокс в критериях приёмки нужно при закрытии каждой задачи, и tea
для этого не годится. tea issues edit --description принимает тело целиком
строкой, а взять эту строку неоткуда: tea issues <номер> печатает текст
обёрнутым и разрисованным для терминала, обратно его не скормишь.
Рабочий путь — забрать сырое тело из API, поправить и вернуть:
# 1. сырой JSON тикета; тело — в поле body
tea api repos/{owner}/{repo}/issues/<n> > issue.json
# 2. правка тела любым удобным способом, например все чекбоксы разом
python3 -c "
import json
d = json.load(open('issue.json'))
json.dump({'body': d['body'].replace('- [ ]', '- [x]')},
open('patch.json', 'w'), ensure_ascii=False)
"
# 3. вернуть
tea api -X PATCH -d @patch.json repos/{owner}/{repo}/issues/<n>
Флаги tea api: -X — метод, -d — сырое тело JSON (@файл читает из файла,
@- из потока ввода), -f и -F — отдельные поля строкой и с типом. Флага
--input нет, хотя рука тянется написать именно его.
Тот же приём — для чек-листа родительской карты: пункт - [ ] #NN тикается
правкой её тела, автоматически Gitea этого не делает.
Отсюда общее правило. tea удобен там, где команда создаёт объект или
меняет его свойство: создать issue, добавить комментарий, повесить метку,
назначить исполнителя, закрыть. Как только нужно изменить уже написанный
текст — тело issue, тело PR, — CLI мешает: он умеет только заменить всё
целиком, а прочитать это «всё» в пригодном для правки виде не даёт. Такие
операции идут прямо в API.
Слияние PR не закрывает issue
Gitea понимает только английские ключевые слова автозакрытия: closes,
fixes, resolves (Closes #13). Русское «Закрывает #13» в теле PR — обычная
ссылка, issue останется открытым. Наступали не раз: последний случай — слияние
PR #17, где issue #13 пришлось закрывать руками.
Отсюда простое правило: пиши в теле PR английское Closes #NN — тогда
слияние закроет задачу само, и ручного шага не остаётся. Всё остальное в PR
по-прежнему на русском: ключевое слово здесь не текст, а команда трекеру.
Если ключевого слова не было, порядок после слияния: закрыть задачу
(tea issues close <номер>) и тикнуть её пункт в чек-листе родительского
issue этапа — Gitea чек-листы сама не обновляет. Чем тикать — выше, в разделе
про правку тела.
Спека — источник истины
- Спецификация фичи — файл в
docs/specs/, версионируется с кодом. - Корневой issue фичи — тонкий: ссылка на спеку + чек-лист дочерних issues
(
- [ ] #NN). Содержание спеки в issue не дублируется — истина одна, в git. - Дочерние issues — полноценные самодостаточные постановки: цель, критерии приёмки чекбоксами, границы («что трогать нельзя»), «сначала прочитать», команды проверки.
- Итоговые резолюции и решения — в спеку или ADR тем же PR; issue — рабочая переписка, она не обязана переживать фичу.
Когда скилл говорит «опубликовать в issue tracker»
Создать issue в Gitea: tea issues create ....
Когда скилл говорит «достать тикет»
tea issues <номер> --comments.
PR как поверхность триажа
Нет — одиночный учебный репозиторий, внешних PR не ждём. (Если включить —
/triage начнёт гонять PR через те же метки и состояния командами
tea pulls ....)
Wayfinding-операции
Используются /wayfinder. Карта — один issue, тикеты — дочерние issues.
-
Карта: issue с меткой
wayfinder:map(Notes / Decisions-so-far / Fog в теле). -
Дочерний тикет: вложенных issues в Gitea нет, поэтому связь держится двумя ссылками — пункт списка
- [ ] #NNв теле карты и строкаPart of #<карта>в начале тела тикета. Метки:wayfinder:<тип>(research/prototype/grilling/task). -
Блокировки: нативные зависимости Gitea — единственный источник истины, текстовых строк
Blocked by:в телах тикетов нет. В CLI их команд нет, работаем черезtea api({owner}и{repo}подставляются из текущего репозитория):- добавить блокер:
tea api repos/{owner}/{repo}/issues/<n>/dependencies -F index=<блокер> -f owner=ddmitry -f repo=clickstream-data-platform— поляownerиrepoобязательны, без них API отвечает «repository does not exist»; - кто блокирует тикет:
GET .../issues/<n>/dependencies; - кого блокирует тикет:
GET .../issues/<n>/blocks; - снять блокировку: тот же путь методом
DELETEс тем же телом.
Тикет разблокирован, когда у всех блокеров
state == "closed". - добавить блокер:
-
Фронтир: открытые дети карты минус заблокированные и назначенные; первый в порядке карты. Блокеры проверяются запросом
dependenciesпо каждому кандидату. -
Взять в работу:
tea issues edit <n> --add-assignees ddmitry— первая запись за сессию. -
Закрыть:
tea comments add <n> -d "<ответ>", затемtea issues close <n>, затем указатель на контекст (суть + ссылка) в Decisions-so-far карты.
Что проверено и когда
2026-08-06: правка тела issue через tea api -X PATCH -d @файл снята живыми
запросами при закрытии #37 — так проставлены чекбоксы самого тикета и пункт
в чек-листе карты #4. Тогда же проверено, что tea issues edit --description
для этого непригоден, а флага --input у tea api нет.
2026-07-31: Gitea 1.27.0 (tea api version), tea 0.15.0. Живыми запросами по
этому репозиторию проверены tea labels list и tea issues list. Остальной
набор команд, флагов и приёмы с tea api перенесены из доки
предшественника — там они снимались с tea <команда> --help установленного
бинарника и проверялись живыми запросами 2026-07-29. При обновлении tea стоит
перечитать --help: набор флагов между версиями менялся.
Архив
- Трекер предшественника — репозиторий
ddmitry/clickstream-ch-kafka-superset-demo. Задачи оттуда сюда не переносились: платформа v2 начата с чистого трекера. - До 2026-07-26 задачи предшественника жили в GitHub Issues
(
dementev-dev/…); аккаунт заблокирован, номера воссозданы в Gitea один в один.