YouGile и GitHub: yogile_connector

Для разработчиков. Состояние на 28.09.2026. Переменные и все ручки — README репозитория 
Buharestskie/yogile_connector.
Коротко
yogile_connector связывает задачи YouGile с ветками GitHub и двигает задачу по доске вслед за кодом: ветки нет — задача ждёт ветку; ветка появилась — задача в работе; ветка слита в основную — задача закрыта; после слияния пришли новые коммиты — задача снова в работе. Внутри YouGile скрипт-витрина показывает состояние бейджем на карточке и блоком «GitHub» в открытой задаче. Сервис доступен по адресу 
https://dev-tasks.donula26.ru, настройки — в админ-панели 
/admin.
Как задача находит свои ветки
По ID задачи в имени ветки. Номер задачи из YouGile плюс префикс проекта дают ID вида 
PRI-18. Любая ветка, в имени которой есть этот токен (
feat/PRI-18-cart, 
pri_18), считается веткой задачи — в каком бы репозитории организации она ни появилась.
Веток может быть несколько, по одной в разных репозиториях. Каждая ведётся отдельно, общее состояние собирается из них: пока не слита хоть одна — задача в работе, слиты все — закрыта.
«Слито» — у ветки нет коммитов вне основной (
compare, 
ahead_by == 0), и при этом собственные коммиты на ней хоть раз были. Основная ветка у каждого репозитория своя: у части проектов это 
dev, а не 
main.
Стикер «Репозиторий» на задаче выбирает один репозиторий — тот, где ветка создаётся автоматически. Задачи без стикера и без привязанных репозиториев сервис не двигает (состояние «репозиторий не выбран»). Стикер сервис заводит и поддерживает сам: вешает на включённые доски, дописывает новые репозитории организации, убирает исчезнувшие.
Что сервис делает сам
Событие
Что происходит
Задачу перенесли в рабочую колонку
Создаётся ветка в репозитории из стикера (если на доске включено автосоздание)
Для задачи появилась ветка
Задача переезжает в рабочую колонку
Все ветки слиты
Задача уезжает в «Готово» и отмечается выполненной
После слияния пришли новые коммиты
Задача возвращается в работу
Задача ушла из рабочей колонки
Пустая ветка (без своих коммитов) удаляется — кроме колонок, где ветки велено сохранять
Задача закрыта
Слитая ветка удаляется. Неслитая не удаляется никогда — в чат задачи один раз приходит сообщение с её именем и числом неслитых коммитов
Автосоздание ветки на доске по умолчанию выключено, удаление пустых и слитых веток — включено; всё это переключается по доскам в админ-панели. Каждый переход пишется в чат задачи, если задан 
YOUGILE_BOT_USER_ID. Цвет карточки меняется под состояние: серый — нет репозитория или ветки, зелёный — слито.
Откуда события
GitHub → 
POST /webhooks/github: события 
push, 
create, 
delete, 
pull_request. Подпись проверяется по 
GITHUB_WEBHOOK_SECRET, повторные доставки отбрасываются. Push в основную ветку пересчитывает все задачи досок этого репозитория.
YouGile → 
POST /webhooks/yougile: события 
task-created и 
task-moved.
Плановая сверка всей доски раз в 
RECONCILE_INTERVAL_MINUTES (по умолчанию 15) — страховка на случай потерянного вебхука.
Витрина (
yougile-script/github-widget.js) раз в 30 секунд читает 
GET /api/board/state и ничего не решает сама. Ответ кешируется на 30 секунд.
Админ-панель
Настройки живут в базе (SQLite в 
./data по умолчанию) и правятся на 
/admin: репозиторий и ключи по умолчанию, параметры YouGile, таблица досок — какие синхронизировать, какой репозиторий у каждой, какие колонки рабочая и завершающая, создавать ли ветку автоматически. При первом запуске значения переносятся из окружения, дальше окружение нужно только для базы и токенов входа. Кнопки панели ходят в 
/admin/api/* с заголовком 
X-Admin-Token:
Ручка
Что делает
POST /admin/api/reconcile
Полная сверка досок
POST /admin/api/webhooks/yougile
Создать подписки YouGile, тело 
{"public_url": "https://dev-tasks.donula26.ru"}
POST /admin/api/webhooks/github
Завести вебхук сервиса во всех репозиториях (или в переданном списке 
repos)
POST /admin/api/reload
Перечитать настройки и структуру досок
GET /admin/api/status
Сводка состояния
Проверка живости — 
GET /healthz, отвечает 
{"status":"ok"}.
Где код и как выкатывается
Репозиторий 
Buharestskie/yogile_connector: FastAPI, SQLAlchemy, httpx. Локально — 
uvicorn app.main:app --reload --port 8000 с заполненным 
.env. Вебхуки на ноутбук не придут — пересчёт вызывайте через 
POST /admin/api/reconcile.
На сервере — git-клон: 
git pull, затем 
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build. Прод-файл — надстройка: убирает публикацию порта и подключает контейнер к сети внешнего прокси. Собранный без неё контейнер опубликует порт наружу и потеряет прокси.
У сервиса есть внешняя проба «Связь с YouGile» (на статус-странице скрыта) — выкатка в окне обслуживания.
Витрина ставится внутри YouGile отдельно: конфигуратор скриптов (
Ctrl + ~, только у администратора компании) → «добавить скрипт». Проще всего взять готовый текст с 
/widget/script.js?token=… — адрес сервиса и токен в нём уже подставлены.
На что наступают
Кириллица в скрипте YouGile ломается при передаче в песочницу: регулярка с 
[а-яё] валит скрипт целиком, строки превращаются в мусор. Код витрины пишется только латиницей, все русские подписи отдаёт сервис вместе с состоянием.
Витрина работает в песочнице без 
window и не видит ID задачи вида 
PRI-18 — поэтому сопоставлением занимается сервис.
App.httpGet из API конфигуратора не годится для GitHub: нет 
User-Agent, GitHub отвечает 
403. Работает обычный 
fetch. 
UI.safeHtml вырезает SVG — плашки рисуются через 
UI.rawHtml с ручным экранированием.
Стикер к доске привязывается только своим. Если отправить в 
PUT /boards/{id} весь набор стикеров, YouGile отвергнет запрос из-за текстовых стикеров.
Первое появление задачи ничего не двигает — сервис только запоминает состояние. Переходы работают со второго наблюдения, иначе первый запуск перетасовал бы всю доску.
Токену GitHub нужна запись. Для создания и удаления веток — 
Contents: Read and write; с токеном только на чтение GitHub отвечает 
403, сервис пишет об этом в чат задачи. Без токена лимит — 60 запросов в час, полная сверка съедает его быстро.
События на одну задачу приходят пачкой (
create и 
push почти одновременно), поэтому обработка задачи идёт под мьютексом. Не убирайте его — задача получала по три одинаковых сообщения.
Зеркальную колонку нельзя делать рабочей: задача туда переезжает, но пропадает из виду своей доски.
Задача, унесённая на ненастроенную доску, больше не двигается, но её состояние в базе остаётся.
YouGile периодически отвечает 
502/
503. Событие, упавшее на такой ошибке, доделает плановая сверка — не выключайте её (
RECONCILE_INTERVAL_MINUTES=0).