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
This commit is contained in:
164
deploy/WOODPECKER.md
Normal file
164
deploy/WOODPECKER.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# 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/`
|
||||
(по умолчанию).
|
||||
Reference in New Issue
Block a user