Перейти к основному контенту

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).