From fd32c6188e27a636624f6082b7ac5cf5c1d10b48 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Mon, 1 Nov 2021 11:29:23 +0100 Subject: Add wheel building workflow for Github Actions. --- .github/workflows/wheels.yml | 149 ++++++++++++++++++++++++++++++++++++++++ Makefile | 9 +-- setup.py | 5 +- tools/manylinux/build-wheels.sh | 6 +- 4 files changed, 160 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/wheels.yml diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml new file mode 100644 index 00000000..020f3339 --- /dev/null +++ b/.github/workflows/wheels.yml @@ -0,0 +1,149 @@ +name: Wheel build + +on: + release: + types: [created] + +jobs: + sdist: + runs-on: ubuntu-20.04 + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v1 + with: + python-version: 3.9 + + - name: Install lib dependencies + run: sudo apt-get update -y -q && sudo apt-get install -y -q "libxml2=2.9.10*" "libxml2-dev=2.9.10*" libxslt1.1 libxslt1-dev + + - name: Install Python dependencies + run: python -m pip install -U pip setuptools && python -m pip install -U docutils pygments sphinx sphinx-rtd-theme -r requirements.txt + + - name: Build docs and sdist + run: make html sdist + env: { STATIC_DEPS: false } + + - name: Release + uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/') + with: + files: dist/*.tar.gz + + - name: Upload sdist + uses: actions/upload-artifact@v2 + with: + name: sdist + path: dist/*.tar.gz + + - name: Upload website + uses: actions/upload-artifact@v2 + with: + name: website + path: doc/html + + Linux: + runs-on: ubuntu-latest + + strategy: + # Allows for matrix sub-jobs to fail without canceling the rest + fail-fast: false + + matrix: + image: + - manylinux1_x86_64 + - manylinux1_i686 + - manylinux2010_x86_64 + - manylinux2010_i686 + - manylinux_2_24_x86_64 + - manylinux_2_24_i686 + - manylinux_2_24_aarch64 + - musllinux_1_1_x86_64 + #- manylinux_2_24_ppc64le + #- manylinux_2_24_ppc64le + #- manylinux_2_24_s390x + pyversion: ["*"] + + exclude: + - image: manylinux_2_24_aarch64 + pyversion: "*" + include: + - image: manylinux_2_24_aarch64 + pyversion: "cp37*" + - image: manylinux_2_24_aarch64 + pyversion: "cp38*" + - image: manylinux_2_24_aarch64 + pyversion: "cp39*" + - image: manylinux_2_24_aarch64 + pyversion: "cp310*" + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v1 + with: + python-version: 3.8 + + - name: Install dependencies + run: python -m pip install -r requirements.txt + + - name: Build Linux wheels + run: make sdist wheel_${{ matrix.image }} + env: { STATIC_DEPS: true, PYTHON_BUILD_VERSION: "${{ matrix.pyversion }}" } + + - name: Release + uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/') + with: + files: wheelhouse*/lxml-*.whl + + - name: Upload wheels + uses: actions/upload-artifact@v2 + with: + name: wheels-${{ matrix.image }} + path: wheelhouse*/*-m*linux*.whl # manylinux / musllinux + if-no-files-found: ignore + + non-Linux: + strategy: + # Allows for matrix sub-jobs to fail without canceling the rest + fail-fast: false + + matrix: + #os: [macos-10.15, windows-latest] + os: [macos-10.15] + python_version: ["2.7", "3.6", "3.7", "3.8", "3.9", "3.10"] + + runs-on: ${{ matrix.os }} + env: { LIBXML2_VERSION: 2.9.10, LIBXSLT_VERSION: 1.1.34, MACOSX_DEPLOYMENT_TARGET: 10.14 } + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v1 + with: + python-version: ${{ matrix.python_version }} + + - name: Install dependencies + run: python -m pip install setuptools wheel -r requirements.txt + + - name: Build wheels + run: make sdist wheel + env: { STATIC_DEPS: true, RUN_TESTS: true } + + - name: Release + uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/') + with: + files: dist/lxml-*.whl + + - name: Upload wheels + uses: actions/upload-artifact@v2 + with: + name: wheels-${{ matrix.os }} + path: dist/lxml-*.whl + if-no-files-found: ignore diff --git a/Makefile b/Makefile index f9e698e9..555d851e 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ PYTHON3?=python3 TESTFLAGS=-p -v TESTOPTS= SETUPFLAGS= -LXMLVERSION:=$(shell sed -ne '/__version__/s|.*__version__\s*=\s*"\([^"]*\)".*|\1|p' src/lxml/__init__.py) +LXMLVERSION:=$(shell $(PYTHON3) -c 'import re; print(re.findall(r"__version__\s*=\s*\"([^\"]+)\"", open("src/lxml/__init__.py").read())[0])' ) PARALLEL?=$(shell $(PYTHON) -c 'import sys; print("-j7" if sys.version_info >= (3, 5) else "")' ) PARALLEL3?=$(shell $(PYTHON3) -c 'import sys; print("-j7" if sys.version_info >= (3, 5) else "")' ) @@ -12,6 +12,7 @@ PY3_WITH_CYTHON?=$(shell $(PYTHON3) -c 'import Cython.Build.Dependencies' >/dev/ CYTHON_WITH_COVERAGE?=$(shell $(PYTHON) -c 'import Cython.Coverage; import sys; assert not hasattr(sys, "pypy_version_info")' >/dev/null 2>/dev/null && echo " --coverage" || true) CYTHON3_WITH_COVERAGE?=$(shell $(PYTHON3) -c 'import Cython.Coverage; import sys; assert not hasattr(sys, "pypy_version_info")' >/dev/null 2>/dev/null && echo " --coverage" || true) +PYTHON_BUILD_VERSION ?= * MANYLINUX_LIBXML2_VERSION=2.9.10 MANYLINUX_LIBXSLT_VERSION=1.1.34 MANYLINUX_CFLAGS=-O3 -g1 -pipe -fPIC -flto @@ -27,10 +28,6 @@ MANYLINUX_IMAGES= \ manylinux_2_24_s390x \ musllinux_1_1_x86_64 -AARCH64_ENV=-e AR="/opt/rh/devtoolset-9/root/usr/bin/gcc-ar" \ - -e NM="/opt/rh/devtoolset-9/root/usr/bin/gcc-nm" \ - -e RANLIB="/opt/rh/devtoolset-9/root/usr/bin/gcc-ranlib" - .PHONY: all inplace inplace3 rebuild-sdist sdist build require-cython wheel_manylinux wheel all: inplace @@ -75,8 +72,8 @@ wheel_%: dist/lxml-$(LXMLVERSION).tar.gz -e LDFLAGS="$(MANYLINUX_LDFLAGS)" \ -e LIBXML2_VERSION="$(MANYLINUX_LIBXML2_VERSION)" \ -e LIBXSLT_VERSION="$(MANYLINUX_LIBXSLT_VERSION)" \ + -e PYTHON_BUILD_VERSION="$(PYTHON_BUILD_VERSION)" \ -e WHEELHOUSE=$(subst wheel_,wheelhouse/,$@) \ - $(if $(patsubst %aarch64,,$@),,$(AARCH64_ENV)) \ quay.io/pypa/$(subst wheel_,,$@) \ bash /io/tools/manylinux/build-wheels.sh /io/$< diff --git a/setup.py b/setup.py index 3fdf6705..930d9632 100644 --- a/setup.py +++ b/setup.py @@ -253,4 +253,7 @@ an appropriate version of Cython installed. if OPTION_RUN_TESTS: print("Running tests.") import test - sys.exit( test.main(sys.argv[:1]) ) + try: + sys.exit( test.main(sys.argv[:1]) ) + except ImportError: + pass # we assume that the binaries were not built with this setup.py run diff --git a/tools/manylinux/build-wheels.sh b/tools/manylinux/build-wheels.sh index 65d76029..3431df47 100755 --- a/tools/manylinux/build-wheels.sh +++ b/tools/manylinux/build-wheels.sh @@ -9,6 +9,7 @@ REQUIREMENTS=/io/requirements.txt SDIST=$1 PACKAGE=$(basename ${SDIST%-*}) SDIST_PREFIX=$(basename ${SDIST%%.tar.gz}) +[ -z "$PYTHON_BUILD_VERSION" ] && PYTHON_BUILD_VERSION="*" build_wheel() { pybin="$1" @@ -16,6 +17,7 @@ build_wheel() { [ -n "$source" ] || source=/io env STATIC_DEPS=true \ + RUN_TESTS=true \ LDFLAGS="$LDFLAGS -fPIC" \ CFLAGS="$CFLAGS -fPIC" \ ${pybin}/pip \ @@ -26,7 +28,7 @@ build_wheel() { run_tests() { # Install packages and test - for PYBIN in /opt/python/*/bin/; do + for PYBIN in /opt/python/${PYTHON_BUILD_VERSION}/bin/; do ${PYBIN}/python -m pip install $PACKAGE --no-index -f /io/$WHEELHOUSE || exit 1 # check import as a quick test @@ -47,7 +49,7 @@ build_wheels() { FIRST= SECOND= THIRD= - for PYBIN in /opt/python/*/bin; do + for PYBIN in /opt/python/${PYTHON_BUILD_VERSION}/bin; do # Install build requirements if we need them and file exists test -n "$source" -o ! -e "$REQUIREMENTS" \ || ${PYBIN}/python -m pip install -r "$REQUIREMENTS" -- cgit v1.2.1