Files
LMS/deploy/WOODPECKER.md
Vladislav Kopnin 685916c4bd ci: перевести merge gate на Gitea + Woodpecker
- .woodpecker/check.yaml, smoke.yaml, release.yaml
- local-backend агент: Java 21, Docker Compose v2, Python 3, Node/Playwright
- concurrency lms-ci, чтобы smoke/release не занимали порты одновременно
- deploy/WOODPECKER.md: server, OAuth Gitea, systemd-агент, security note
- удалён .gitlab-ci.yml
2026-10-29 12:01:44 +03:00

7.3 KiB
Raw Blame History

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-браузеры.

Проверка окружения:

./scripts/ci-preflight.sh          # для smoke/check
./scripts/ci-preflight.sh --release

2. Woodpecker server

Удобно запустить server в Docker рядом с Gitea. Пример docker-compose.woodpecker.yml (не коммитьте секреты):

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:
    [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 хоста.

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):

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:

[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
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/ (по умолчанию).