Files
bedolaga-cabinet/docs/RUNBOOK.md

9.0 KiB
Raw Blame History

Раннбук: автосинк и деплой кабинета

Как устроено скрытие блока «Дополнительные опции» на странице Подписки и вся автоматика вокруг него: приватный форк, ежедневный синк с апстримом, сборка статики и выкладка на VPS.

Репозиторий: chillpadclub/bedolaga-cabinet (приватный форк BEDOLAGA-DEV/bedolaga-cabinet).

Суть задачи

На странице Подписка нужно было скрыть блок «Дополнительные опции» (докупка устройств, трафика, управление серверами), не потеряв возможность и дальше получать обновления апстрима — проект активно развивается, жить на статичном форке было бы риском самим по себе.

Решение: приватный форк со своим патчем поверх + GitHub Action, который каждый день сам подтягивает апстрим, накатывает патч и собирает готовую статику для VPS.

Патч: как спрятан блок

Файл — src/pages/Subscription.tsx. Условие рендера обёрнуто в false &&, но не правкой существующей строки, а обёрткой снаружи — так, чтобы ни одна оригинальная строка апстрима не менялась, только добавлены две строки до и две после:

{/* Additional Options — disabled on purpose */}
{false && (
  <>
{subscription &&                         // ← строка апстрима не тронута
  (subscription.is_active || subscription.is_limited) &&
  ...
    <div>...</div>
  )}
  </>
)}

Благодаря этому будущий git merge с апстримом конфликтует, только если апстрим правит саму первую или последнюю строку блока — а не любую строку внутри (докупка устройств, трафика и т.д.), которую вы всё равно не используете.

Компоненты DeviceTopupSheet, DeviceReductionSheet, TrafficTopupSheet, ServerManagementSheet остаются в коде и в сборке — просто не рендерятся. Это осознанный выбор в пользу простоты патча, а не баг.

Как работает автоматика

Один workflow — .github/workflows/sync-and-build.yml. Запускается по расписанию (ежедневно, 06:00 UTC) и вручную кнопкой Run workflow.

  1. Merge апстримаgit fetch + merge upstream/main поверх форка.
  2. Чистка CI — удаляет dependabot.yml и чужие workflow, если merge их принёс.
  3. Push в форк — только если merge реально что-то изменил.
  4. Сборкаnpm ci + npm run build:docker (те же build-args, что и в официальном образе).
  5. Релизtar.gz статики → GitHub Release с тегом vX.Y.Z.
  6. Уведомление — сообщение в Telegram: готово или упало.

Если апстрим правит ровно ту же строку, что и патч, — шаг merge падает намеренно. Чужой код не должен домёрживаться в обход человека. Приходит сообщение в Telegram, конфликт разрешается руками локально, затем push — синк продолжается.

Сборка и релиз происходят, только если merge реально что-то поменял (или при ручном запуске) — вхолостую по расписанию ничего не собирается и не публикуется.

Файлы

Путь Назначение
.github/workflows/sync-and-build.yml Весь пайплайн: синк, чистка, сборка, релиз, уведомления
scripts/deploy-cabinet.sh Деплой на VPS: скачивает релиз, бэкапит текущую статику, раскатывает
src/pages/Subscription.tsx Патч — скрытый блок «Дополнительные опции»
docs/RUNBOOK.md Этот файл

Удалено из форка сознательно (было в апстриме, плодило шум):

Файл Почему убран
.github/dependabot.yml Открывал десятки PR на бамп версий — оставили только Dependabot alerts (без авто-PR)
ci.yml, lint.yml Тесты/линт апстрима — код уже проверен в апстриме до мёржа
codeql.yml, security-audit.yml Security-сканы апстрима, дублируют Dependabot alerts
docker.yml Пуш официального образа в GHCR — не нужен, мы публикуем статику
release-please.yml, release.yml Автобамп версии апстрима — версию читаем из package.json

Секреты и токены

Что Где хранится Права
TG_BOT_TOKEN GitHub → Settings → Secrets and variables → Actions Отправка сообщений ботом
TG_CHAT_ID Там же
Fine-grained PAT VPS: ~/.cabinet-deploy-token, права файла 600 Только Contents: Read-only на этот репозиторий

Токен для VPS специально ограничен одним репозиторием и правом только на чтение — даже если файл утечёт, им нельзя ничего запушить или изменить.

Как выкатить на прод

На VPS:

./deploy-cabinet.sh              # последний релиз
./deploy-cabinet.sh v1.63.0      # откат/установка конкретной версии

Скрипт сам:

  1. скачивает cabinet-dist.tar.gz через gh release download;
  2. бэкапит текущую статику в cabinet-dist.bak;
  3. раскатывает новую через rsync -a --delete (чистит устаревшие хэшированные JS-чанки, не трогает 50x.html).

Бэкап один, перезаписывается при каждом запуске. Откатиться на конкретную версию надёжнее через ./deploy-cabinet.sh vX.Y.Z (GitHub хранит все релизы), а не полагаться только на .bak.

Если что-то пошло не так

Пришло Telegram-сообщение «⚠️ упал» — почти всегда конфликт merge с апстримом. Локально:

git fetch upstream main && git merge upstream/main
# разрешить конфликт (скорее всего в месте патча Subscription.tsx)
git add -A && git commit && git push origin main

Следующий прогон workflow снова пойдёт сам.

Деплой на VPS выкатил битую сборку:

rsync -a --delete cabinet-dist.bak/ cabinet-dist/     # мгновенный откат
# либо
./deploy-cabinet.sh vX.Y.Z                             # конкретный рабочий релиз

Security-алерт в GitHub про уязвимость — это Dependabot alerts (без авто-PR). Апстрим обычно фиксит сам, фикс прилетит следующим синком. Если критично и срочно — можно поправить зависимость руками отдельным коммитом.

Что стоит проверять периодически

  • Раз в 12 месяца — вкладка Actions. GitHub отключает scheduled-триггер после ~60 дней без активности в репозитории. Один ручной Run workflow включает обратно.
  • Бэк и фронт бота обновлять вместе. Синк фронта и апдейт бэкенда бота — по-прежнему ручной процесс, специально не автоматизировали дальше деплоя.
  • CHANGELOG апстрима перед выкаткой — на случай breaking changes в API между бэкендом и фронтом.