mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 09:33:46 +00:00
153 lines
9.0 KiB
Markdown
153 lines
9.0 KiB
Markdown
# Раннбук: автосинк и деплой кабинета
|
||
|
||
Как устроено скрытие блока «Дополнительные опции» на странице Подписки и вся
|
||
автоматика вокруг него: приватный форк, ежедневный синк с апстримом, сборка
|
||
статики и выкладка на VPS.
|
||
|
||
Репозиторий: `chillpadclub/bedolaga-cabinet` (приватный форк
|
||
`BEDOLAGA-DEV/bedolaga-cabinet`).
|
||
|
||
## Суть задачи
|
||
|
||
На странице `Подписка` нужно было скрыть блок «Дополнительные опции» (докупка
|
||
устройств, трафика, управление серверами), не потеряв возможность и дальше
|
||
получать обновления апстрима — проект активно развивается, жить на статичном
|
||
форке было бы риском самим по себе.
|
||
|
||
Решение: приватный форк со своим патчем поверх + GitHub Action, который каждый
|
||
день сам подтягивает апстрим, накатывает патч и собирает готовую статику для
|
||
VPS.
|
||
|
||
## Патч: как спрятан блок
|
||
|
||
Файл — `src/pages/Subscription.tsx`. Условие рендера обёрнуто в `false &&`, но
|
||
не правкой существующей строки, а **обёрткой снаружи** — так, чтобы ни одна
|
||
оригинальная строка апстрима не менялась, только добавлены две строки до и две
|
||
после:
|
||
|
||
```tsx
|
||
{/* 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:
|
||
|
||
```bash
|
||
./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 с
|
||
апстримом. Локально:
|
||
```bash
|
||
git fetch upstream main && git merge upstream/main
|
||
# разрешить конфликт (скорее всего в месте патча Subscription.tsx)
|
||
git add -A && git commit && git push origin main
|
||
```
|
||
Следующий прогон workflow снова пойдёт сам.
|
||
|
||
**Деплой на VPS выкатил битую сборку**:
|
||
```bash
|
||
rsync -a --delete cabinet-dist.bak/ cabinet-dist/ # мгновенный откат
|
||
# либо
|
||
./deploy-cabinet.sh vX.Y.Z # конкретный рабочий релиз
|
||
```
|
||
|
||
**Security-алерт в GitHub про уязвимость** — это Dependabot alerts (без
|
||
авто-PR). Апстрим обычно фиксит сам, фикс прилетит следующим синком. Если
|
||
критично и срочно — можно поправить зависимость руками отдельным коммитом.
|
||
|
||
## Что стоит проверять периодически
|
||
|
||
- **Раз в 1–2 месяца — вкладка Actions.** GitHub отключает scheduled-триггер
|
||
после ~60 дней без активности в репозитории. Один ручной `Run workflow`
|
||
включает обратно.
|
||
- **Бэк и фронт бота обновлять вместе.** Синк фронта и апдейт бэкенда бота —
|
||
по-прежнему ручной процесс, специально не автоматизировали дальше деплоя.
|
||
- **CHANGELOG апстрима перед выкаткой** — на случай breaking changes в API
|
||
между бэкендом и фронтом.
|