ha(packaging): musllinux-wheel для HA OS и статический C++-рантайм
- _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
This commit is contained in:
@@ -1,21 +1,17 @@
|
||||
# Сборка и публикация pyfglair в PyPI-реестр пакетов Gitea.
|
||||
# Запуск: Actions → Publish pyfglair → Run workflow (ручной, workflow_dispatch).
|
||||
# Запуск: Actions → Publish pyfglair → Run workflow (workflow_dispatch).
|
||||
#
|
||||
# Авторизация (любой из вариантов):
|
||||
# 1) встроенный job-токен: permissions: packages: write (Gitea ≥ 1.27 со
|
||||
# scope packages у features) — секреты не нужны;
|
||||
# 2) personal access token (scope write:package) в секрете PYPI_TOKEN —
|
||||
# для старых Gitea, где публикация пакетов job-токеном не реализована
|
||||
# (см. https://docs.gitea.com/usage/actions/comparison — "Package
|
||||
# repository authorization").
|
||||
# Секрет PYPI_USER (опционально) — имя пользователя к PAT; по умолчанию актор.
|
||||
# ВНИМАНИЕ: имена секретов не могут начинаться с GITEA_ (зарезервировано).
|
||||
# Собираются ДВА wheel (одинаковая версия):
|
||||
# * linux_x86_64 — glibc (HA Supervised/Core на Debian/Ubuntu);
|
||||
# * musllinux_X_Y — musl (HA OS: Alpine-контейнеры); собирается в
|
||||
# контейнере python:3.12-alpine. Если runner не поддерживает
|
||||
# `container:` — job build-musllinux упадёт на apk; в этом случае
|
||||
# musllinux-wheel соберите вручную (см. docs/RELEASE_HA.md §1.4).
|
||||
#
|
||||
# Примечания:
|
||||
# * actions/checkout и actions/setup-python тянутся с github.com
|
||||
# (если инстанс изолирован — замените на абсолютные URL зеркал);
|
||||
# * сборка wheel с bundled mbedtls требует доступ к github.com
|
||||
# (FetchContent); при BUNDLED=0 ставится системный libmbedtls-dev.
|
||||
# Авторизация: встроенный job-токен при `permissions: packages: write`
|
||||
# (Gitea ≥ 1.27) либо PAT write:package в секрете PYPI_TOKEN.
|
||||
# Секрет PYPI_USER — имя пользователя к PAT; имена секретов не могут
|
||||
# начинаться с GITEA_ (префикс зарезервирован).
|
||||
name: Publish pyfglair
|
||||
|
||||
on:
|
||||
@@ -31,7 +27,7 @@ permissions:
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
build-glibc:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -56,7 +52,7 @@ jobs:
|
||||
cmake --version | head -1
|
||||
g++ --version | head -1
|
||||
|
||||
- name: Build wheel + sdist
|
||||
- name: Build wheel + sdist (glibc)
|
||||
env:
|
||||
BUNDLED: ${{ inputs.bundled_mbedtls }}
|
||||
run: |
|
||||
@@ -69,50 +65,71 @@ jobs:
|
||||
python -m build
|
||||
ls -l dist
|
||||
|
||||
# Запускать из каталога без исходников: иначе python подхватывает
|
||||
# Запуск из каталога без исходников: иначе python подхватывает
|
||||
# ./pyfglair (без собранного .so) вместо установленного wheel.
|
||||
- name: Smoke test wheel
|
||||
- name: Smoke test wheel (glibc)
|
||||
run: |
|
||||
python -m venv /tmp/wheeltest
|
||||
WHEEL="$(pwd)/dist"
|
||||
/tmp/wheeltest/bin/pip install --quiet "$WHEEL"/*.whl
|
||||
cd /tmp
|
||||
/tmp/wheeltest/bin/python -P -c "import pyfglair.session as s; print('pyfglair:', s.__file__)"
|
||||
/tmp/wheeltest/bin/python -P -c "import pyfglair.session as s; print('pyfglair(glibc):', s.__file__)"
|
||||
/tmp/wheeltest/bin/python -P -c "from pyfglair import Template, Prop, convert_to_display; assert convert_to_display(Template.A, Prop.DISPLAY_TEMPERATURE, 7000) == 200"
|
||||
|
||||
- name: Publish to Gitea package registry (PyPI)
|
||||
- name: Publish glibc wheel + sdist
|
||||
env:
|
||||
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
||||
SERVER: ${{ github.server_url }}
|
||||
OWNER: ${{ github.repository_owner }}
|
||||
TOKEN: ${{ secrets.PYPI_TOKEN }}
|
||||
GITEA_JOB_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
PYPI_USER: ${{ secrets.PYPI_USER }}
|
||||
JOB_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
run: bash scripts/publish-gitea-pypi.sh
|
||||
|
||||
build-musllinux:
|
||||
runs-on: ubuntu-latest
|
||||
container: python:3.12-alpine
|
||||
steps:
|
||||
- name: Build musllinux wheel
|
||||
env:
|
||||
BUNDLED: ${{ inputs.bundled_mbedtls }}
|
||||
REPO_URL: ${{ github.server_url }}/${{ github.repository }}.git
|
||||
SHA: ${{ github.sha }}
|
||||
run: |
|
||||
TOKEN="${PYPI_TOKEN:-$JOB_TOKEN}"
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "::error::Нет токена: разрешите 'packages: write' (Gitea ≥ 1.27) или задайте секрет PYPI_TOKEN (PAT write:package)"
|
||||
apk add --no-cache git cmake ninja g++ make curl libstdc++-dev
|
||||
if [ -z "$REPO_URL" ] || [ "$REPO_URL" = "/.git" ]; then
|
||||
echo "::error::Пустой github.server_url/repository — задайте контексты или соберите musllinux вручную (docs/RELEASE_HA.md §1.4)"
|
||||
exit 1
|
||||
fi
|
||||
SERVER="${GITHUB_SERVER_URL:-}"
|
||||
if [ -z "$SERVER" ]; then
|
||||
SERVER="$(git remote get-url origin | sed -E 's#^git@([^:]+):.*#https://\1#; s#^(https?://[^/]+)/.*#\1#')"
|
||||
git clone --depth 1 "$REPO_URL" /src
|
||||
cd /src
|
||||
if [ -n "$SHA" ]; then
|
||||
git fetch --depth 1 origin "$SHA"
|
||||
git checkout --detach FETCH_HEAD
|
||||
fi
|
||||
REPO="${GITHUB_REPOSITORY:-$(git remote get-url origin | sed -E 's#.*[:/]([^/]+/[^/]+?)(\.git)?$#\1#')}"
|
||||
OWNER="${REPO%%/*}"
|
||||
GITEA_USER="${PYPI_USER:-${GITHUB_ACTOR:-git}}"
|
||||
pip install --upgrade twine
|
||||
|
||||
# twine 7 не поддерживает --skip-existing для не-PyPI репозиториев,
|
||||
# поэтому проверяем simple-индекс Gitea сами.
|
||||
VERSION="$(basename "$(ls dist/pyfglair-*.tar.gz | head -1)" | sed -E 's/^pyfglair-(.+)\.tar\.gz$/\1/')"
|
||||
INDEX="$SERVER/api/packages/$OWNER/pypi/simple/pyfglair/"
|
||||
if curl -fsS -u "$GITEA_USER:$TOKEN" "$INDEX" | grep -q "pyfglair-${VERSION}-"; then
|
||||
echo "Версия $VERSION уже опубликована — пропуск загрузки."
|
||||
exit 0
|
||||
if [ "$BUNDLED" = "0" ]; then
|
||||
export FGL_BUNDLED_MBEDTLS=0
|
||||
else
|
||||
export FGL_BUNDLED_MBEDTLS=1
|
||||
fi
|
||||
pip install --upgrade build
|
||||
python -m build --wheel
|
||||
ls -l dist
|
||||
|
||||
python -m twine upload \
|
||||
--repository-url "$SERVER/api/packages/$OWNER/pypi" \
|
||||
--username "$GITEA_USER" \
|
||||
--password "$TOKEN" \
|
||||
--non-interactive \
|
||||
dist/*
|
||||
echo "Опубликовано: $SERVER/api/packages/$OWNER/pypi/simple/pyfglair/"
|
||||
- name: Smoke test wheel (musl)
|
||||
run: |
|
||||
cd /src
|
||||
python -m venv /tmp/wheeltest
|
||||
/tmp/wheeltest/bin/pip install --quiet "$(pwd)"/dist/*.whl
|
||||
cd /tmp
|
||||
/tmp/wheeltest/bin/python -P -c "import pyfglair.session as s; print('pyfglair(musl):', s.__file__)"
|
||||
/tmp/wheeltest/bin/python -P -c "from pyfglair import Template, Prop, convert_to_display; assert convert_to_display(Template.A, Prop.DISPLAY_TEMPERATURE, 7000) == 200"
|
||||
|
||||
- name: Publish musllinux wheel
|
||||
env:
|
||||
SERVER: ${{ github.server_url }}
|
||||
OWNER: ${{ github.repository_owner }}
|
||||
TOKEN: ${{ secrets.PYPI_TOKEN }}
|
||||
GITEA_JOB_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
PYPI_USER: ${{ secrets.PYPI_USER }}
|
||||
DIST_DIR: /src/dist
|
||||
run: cd /src && bash scripts/publish-gitea-pypi.sh
|
||||
|
||||
Reference in New Issue
Block a user