Files
MeshCore/ci/README.md
T

201 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CI: автоматическая сборка прошивок на своём Gitea
Схема: **Gitea (systemd) → Gitea Runner на том же сервере → PlatformIO → артефакты `out/`**.
Сборка идёт через `build.sh` из репозитория, то есть тем же путём, что и локально
(версия прошивки, `merge-bin` для ESP32, `.uf2` для nRF52), — логика не дублируется.
## Что где лежит
| Файл | Назначение |
|---|---|
| `.gitea/workflows/firmware.yml` | workflow: клон, кэш, сборка, артефакты (запуск только вручную) |
| `ci/build-firmwares.sh` | сборка выбранного набора env (годится и для запуска руками) |
| `ci/build-local.ps1` | сборка на своей машине под Windows и публикация релиза в Gitea |
| `ci/act_runner/gitea-runner.service` | systemd-юнит раннера |
| `ci/act_runner/config.yaml` | конфиг раннера: ёмкость, таймаут, кэш |
| `ci/act_runner/docker-compose.yml` | альтернатива: раннер в Docker |
## 1. Что должно быть на сервере
```bash
apt-get update
apt-get install -y git python3 python3-venv python3-pip curl ca-certificates build-essential
```
- **`python3-pip` обязателен:** без него `python3 -m venv` создаёт окружение без pip,
и шаг установки PlatformIO падает. Готовое окружение workflow пересоздаст сам.
- Свободного места нужно **5 ГБ**: тулчейны PlatformIO занимают ~800 МБ на одну платформу,
а при сборке и ESP32, и nRF52 — заметно больше.
- **Swap желателен.** На VPS с 2 ГБ RAM линковка ESP32 упирается в память:
```bash
fallocate -l 2G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
```
## 2. Включение Actions в Gitea
В `/etc/gitea/app.ini` (владелец `git:git`, права 600):
```ini
[actions]
ENABLED = true
# значение — github или gitea (ссылка не поддерживается)
DEFAULT_ACTIONS_URL = github
# workflow ищем только здесь, чтобы не подхватывались upstream-файлы
WORKFLOW_DIRS = .gitea/workflows
```
После правки: `systemctl restart gitea`. Перед изменением делайте копию конфига —
`cp -a /etc/gitea/app.ini /etc/gitea/app.ini.bak`.
## 3. Установка раннера (systemd)
```bash
useradd --create-home --home-dir /var/lib/act-runner --shell /bin/bash act-runner
# актуальный релиз: https://gitea.com/gitea/runner/releases
curl -fsSL -o /usr/local/bin/gitea-runner \
https://gitea.com/gitea/runner/releases/download/v5.0.0/gitea-runner-5.0.0-linux-amd64
chmod +x /usr/local/bin/gitea-runner
gitea-runner --version
install -d -o act-runner -g act-runner /var/lib/act-runner
cp ci/act_runner/config.yaml /var/lib/act-runner/config.yaml
chown act-runner:act-runner /var/lib/act-runner/config.yaml
```
**Токен — обязательно со scope репозитория**: без `--scope` раннер становится глобальным
и начинает брать задачи всех репозиториев инстанса:
```bash
# от имени пользователя Gitea (CLI не работает под root)
su - git -c "gitea actions generate-runner-token -c /etc/gitea/app.ini --scope shade/MeshCore" \
> /var/lib/act-runner/reg-token
chown act-runner:act-runner /var/lib/act-runner/reg-token && chmod 600 /var/lib/act-runner/reg-token
su - act-runner -c "/usr/local/bin/gitea-runner register --no-interactive \
--instance https://git.meshinfo.ru \
--token-file /var/lib/act-runner/reg-token \
--name meshcore-builder \
--labels ubuntu-latest:host \
-c /var/lib/act-runner/config.yaml"
rm -f /var/lib/act-runner/reg-token # токен больше не нужен
```
Метка `ubuntu-latest:host` означает, что шаги выполняются **прямо на сервере** — без Docker,
но зависимости ставятся в систему. Метка должна совпадать с `runs-on` в workflow.
```bash
cp ci/act_runner/gitea-runner.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now gitea-runner
systemctl status gitea-runner
journalctl -u gitea-runner -f # ждём "declare successfully"
```
### Альтернатива: раннер в Docker
```bash
cd ci/act_runner && cp .env.example .env && nano .env && docker compose up -d
```
## 4. Запуск сборки
Workflow запускается **только вручную** — автоматических сборок по push и тегам нет
(прошивки собираются локально и публикуются релизом, см. следующий раздел).
- **Вручную в Gitea** — Actions → Firmware build → Run workflow (`targets`, `match`, `version`),
либо через API:
```bash
curl -X POST -H "Authorization: token $GITEA_TOKEN" -H 'Content-Type: application/json' \
-d '{"ref":"main","inputs":{"targets":"Heltec_t096_companion_radio_ble","version":"ci"}}' \
https://git.meshinfo.ru/api/v1/repos/shade/MeshCore/actions/workflows/firmware.yml/dispatches
```
- **Локально** — тем же скриптом, что запускает CI:
```bash
FIRMWARE_VERSION=v1.0.0 bash ci/build-firmwares.sh
MATCH=promicro bash ci/build-firmwares.sh
TARGETS="Heltec_t096_companion_radio_ble" bash ci/build-firmwares.sh
```
Готовые файлы попадают в `out/` (каталог в `.gitignore`); при запуске в Gitea они
выгружаются артефактом `firmware`.
### Локально на Windows, без нагрузки на сервер
На этом VPS всего 1 CPU, поэтому полный набор прошивок собирается там часами. Разумнее
собрать у себя, а на сервер отправить только готовые файлы — релизом Gitea:
```powershell
# быстрый набор: все env, в имени которых есть подстрока
.\ci\build-local.ps1 -Match promicro -Version v1.0.0
# полный набор из DEFAULT_TARGETS
.\ci\build-local.ps1 -Version v1.0.0
# собрать и опубликовать релиз
$env:GITEA_TOKEN = '<токен с правом write:repository>'
.\ci\build-local.ps1 -Version v1.0.0 -Publish -Public -Tag v1.0.0
# опубликовать уже собранное, без пересборки
.\ci\build-local.ps1 -Version v1.0.0 -SkipBuild -Publish -Public -Tag v1.0.0
```
Скрипт находит Git Bash и PlatformIO, подставляет рабочий `python3`, чистит `out/`
перед сборкой, а с `-Publish` создаёт тег и релиз, прикрепляя к нему файлы
(`-Public` публикует сразу, без флага создаётся черновик). Токен нужен только для
публикации: сама сборка работает без него.
На Linux/macOS то же самое делается напрямую: `FIRMWARE_VERSION=v1.0.0 bash ci/build-firmwares.sh`.
## 5. Релизы
Релиз собирается и публикуется **локально**: `ci/build-local.ps1 -Publish -Public -Tag <тег>`
(см. выше). Скрипт создаёт тег на текущем коммите, релиз в Gitea и прикрепляет к нему
`.bin` / `.uf2` / `.zip`; версия `-Version` попадает в имена файлов
(`<env>-v1.0.0-<sha>.uf2`). Если тег уже существует, он переиспользуется.
В CI шага публикации нет: сервер только собирает прошивки по ручному запуску и отдаёт их
артефактом.
### Прошивальщик на сайте
Страница <https://meshinfo.ru/flasher/> берёт список прошивок из своего `index.json`
(статика в `/var/www/flasher`, а сами файлы браузер тянет через nginx напрямую из релизов
Gitea). Имена файлов в манифесте разобраны на плату, роль, чип и формат, поэтому после
каждой публикации релиза его нужно пересобрать — иначе на странице останутся старые ссылки.
```powershell
.\ci\update-flasher.ps1 # пересобрать и выложить на сервер
.\ci\update-flasher.ps1 -SkipUpload # только пересобрать, без заливки
```
Скрипт запускает генератор `build-flasher-index.py` из соседнего репозитория
(`..\MeshCore-posadmesh-meshcoretel\posadmesh-tools\`; путь задаётся через `-Generator`
или `FLASHER_GENERATOR`), делает на сервере бэкап старого манифеста, заливает новый и
проверяет, что страница отдаёт его, а файлы доступны через `/flasher/fw/...`.
При публикации релиза (`ci/build-local.ps1 -Publish`) обновление выполняется автоматически,
отключить можно флагом `-SkipFlasher`.
## 6. Набор прошивок по умолчанию
`ci/build-firmwares.sh`, массив `DEFAULT_TARGETS` — 26 env:
- **companion (15):** T096, ProMicro (SSD1306 и SH1106), Heltec v3, heltec_v4, heltec_v4 TFT,
tracker_v2, T-Deck, T-Echo Card, T114, T190, M9, Meshadventurer (sx1262, sx1262 + e22p
868M30S, e22p 433M30S);
- **repeater (8):** Heltec v3, heltec_v4, heltec_v4 TFT, T096, ProMicro, Meshadventurer
(sx1262, sx1262 + e22p 868M30S, sx1262 + e22p 433M30S);
- **room server / sensor (3):** T096 room server, T096 sensor, ProMicro room server.
## 7. Время и ресурсы
- Сервер с **1 CPU / 2 ГБ RAM** полный набор собирает часами, поэтому рабочий вариант —
собирать полный набор локально (`ci/build-local.ps1`), а в Gitea запускать вручную
только те env, которые нужно проверить.
- Первая сборка качает тулчейны (nRF52: framework + CMSIS + gcc-arm ≈ 660 МБ;
ESP32 — ещё столько же), дальше работает кэш `~/.platformio`.
- `capacity: 1` в `config.yaml` — одна сборка за раз.