set -o pipefail убран (единственный bashism), shebang /bin/sh; musl-джоб
вызывает sh scripts/publish-gitea-pypi.sh, bash из apk-списка исключён.
Логика проверена на фейковом индексе: уже загруженный linux-wheel
пропускается, musl-wheel и sdist загружаются.
- _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
twine 7 запрещает --skip-existing для не-PyPI репозиториев
(UnsupportedConfiguration); workflow проверяет наличие версии в
simple-индексе и пропускает повторную публикацию.
- smoke-тест запускается из /tmp с python -P: раньше из корня репозитория
python подхватывал исходники pyfglair/ (без .so) вместо wheel
- permissions: contents: read, packages: write — встроенный GITEA_TOKEN;
PAT (scope write:package) в секрете PYPI_TOKEN остаётся fallback для
старых Gitea; имена секретов без зарезервированного префикса GITEA_
- RELEASE_HA: оба варианта авторизации и пояснение про smoke-тест