DSH-плагин: состояние CI Forgejo в Web GUI + tool forgejo_ci_status/forgejo_ci_wait
  • JavaScript 100%
Find a file
ai agent fd8ba74ffa fix(0.8.3): синяя точка и кольцо «идёт» — business-blue токен вместо brand-primary
--dsw-alias-brand-primary в этой платформе чернильный (near-black): в тёмной
теме он давал белую точку. Shipped-компоненты для акцента используют
--dsw-alias-brand-primary-new-colorprimary-new-color (с fallback #4d6bfe);
тот же токен теперь у точки и кольца активного прогона.

node --test: exit=0.
2026-10-28 14:48:41 +03:00
lib feat(0.8.0): «в очереди» для waiting-прогона и общий backlog раннера 2026-10-28 12:23:15 +03:00
locale feat(0.2.0): форма входа — кнопка в шапке + popover + страница 2026-10-28 10:38:37 +03:00
test fix(0.8.2): счётчик задач только у активных прогонов 2026-10-28 12:29:44 +03:00
.gitignore feat(phase-1-2): каркас пакета + чистая логика и тесты 2026-10-28 10:02:14 +03:00
client.js fix(0.8.3): синяя точка и кольцо «идёт» — business-blue токен вместо brand-primary 2026-10-28 14:48:41 +03:00
cordis.patch.yml feat(phase-1-2): каркас пакета + чистая логика и тесты 2026-10-28 10:02:14 +03:00
icon.svg feat(phase-1-2): каркас пакета + чистая логика и тесты 2026-10-28 10:02:14 +03:00
index.js feat(0.8.0): «в очереди» для waiting-прогона и общий backlog раннера 2026-10-28 12:23:15 +03:00
package.json fix(0.8.3): синяя точка и кольцо «идёт» — business-blue токен вместо brand-primary 2026-10-28 14:48:41 +03:00
PROVENANCE.md feat(phase-1-2): каркас пакета + чистая логика и тесты 2026-10-28 10:02:14 +03:00
README.md feat(0.8.0): «в очереди» для waiting-прогона и общий backlog раннера 2026-10-28 12:23:15 +03:00

dsh-forgejo-ci

Плагин DSH: состояние CI Forgejo в Web GUI и два tool'а для агента вместо ручных watcher'ов.

  • кнопка CI в правой части шапки сессии (рядом с прочими утилитами сессии; на экране без открытой сессии её нет — слот принадлежит сессии) с индикатором: красная точка — последний прогон с исходом (success/failure) упал (отменённые прогоны исходом не считаются); синяя точка и пульс — прогон идёт; падение главнее. Клик открывает popover с коротким списком (5 прогонов) и статусом раннера; из popover — «открыть полностью» на страницу в центральной панели, где показана вся доступная история (до historyLimit) в списке с прокруткой.
  • forgejo_ci_status — снимок состояния из кеша (без сетевого вызова);
  • forgejo_ci_wait — ожидание завершения прогона с таймаутом;
  • toast о завершении прогона.

Плагин только читает Forgejo: ни одной операции записи, workflow не запускает.

Конфигурация

Поле По умолчанию Смысл
baseUrl https://git.sm-karaoke.ru адрес Forgejo
repo svoemesto/Karaoke репозиторий owner/name
tokenRef FORGEJO_CI_TOKEN имя ссылки на секрет в хранилище секретов DSH; значение сюда не пишется
pollMs 15000 интервал опроса Forgejo, ≥ 5000
runsLimit 5 витрина: сколько прогонов показывают панель, popover и tool по умолчанию, 1..20
historyLimit 20 память: сколько прогонов держать в снимке, 5..100, не меньше runsLimit
staleAfterMs 45000 после какого молчания данные считаются устаревшими
queueStuckAfterMs 600000 когда «очередь стоит» (нет активности при ждущих прогонах)
routePath /forgejo-ci/state маршрут снимка для браузера

Порядок строк: активные прогоны → завершившиеся с исходом (success/failure) → отменённые; внутри группы — свежие сверху. Сортировка делается на host-половине один раз, поэтому popover, страница и ответ инструмента показывают один и тот же порядок, а серия отменённых прогонов не вытесняет из витрины полезные строки.

Два числа вместо одного: память шире витрины, потому что индикатор на кнопке считается по всей истории — иначе серия отменённых прогонов вытесняет единственный реальный исход из окна и красная точка гаснет, хотя CI красный.

Токен нужен только на чтение репозитория (read:repository). Он живёт в ~/.dsh/.credentials.yaml:

refs:
  FORGEJO_CI_TOKEN: <токен>

Как установить

# 1) поставить бандл из локального клона (профиль DSH)
plugin_manager install_bundle <абсолютный путь к этому каталогу>
# 2) перезагрузить страницу Web GUI

Частота обновления панели — 15 секунд (фиксированная, чтение кеша); параметр pollMs управляет опросом Forgejo на host-половине.

Что значит каждое число

  • «9 из 27» в строке прогона — задачи этого прогона: 9 уже выполняются или завершены из 27 джобов, объявленных в .forgejo/workflows/lint.yml. У завершённого прогона «в работе» всегда 0: Forgejo оставляет у таких прогонов мусорные строки задач со статусом running, и они не считаются. Числитель — done + running (в API случаются повторы по attempt, поэтому он никогда не больше знаменателя). Если файл workflow недоступен, знаменателя нет и строка показывает «9 задач».
  • «в очереди» вместо счётчика — у прогона статус waiting, а задач по нему ещё нет: Forgejo не создал строки actions/tasks. Это не поломка и не ноль, а ожидание свободного раннера.
  • «очередь CI: 34 ждут / 19 идут» на строке раннера — общий backlog из actions/runners/jobs, по всем прогонам сразу. Оговорка: часть статусов может быть устаревшей — Forgejo не всегда обновляет состояние задач завершённых прогонов, поэтому цифра показывает загруженность очереди, а не «этот прогон сейчас бежит».
  • «≈7 мин» — оценка остатка, только когда есть основа: медиана длительностей двух и более завершённых прогонов (history) или прогресс по задачам, когда завершено ≥3 и прошло ≥60 с (progress). Нет основы — нет и времени.
  • Красная точка — последний прогон с исходом (success/failure) упал; отменённые прогоны исходом не считаются.
  • Синяя точка и пульс — прогон идёт сейчас. Пульс не горит при падении и при простое: он означает только «исполняется».
  • Порядок строк — активные → с исходом → отменённые; внутри группы свежие сверху.

Обновление после правок

  • правка клиента (client.js) → перезагрузка страницы;
  • правка host-кода (index.js, lib/) → plugin_manager set_bundle off/on (или перезапуск процесса): HMR на этом пакете не срабатывает, маршрут продолжает отдавать старую версию до переключения бандла.

Проверка

cd <этот каталог> && node --test          # юнит-тесты чистой логики
curl -s http://127.0.0.1:3080/forgejo-ci/state | head -c 400

Известные ограничения

  • После перезапуска DSH история прогонов пуста: кольцевой буфер живёт в памяти процесса, а Forgejo хранит историю недолго (наблюдалось схлопывание четырёх прогонов до одного за 40 минут). Панель показывает столько строк, сколько успел увидеть текущий процесс, и честно помечает прогоны, которых Forgejo больше не отдаёт.
  • Разбивки «прогон → его джобы» нет: API Forgejo 15 не отдаёт джобы произвольного прогона; строка «сейчас бегут» описывает только последний прогон и только пока он активен.
  • waiting у прогона не значит «ничего не происходит»: статус прогона отстаёт; состояние раннера вычисляется по свежести активности.
  • После включения или выключения бандла нужна перезагрузка страницы: host снимается сразу (маршрут /forgejo-ci/state → 404, tool'ы исчезают), а браузерная половина живёт в уже загруженном бандле — до перезагрузки иконки, панели и уведомлений нет, и уведомления не приходят: опрос делает браузерный модуль.
  • Ручной запуск workflow недоступен — плагин read-only.
  • Джоб-логи и артефакты не показываются: API их не отдаёт.
  • Если очередь задач недоступна (actions/tasks ответил ошибкой), строка «сейчас бегут» не показывается, но прогоны и статус раннера остаются свежими: снимок не помечается устаревшим из-за одного эндпоинта.
  • Если Forgejo не отдал created/updated, плагин подставляет время наблюдения — возраст такой строки считается от первого опроса.

Лицензия

MIT.