# CI на Gitea + Woodpecker Репозиторий использует **Woodpecker CI 3.x**. Конфигурация лежит в `.woodpecker/`: | Workflow | Событие | Что делает | |---|---|---| | `check` | push, pull_request | `ci-preflight.sh`, `test ktlintCheck detekt evidenceCheck` | | `smoke` | push, pull_request | после `check`: полный стек, health, вход админа, один курс | | `release` | tag, manual | `npm ci`, preflight, полный `ldd-release.sh` (миграции, mutation, load, Chromium/Firefox/WebKit) | Все три workflow используют `concurrency: {limit: 1, group: lms-ci}`: smoke и release поднимают реальный стек на портах 8080–8090, параллельный запуск занял бы порты. ## Почему local backend `check` может работать в Docker-бэкенде, но `smoke`/`release` запускают `docker compose` и Java-процессы на `localhost`, поэтому им нужен доступ к Docker и портам хоста. Проще всего один агент с **local backend** на том же сервере, где стоит Docker. > **Безопасность.** Local backend выполняет пайплайн прямо на хосте без > изоляции. Он допустим только для **приватного** репозитория с доверенными > авторами. Не включайте публичные форки/PR от недоверенных пользователей на > этом агенте: код пайплайна сможет прочитать окружение агента. Если появится > публичный контур — вынесите `check` на отдельный Docker-backend агент, а > smoke/release оставьте на изолированной машине. ## 1. Требования к серверу агента - Java 21 в `PATH` (не Java 25 — см. README). - Docker Engine + Compose v2, пользователь агента в группе `docker`. - Python 3, bash, git, curl, `ss` (`iproute2`), Node.js 22 + npm. - Системные библиотеки для Chromium/Firefox/WebKit. На Fedora проще один раз выполнить `sudo npx playwright install-deps`; WebKit при их отсутствии автоматически запускается в Docker-образе Playwright. - Свободные порты 8080–8090 на время smoke/release. - Достаточно места: Gradle-кэш, Docker-образы, Playwright-браузеры. Проверка окружения: ```bash ./scripts/ci-preflight.sh # для smoke/check ./scripts/ci-preflight.sh --release ``` ## 2. Woodpecker server Удобно запустить server в Docker рядом с Gitea. Пример `docker-compose.woodpecker.yml` (не коммитьте секреты): ```yaml services: woodpecker-server: image: woodpeckerci/woodpecker-server:v3 restart: unless-stopped ports: - "127.0.0.1:8000:8000" # UI за nginx - "127.0.0.1:9000:9000" # gRPC для агента environment: WOODPECKER_OPEN: "false" WOODPECKER_HOST: ${WOODPECKER_HOST:?https://ci.example.ru} WOODPECKER_GITEA: "true" WOODPECKER_GITEA_URL: ${GITEA_URL:?https://git.example.ru} WOODPECKER_GITEA_CLIENT: ${GITEA_CLIENT:?} WOODPECKER_GITEA_SECRET: ${GITEA_SECRET:?} WOODPECKER_AGENT_SECRET: ${WOODPECKER_AGENT_SECRET:?} WOODPECKER_ADMIN: ${WOODPECKER_ADMIN:?admin} volumes: - woodpecker-data:/var/lib/woodpecker volumes: woodpecker-data: ``` 1. В Gitea создайте OAuth2-приложение: redirect URI `https://ci.example.ru/authorize`. 2. Заполните `GITEA_CLIENT`, `GITEA_SECRET`, `WOODPECKER_AGENT_SECRET` (например, `openssl rand -hex 32`), `WOODPECKER_HOST`, `GITEA_URL`. 3. Если Gitea и Woodpecker на одном хосте, разрешите webhook на loopback в `/etc/gitea/conf/app.ini`: ```ini [webhook] ALLOWED_HOST_LIST = external,loopback ``` Также проверьте, что Gitea отдаёт API-страницы не меньше 50 элементов (значение по умолчанию подходит). 4. Поднимите server и зайдите в UI через Gitea-аккаунт. 5. Включите репозиторий LMS в Woodpecker (Settings → Repositories). ## 3. Агент на хосте Server в контейнере, агент — **на хосте**, иначе local backend не увидит Java/Docker/Node хоста. ```bash sudo useradd --system --create-home --shell /bin/bash woodpecker sudo usermod -aG docker woodpecker sudo install -m 0755 woodpecker-agent /usr/local/bin/woodpecker-agent ``` `woodpecker-agent` скачивается из релизов Woodpecker (Linux amd64): `https://github.com/woodpecker-ci/woodpecker/releases`. `/etc/woodpecker-agent.env` (права `0600`, владелец `root`): ```dotenv WOODPECKER_SERVER=localhost:9000 WOODPECKER_AGENT_SECRET=тот-же-секрет-что-у-server WOODPECKER_BACKEND=local WOODPECKER_MAX_WORKFLOWS=1 # Кэш Gradle и браузеров Playwright переживает запуски. Допустимо только для # приватного репозитория с доверенными авторами (см. предупреждение выше). WOODPECKER_BACKEND_LOCAL_ISOLATED_HOME=false ``` `/etc/systemd/system/woodpecker-agent.service`: ```ini [Unit] Description=Woodpecker CI agent (LMS) After=network-online.target docker.service Wants=network-online.target [Service] User=woodpecker EnvironmentFile=/etc/woodpecker-agent.env ExecStart=/usr/local/bin/woodpecker-agent Restart=always RestartSec=5 [Install] WantedBy=multi-user.target ``` ```bash sudo systemctl daemon-reload sudo systemctl enable --now woodpecker-agent journalctl -u woodpecker-agent -f ``` В UI агент появится через несколько секунд. Репозиторий должен быть помечен как trusted, если вы захотите использовать volumes/privileged (текущему конфигу они не нужны). ## 4. Первый прогон 1. Push в ветку или MR → pipeline `check` → `smoke`. 2. Убедиться, что зелёные оба workflow. 3. Проверить ручной запуск: UI → Run pipeline → event `manual` → workflow `release`. 4. Для релиза: `git tag vX.Y.Z && git push origin vX.Y.Z` → workflow `release`; полный отчёт печатается в лог, файлы остаются в `build/evidence/` рабочей копии агента. Если pipeline не появляется: - проверьте, что репозиторий включён в Woodpecker; - проверьте `WOODPECKER_SERVER` и общий `WOODPECKER_AGENT_SECRET`; - проверьте, что агент видит Docker (`docker compose version` от пользователя `woodpecker`) и Java 21; - проверьте, что путь конфигурации в настройках проекта — `.woodpecker/` (по умолчанию).