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

CI/CD

Качество кода защищено тремя слоями (defense in depth): Gate 1 — проверки перед коммитом и PR в цикле разработки, Gate 2 — pre-commit хук, Gate 3 — CI в GitHub Actions. Доставка — GitHub Actions → GHCR → Coolify (для документации — auto-deploy из Git). Устройство окружений — Развёртывание.

Гейты качества​

ГейтГдеЧто проверяет
Gate 1фаза SHIP цикла /op + консультативный Stop-хукbackend: lint, тесты, сборка, покрытие документации (docs:coverage); frontend: lint, typecheck, unit-тесты, сборка, e2e
Gate 2pre-commit (husky + lint-staged, backend/)по staged backend/src/**/*.ts: eslint --fix и tsc -p tsconfig.build.json --noEmit; коммит блокируется при неисправимой ошибке
Gate 3CI (GitHub Actions)полный набор проверок ниже на каждый PR и push

Ветки и коммиты: feat/OP-XX-<slug> от develop, сообщения <type>(scope): описание (OP-XX). Merge PR — чекпоинт человека; develop деплоится на stage, main — на prod.

Workflow'ы​

Каждый workflow запускается при изменении своего каталога (paths), на push в main/develop, на pull_request и вручную (workflow_dispatch, без деплоя). Деплой-job выполняется только на push.

backend-ci.yml (backend/**)​

Job build-and-check поднимает сервисы pgvector/pgvector:pg16 и redis:7-alpine, Node 22:

ШагКоманда
Установкаnpm ci
Аудит зависимостейnpm audit --omit=dev --audit-level=high (не блокирует)
Lintnpm run lint
Юнит-тестыnpm test
Миграции — применитьnpm run migration:run
e2e + цикл миграцийnpm run test:e2e (применить → откатить → применить)
Сборкаnpm run build
Покрытие документацииnpm run docs:coverage (порог 80 %)
Контракт OpenAPInpm run docs:openapi, артефакт openapi.json

frontend-ci.yml (frontend/**)​

npm ci → npm run lint → npm run typecheck → npm run test:unit → npm run build (NEXT_PUBLIC_API_URL=https://api.optimawb.ru) → установка Chromium → npm run e2e (Playwright; при падении отчёт сохраняется артефактом на 7 дней).

landing-ci.yml (landing/**)​

npm ci → npm run lint → npm run typecheck → npm run build (VITE_APP_ORIGIN, VITE_DOCS_URL).

Портал документации​

Отдельного workflow нет: проверка и сборка выполняются Docker-сборкой в Coolify (npm run build внутри docs-site/Dockerfile). Битые ссылки в документации ломают сборку, поэтому перед пушем запускайте npm run build в docs-site/ (Локальная разработка).

Доставка (CD)​

После успешных проверок на push job deploy собирает образ и публикует его в GHCR, затем дёргает deploy-webhook Coolify (curl --fail, заголовок Authorization: Bearer ${{ secrets.COOLIFY_TOKEN }}).

ПриложениеОбраз GHCRprod (main)stage (develop)
Backendghcr.io/affiliatefabriq/optima-backendapi.optimawb.ruwebhook stage
Frontendghcr.io/affiliatefabriq/optima-frontendapp.optimawb.ruwebhook stage
Landingghcr.io/affiliatefabriq/optima-landingoptimawb.ruwebhook stage
Docs-site— (сборка в Coolify)docs.optimawb.ruauto-deploy из Git
  • Теги образа: latest (из main) или develop (из develop) + sha-<short>.
  • Сборка linux/amd64 с кэшем GitHub Actions; concurrency отменяет устаревшие деплои той же ветки.
  • Публикация в GHCR — встроенным GITHUB_TOKEN (права packages: write).
  • Backend: образ при старте сам применяет миграции (см. Развёртывание).
  • Docs-site деплоится через GitHub App Coolify: main → prod, develop → stage; Watch Paths — docs-site/** и backend/**.

Секреты GitHub​

Settings → Secrets and variables → Actions:

СекретНазначение
COOLIFY_TOKENAPI-токен Coolify с правом Deploy
COOLIFY_WEBHOOK_BACKEND_PROD / COOLIFY_WEBHOOK_BACKEND_STAGEdeploy-webhook бэкенда
COOLIFY_WEBHOOK_FRONTEND_PROD / COOLIFY_WEBHOOK_FRONTEND_STAGEdeploy-webhook фронтенда
COOLIFY_WEBHOOK_LANDING_PROD / COOLIFY_WEBHOOK_LANDING_STAGEdeploy-webhook лендинга

URL webhook берётся из карточки приложения в Coolify. Для docs-site секреты не нужны. Секреты приложений (JWT, ключи шифрования, LLM и т. д.) хранятся в Coolify, а не в GitHub; в CI используются только заглушки для тестов.

Когда проверка падает​

  • Lint/typecheck — исправьте локально той же командой; хук Gate 2 ловит большинство случаев до коммита.
  • docs:coverage — публичному коду не хватает TSDoc: документируйте классы, методы и DTO вместе с кодом.
  • Контракт OpenAPI — изменился набор эндпоинтов: обновите ожидаемый список в backend/test/openapi.e2e-spec.ts и перегенерируйте клиент фронтенда (npm run api:generate).
  • Миграции — проверьте, что down() корректно откатывает up(): e2e гоняет полный цикл.