# CI/CD (Gitea Actions) Пайплайн — `.gitea/workflows/ci-cd.yml`. На каждый push/PR: юнит-тесты `Domain.Tests` + `docker compose build` (проверка, что весь стек собирается). На push в `master` — дополнительно `docker compose up -d` (реальный редеплой). Раннер выполняет джобы **прямо на целевом сервере** (`ruvdstest.danamir.site`, тот же, что описан в `docs/DEPLOY.md`) — это и есть логика деплоя: шаг "Deploy" в workflow просто выполняет `docker compose up -d` в том же каталоге `/opt/ruvdstests`, поверх уже поднятого стека. ## Регистрация раннера Выполняется один раз, на целевом сервере (там же, где разворачивали приложение), после того как шаги 1–6 из `docs/DEPLOY.md` пройдены. **1. Убедиться, что Actions включены** на вашем Gitea (Site Administration → пункт "Actions" должен быть виден; если Gitea развёрнута в докере — переменная `GITEA__actions__ENABLED=true` в её конфиге/окружении). **2. Получить токен регистрации**: Site Administration → Actions → Runners → **Create new runner** (или в настройках именно этого репозитория: Settings → Actions → Runners). **3. Запустить раннер** (заполните токен и запустите сами — секрет никому больше не передаётся): ```bash docker volume create gitea-runner-data docker run -d --name gitea-ci-runner --restart unless-stopped \ -v /var/run/docker.sock:/var/run/docker.sock \ -v gitea-runner-data:/data \ -e GITEA_INSTANCE_URL=https://git.danamir.su \ -e GITEA_RUNNER_REGISTRATION_TOKEN=ВАШ_ТОКЕН_СЮДА \ -e GITEA_RUNNER_NAME=ruvdstest-prod \ -e GITEA_RUNNER_LABELS=host:host \ gitea/runner:latest ``` `host:host` — раннер выполняет джобы напрямую в своём собственном контейнере (никаких вложенных контейнеров на каждый джоб), у него смонтирован docker.sock хоста — поэтому `docker compose` внутри джоба управляет реальными контейнерами на этой машине. Джоб сам ставит себе `node`, `docker-cli` и .NET SDK через `apk`/`dotnet-install.sh` (см. workflow) — образ раннера намеренно голый, чтобы не поддерживать отдельный кастомный образ. `node` ставится первым шагом, до `actions/checkout` — этот шаг сам является JS-экшеном и без `node` в PATH падает с `Cannot find: node in PATH` раньше, чем успевает выполниться что-либо ещё. Проверить, что раннер подключился: Site Administration → Actions → Runners — должен появиться `ruvdstest-prod` со статусом Idle/Online. ## Секреты Джоб чекаутит репозиторий во временную директорию раннера, а не в `/opt/ruvdstests` — своего `.env` там нет, поэтому `JWT_SECRET`/`POSTGRES_PASSWORD` для `docker compose build`/`up` берутся не из файла, а из хранилища секретов самой Gitea Actions: Settings репозитория → Actions → Secrets → **Add Secret**. Завести `JWT_SECRET` и `POSTGRES_PASSWORD` со **значениями, совпадающими с тем, что уже лежит в `/opt/ruvdstests/.env`** на сервере (`cat /opt/ruvdstests/.env` на сервере, скопировать оттуда) — деплой-шаг пересоздаёт тот же самый запущенный проект (`COMPOSE_PROJECT_NAME` выше), и рассинхронизация паролей с уже инициализированным `pgdata`-volume сломает подключение к БД. ## Проверка Сделайте любой коммит и запушьте в `master` — во вкладке **Actions** репозитория должен появиться запуск, пройти тесты, сборку и деплой. После завершения `https://ruvdstest.danamir.site` уже обслуживает обновлённую версию.