- _corebuild.musl_platform_tag(): на musl (Alpine/HA OS) bdist_wheel выпускает py3-none-musllinux_X_Y_<arch> вместо linux_<arch> — иначе pip ставит glibc-сборку и dlopen падает на ld-linux-x86-64.so.2 - shared-библиотека линкуется со -static-libstdc++ -static-libgcc (gcc): NEEDED только libm/libc (проверено readelf), меньше зависимостей у HA OS - Gitea Actions: job build-musllinux (container python:3.12-alpine) собирает и публикует musl-wheel; build-glibc — как раньше; общий scripts/publish-gitea-pypi.sh с пропуском уже загруженных файлов - тесты musl_platform_tag; RELEASE_HA §1.1-1.4 (выбор wheel, переустановка на HA OS, ручная сборка musllinux без container:); README troubleshooting
9.7 KiB
Релиз и установка HA-интеграции
1. Внутренняя сборка и установка (Gitea, текущий режим)
Внутренний репозиторий — Gitea (git.ratigorsk-12.ru), поэтому:
- HACS к Gitea не подключается (только публичный GitHub) — для
внутреннего использования интеграция ставится копированием
custom_components/fglair/в<config>/custom_components/; - зависимость
pyfglairпубликуется в PyPI-реестр пакетов Gitea и ставится оттуда.
1.1. Сборка и публикация wheel (Gitea Actions, ручной запуск)
Workflow: .gitea/workflows/publish-pyfglair.yaml (workflow объявляет
permissions: contents: read, packages: write).
Авторизация — любой из вариантов:
- Встроенный job-токен (Gitea ≥ 1.27, где
packagesподдержан у features): ничего настраивать не нужно, workflow возьмёт${{ secrets.GITEA_TOKEN }}; - Personal access token со scope
write:package(для версий, где публикация пакетов job-токеном ещё не реализована — см. HACS-док Gitea «Package repository authorization»): положите его в секретPYPI_TOKEN, при необходимости задайтеPYPI_USER(имя пользователя к PAT; иначе — актор запуска). Имена секретов не могут начинаться сGITEA_— префикс зарезервирован Gitea.
Запуск: Actions → Publish pyfglair → Run workflow (вход
bundled_mbedtls: 1 — встроить mbedtls, 0 — системный
libmbedtls-dev). Собираются два wheel одной версии:
py3-none-linux_x86_64— glibc (HA Supervised/Core на Debian/Ubuntu);py3-none-musllinux_1_2_x86_64— musl (HA OS, Alpine-контейнер); jobbuild-musllinuxвыполняется вcontainer: python:3.12-alpine(нуженcontainer:у runner'а; иначе см. §1.4).
Артефакты появятся в
https://git.ratigorsk-12.ru/api/packages/<owner>/pypi/simple/pyfglair/
(<owner> — владелец репозитория, напр. esphome). C++-рантайм в .so
встроен (-static-libstdc++ -static-libgcc), поэтому wheel зависит только
от libc/libm соответствующей платформы.
Workflow собирает wheel + sdist, прогоняет smoke-тест установки
(запускается из /tmp с python -P, чтобы не подхватить исходники
pyfglair/ вместо wheel) и публикует через twine upload. Twine 7 не
поддерживает --skip-existing для не-PyPI репозиториев, поэтому workflow
сам проверяет simple-индекс Gitea и пропускает загрузку, если версия уже
опубликована. Для новой версии поднимите version в pyproject.toml.
1.2. Установка pyfglair в Home Assistant
Выбор wheel pip делает сам по платформе: на HA OS (Alpine/musl) — из musllinux, на HA Supervised/Core (Debian/glibc) — из linux-сборки.
Пакет обязателен (cffi-биндинги). Варианты:
-
Вручную в окружение HA (проще всего для теста; HA увидит установленный дистрибутив и не будет вызывать pip для
pyfglair>=1.0.0):# в контейнере/venv Home Assistant (Advanced SSH & Web Terminal, docker exec и т.п.) pip install --index-url https://<user>:<token>@git.ratigorsk-12.ru/api/packages/<owner>/pypi/simple \ --no-deps pyfglair -
Через индекс pip в окружении HA (
pip.conf/PIP_EXTRA_INDEX_URL): тогда HA сам поставитpyfglairиз манифеста. Учтите риск dependency confusion при--extra-index-url— для внутреннего стенда допустимо.
Если при добавлении интеграции HA пишет «Invalid handler specified» —
пакет pyfglair не установлен (или компонент не перезапущен). Смотрите
grep -iE "fglair|pyfglair" /config/home-assistant.log: при
ModuleNotFoundError: No module named 'pyfglair' установите пакет в
окружение HA (docker exec homeassistant python -m pip install ...) и
полностью перезапустите HA.
- Публичный PyPI — см. §2 (для распространения вне сети).
1.3. Если HA уже установил glibc-wheel на HA OS
Симптом: OSError: cannot load library ... Error loading shared library ld-linux-x86-64.so.2: No such file or directory. Переустановите пакет с
musllinux-сборкой:
docker exec homeassistant python -m pip uninstall -y pyfglair
docker exec homeassistant python -m pip install --no-deps --index-url \
https://<user>:<token>@git.ratigorsk-12.ru/api/packages/<owner>/pypi/simple \
pyfglair
docker exec homeassistant python -c "import pyfglair; print(pyfglair.__version__)"
docker restart homeassistant
1.4. Ручная сборка musllinux (если runner без container:)
docker run --rm -v "$PWD":/src -w /src python:3.12-alpine sh -c '
apk add --no-cache git cmake ninja g++ make curl libstdc++-dev &&
pip install build &&
python -m build --wheel'
# dist/pyfglair-<ver>-py3-none-musllinux_1_2_x86_64.whl
pip install twine
python -m twine upload --repository-url \
https://git.ratigorsk-12.ru/api/packages/<owner>/pypi \
-u <user> -p <token> dist/*musllinux*.whl
1.5. Обновление интеграции
custom_components/fglair/ обновляется из Gitea (git pull / копирование),
затем перезапуск HA. pyfglair — переустановкой из пакетов Gitea.
2. Публикация pyfglair на PyPI (если понадобится публично)
PyPI (warehouse) принимает только manylinux*/musllinux* теги, поэтому
локальный py3-none-linux_x86_64 нужно чинить auditwheel'ом в контейнере
со старой glibc:
pip install build auditwheel twine
# для каждой архитектуры (linux x86_64/aarch64) в manylinux-контейнере:
python -m build --wheel
auditwheel repair dist/pyfglair-*.whl --plat manylinux2014_x86_64 -w dist/manylinux/
rm -f dist/pyfglair-*-linux_*.whl
python -m build --sdist
twine upload dist/manylinux/* dist/*.tar.gz
Проверки: scripts/py-ci.sh, scripts/ci.sh, readelf -d по .so
(нет внешней libmbedcrypto), установка wheel в чистый venv.
3. GitHub-зеркало и Custom Repositories (HACS)
HACS устанавливает интеграции только с публичных GitHub-репозиториев (GitLab/Gitea не поддерживаются: https://hacs.xyz/docs/faq/other_git_providers/). Публикация в default-репозиторий HACS не требуется — достаточно Custom Repositories, но хостинг обязан быть GitHub.
git remote add github git@github.com:<owner>/fgl-aircon.git
git push --mirror github
После зеркала:
- заполнить на GitHub Description, Topics (
home-assistant,hacs,fujitsu,air-conditioner), включить Issues (проверяет HACS Action); - проверить
codeownersв manifest (@petr.polezhaev; для GitHub нужен реальный GitHub-логин); - обновить
versionманифеста под тег; заменить заглушкиscreenshots/step-N.pngиbrand/*.pngреальными ассетами; - создать тег (semver) — HACS покажет версию.
Готовые файлы HACS: hacs.json, info.md, LICENSE (MIT),
custom_components/fglair/brand/ (icon/icon@2x/logo + dark-варианты),
workflows .github/workflows/{validate-hacs,hassfest}.yaml.
4. Приёмка на живом стенде
tests/acceptance/test_esphome_ha.py quick— матрица изменений (HA; с--esphome-hostшаги «режим/уставка» идут через ESPHome, проверка — по состоянию в HA), возврат к исходному.long --hours 24 --interval 3600 --report acceptance.csv.- Сценарии: 503 (два слота), key_error + Repair, offline/восстановление, два устройства, options flow (копирование/смена ключа), reconfigure.
5. Ограничения стенда
- Реального железа/облака в CI нет: протокол проверен mock-модулем, облако — мок-сервером; приёмочный скрипт имеет self-test на моке HA REST.
- Суточный soak, re-key и облачный вход — только на приборе/аккаунте.
- Gitea Actions: встроенный
GITEA_TOKENне публикует пакеты (нужен PAT);actions/checkout/setup-pythonтянутся с github.com (для изолированного инстанса используйте абсолютные URL зеркал).