From d4ded77355611074b5a423c7642789b21a616895 Mon Sep 17 00:00:00 2001 From: IK Date: Sat, 12 Sep 2026 20:58:50 +0700 Subject: [PATCH] ci: schedule isolated production bootstrap --- .gitea/workflows/production-bootstrap.yml | 40 +++++++++++++++++++++++ README.md | 2 ++ deploy/README.md | 2 ++ docs/ROADMAP.md | 2 +- 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 .gitea/workflows/production-bootstrap.yml diff --git a/.gitea/workflows/production-bootstrap.yml b/.gitea/workflows/production-bootstrap.yml new file mode 100644 index 0000000..c3fff92 --- /dev/null +++ b/.gitea/workflows/production-bootstrap.yml @@ -0,0 +1,40 @@ +name: Production bootstrap drill + +on: + workflow_dispatch: + schedule: + - cron: "17 3 * * 6" + +jobs: + isolated-production-bootstrap: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: "22" + cache: npm + cache-dependency-path: apps/web/package-lock.json + - name: Install web dependencies + run: npm --prefix apps/web ci + - name: Run isolated production bootstrap + shell: bash + run: | + set -o pipefail + mkdir -p artifacts + ./deploy/test-production-bootstrap.sh 2>&1 | tee artifacts/production-bootstrap.log + - name: Collect failure diagnostics + if: failure() + run: | + docker compose --env-file .env.production.example -f compose.production.yaml ps -a > artifacts/compose-ps.txt 2>&1 || true + cp -R apps/web/test-results artifacts/test-results 2>/dev/null || true + cp -R apps/web/playwright-report artifacts/playwright-report 2>/dev/null || true + - name: Upload drill diagnostics + if: always() + uses: actions/upload-artifact@v4 + with: + name: production-bootstrap-${{ github.run_id }} + path: artifacts + if-no-files-found: error + retention-days: 14 diff --git a/README.md b/README.md index 4d0692e..85ba6bc 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,8 @@ Production release отделяет Alembic от runtime: одноразовый Путь обновления схемы проверяется изолированным `deploy/test-release-upgrade.sh`: предыдущая ревизия получает контрольную запись, обновляется до head, после чего проверяются версия, сохранность записи и новые колонки. +Тяжёлый production bootstrap вынесен в отдельный ручной/еженедельный CI workflow с 30-минутным timeout и сохраняемыми diagnostics; обычный push по-прежнему использует быстрый Compose E2E. + После повторных ошибок scheduler увеличивает паузу экспоненциально до 24 часов и возвращается к 30 минутам после успеха. Публичная страница `/status` показывает свежесть и состояние источников без URL запросов, внутренних ошибок и другой диагностической информации. Подробный план и актуальные чекбоксы находятся в [`docs/ROADMAP.md`](docs/ROADMAP.md). Результаты проверки интерфейса и пять приоритетных UX-пакетов описаны в [`docs/UI_UX_AUDIT.md`](docs/UI_UX_AUDIT.md). diff --git a/deploy/README.md b/deploy/README.md index 4e55169..e70aedc 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -131,6 +131,8 @@ curl -fsS https://rf4spotter.ru/ready Drill успешно пройден 6 сентября 2026 года. На целевом сервере всё равно проведите учебное восстановление с реальной зашифрованной копией перед приглашением пользователей. Затем настройте ежедневный запуск `backup.sh`, выгрузку копий во внешнее хранилище и уведомление при ошибке; храните минимум 7 ежедневных и 4 еженедельных копии. +Полный production bootstrap дополнительно запускается отдельным CI workflow вручную и еженедельно. Он не удваивает быстрый Compose E2E на каждом push; полный лог сохраняется всегда, а при ошибке — также Compose status и браузерные diagnostics. + ## 7. Ежедневное обслуживание После успешного backup сначала проверьте план очистки, затем примените его: diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index fd046cd..d2ef93d 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -53,7 +53,7 @@ - [ ] **Q11 · Декомпозиция API.** Инкрементально разделить `apps/api/app/main.py` (638 строк, 26 маршрутов) на `APIRouter` по публичному каталогу/activity, submissions и admin/community. Сначала зафиксировать OpenAPI snapshot и сохранить URL, response models, middleware и dependency-поведение без функциональных изменений. - [ ] **Q12 · Query-plan gate.** В рамках Q07 снять `EXPLAIN (ANALYZE, BUFFERS)` для activity, records, spot detail и public spot pages на реалистичном наборе данных. Существующие индексы миграции `0011_query_indexes` не дублировать; индекс с `fish_id`, SQL-агрегацию или materialized view добавлять только по измеренному плану и p95. -- [ ] **Q13 · Production bootstrap в CI.** Добавить отдельный ручной/плановый job для `deploy/test-production-bootstrap.sh`, не удваивая быстрый Compose E2E на каждом коммите; сохранять diagnostics при падении. +- [x] **Q13 · Production bootstrap в CI.** Отдельный workflow запускает `deploy/test-production-bootstrap.sh` вручную или раз в неделю, а не на каждом push. Вывод bootstrap всегда сохраняется 14 дней; при падении добавляются Compose status и Playwright diagnostics. - [ ] **Q14 · Полная CSP.** Расширить текущую CSP (`frame-ancestors`, `base-uri`, `object-src`) до `default-src`, `script-src`, `style-src`, `img-src`, `connect-src` и `form-action`. Сначала инвентаризировать inline scripts/styles Astro, затем внедрить nonce/hash или безопасное вынесение; проверить report/admin/OG без ослабления до произвольных внешних origin. - [ ] **Q15 · Частичная деградация главной.** Разделить получение activity, community signals и справочников так, чтобы отказ одного источника не превращал всю главную в общий 503. Для SSR не добавлять искусственный client-side loading/optimistic UI; показывать независимые `StatePanel` и корректный HTTP/cache статус. - [ ] **Q16 · Контракт OpenAPI.** Генерировать OpenAPI artifact из приложения в CI и проверять осознанные изменения контракта при декомпозиции API; не поддерживать вручную редактируемую копию.