Files
MeshCore/ci

CI: автоматическая сборка прошивок на своём Gitea

Схема: Gitea (systemd) → act_runner на том же сервере → PlatformIO → артефакты out/. Сборка идёт через build.sh из репозитория, то есть тем же путём, что и локально (версия прошивки, merge-bin для ESP32, .uf2 для nRF52), — логика не дублируется.

Что где лежит

Файл Назначение
.gitea/workflows/firmware.yml workflow: клон, кэш PlatformIO, сборка, артефакты, черновик релиза по тегу
ci/build-firmwares.sh сборка выбранного набора env (годится и для запуска руками)
ci/act_runner/act-runner.service systemd-юнит раннера
ci/act_runner/config.yaml конфиг раннера: ёмкость, таймаут, кэш
ci/act_runner/docker-compose.yml альтернатива: раннер в Docker

1. Что должно быть на VPS

apt-get update
apt-get install -y git python3 python3-venv python3-pip build-essential curl ca-certificates
  • python3-venv обязателен: workflow ставит PlatformIO в отдельное окружение (~/.platformio-venv), потому что на свежих Debian/Ubuntu pip в систему запрещён.
  • Свободного места нужно 5 ГБ: ~/.platformio с тулчейнами (~2–3 ГБ), venv и промежуточные файлы сборки.
  • RAM: 2 ГБ достаточно, при 1 ГБ возможны падения линковки ESP32.

2. Установка раннера (systemd)

# отдельный пользователь, от его имени пойдут сборки
useradd --create-home --home-dir /var/lib/act-runner --shell /bin/bash act-runner

# бинарник: актуальную версию и имя файла сверьте на
# https://gitea.com/gitea/act_runner/releases
# (в свежих релизах проект называется Gitea Runner, см. https://docs.gitea.com/runner/)
curl -fsSL -o /usr/local/bin/act_runner \
  https://gitea.com/gitea/act_runner/releases/download/v0.2.11/act_runner-0.2.11-linux-amd64
chmod +x /usr/local/bin/act_runner

# каталоги
install -d -o act-runner -g act-runner /var/lib/act-runner
install -d /etc/act_runner
cp ci/act_runner/config.yaml /etc/act_runner/config.yaml

# токен: Gitea → репозиторий → Settings → Actions → Runners → Create new Runner
su - act-runner -c 'act_runner register --no-interactive \
  --instance https://git.meshinfo.ru \
  --token ВСТАВИТЬ_ТОКЕН \
  --name meshcore-builder \
  --labels ubuntu-latest:host'

# сервис
cp ci/act_runner/act-runner.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now act-runner
systemctl status act-runner
journalctl -u act-runner -f          # в логах: "runner registered" / "polling tasks"

Метка ubuntu-latest:host означает, что шаги выполняются прямо на сервере — быстро и без Docker, но зависимости ставятся в систему. Метка должна совпадать с runs-on в .gitea/workflows/firmware.yml.

Раннер виден в Gitea: репозиторий → Settings → Actions → Runners (должен быть зелёным).

Альтернатива: раннер в Docker

Если на VPS есть Docker, из ci/act_runner:

cd ci/act_runner
cat > .env <<'EOF'
GITEA_INSTANCE_URL=https://git.meshinfo.ru
GITEA_RUNNER_REGISTRATION_TOKEN=ВСТАВИТЬ_ТОКЕН
GITEA_RUNNER_NAME=meshcore-builder
EOF
docker compose up -d && docker compose logs -f

В этом варианте job'ы идут в контейнере catthehacker/ubuntu:act-22.04, а docker.sock смонтирован внутрь раннера. В свежих версиях образ может называться gitea/runner.

3. Отключить лишние workflow

Gitea читает workflow и из .gitea/workflows, и из .github/workflows, а там лежат upstream-файлы с триггером push: build-companion-firmwares.yml, build-repeater-firmwares.yml, build-room-server-firmwares.yml, github-pages.yml, run-unit-tests.yml. На первом же пуше они попытаются собрать сотни env (в проекте их около 600) или задеплоить Pages.

Отключите их в настройках репозитория (раздел Actions) либо через API:

curl -X POST -H "Authorization: token $GITEA_TOKEN" \
  https://git.meshinfo.ru/api/v1/repos/shade/MeshCore/actions/workflows/run-unit-tests.yml/disable

Оставьте включённым только firmware.yml. Если ваша версия Gitea поддерживает настройку actions.WORKFLOW_DIRS, можно ограничить список каталогов одним .gitea/workflows — тогда upstream-файлы не подхватятся вовсе.

4. Запуск сборки

  • Автоматически — push в main (кроме изменений в *.md, ci/**, .preview/**).
  • Вручную — Actions → Firmware build → Run workflow, поля:
    • targets — env через запятую, например Heltec_t096_companion_radio_ble,ProMicro_companion_radio_ble;
    • match — подстрока имени env, например heltec_t096;
    • version — значение FIRMWARE_VERSION (по умолчанию ci).
  • Локально — тот же скрипт, что запускает CI:
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
bash build.sh list | grep -i t096        # доступные env

Готовые файлы попадают в out/ (каталог в .gitignore) и прикрепляются к запуску workflow как артефакт firmware.

5. Релизы по тегу

Пуш тега вида v1.0.0 или companion-v1.0.0 запускает сборку и создаёт черновик релиза с прикреплёнными .bin / .uf2 / .zip. Версия прошивки берётся из тега: companion-v1.2.3 → v1.2.3, и попадает в имена файлов (<env>-v1.2.3-<sha>.uf2).

Черновик — чтобы можно было посмотреть состав и нажать Publish руками:

git tag companion-v1.0.0
git push origin companion-v1.0.0
# затем: репозиторий → Releases → черновик → Publish

Для публикации используется secrets.GITHUB_TOKEN, который Gitea выдаёт workflow автоматически (в workflow стоит permissions: contents: write). Если по вашему токену релизы не создаются, заведите секрет репозитория RELEASE_TOKEN с правом write:repository и подставьте его в шаге «Черновик релиза».

Набор прошивок по умолчанию

ci/build-firmwares.sh собирает устройства этого форка (список — массив DEFAULT_TARGETS): T096 (companion, repeater, room server, sensor), ProMicro (SSD1306, SH1106, repeater, room server), Heltec v3, heltec_v4 TFT, tracker_v2, T-Deck, T-Echo Card, T114, T190, M9 и три варианта Meshadventurer.

Время и кэш

  • Первая (холодная) сборка набора — примерно 30–60 минут: скачиваются тулчейны.
  • Последующие запуски заметно быстрее: ~/.platformio и venv кэшируются между запусками через actions/cache.
  • capacity: 1 в config.yaml — одна сборка за раз; поднимайте, если CPU позволяет.

Ограничения

  • Шаги используют actions/checkout, actions/cache, actions/upload-artifact, actions/download-artifact. Раннер скачивает их с GitHub (DEFAULT_ACTIONS_URL), поэтому серверу нужен доступ в интернет; в закрытом контуре укажите свой миррор экшенов в config.yaml.
  • Кэш ~/.platformio растёт со временем: если диск кончается, почистите ~/.platformio/.cache у пользователя act-runner.