diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 97ec258..fdd10ff 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -3,56 +3,75 @@ name: samplerate on: [push, pull_request] jobs: - build: + build_wheels: + name: Build wheels on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false - max-parallel: 12 matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - python-version: [3.9, "3.10", "3.11", "3.12", "3.13", "3.14"] + include: + # Linux x86_64 + - os: ubuntu-latest + arch: x86_64 + cibw_archs: "x86_64" + # Linux ARM64 (native, no QEMU) + - os: ubuntu-24.04-arm + arch: aarch64 + cibw_archs: "aarch64" + # Windows AMD64 + - os: windows-latest + arch: AMD64 + cibw_archs: "AMD64" + # macOS x86_64 (Intel) + - os: macos-15-intel + macoosx_deployment_target: "10.15" + arch: x86_64 + cibw_archs: "x86_64" + # macOS ARM64 (Apple Silicon) + - os: macos-latest + macoosx_deployment_target: "11.0" + arch: arm64 + cibw_archs: "arm64" steps: - - uses: actions/checkout@v5 - with: - submodules: recursive - # - name: Checkout submodules - # shell: bash - # run: | - # auth_header="$(git config --local --get http.https://github.com/.extraheader)" - # git submodule sync --recursive - # git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1 - - name: Install uv - uses: astral-sh/setup-uv@v7 - - name: Sync dependencies with uv - run: | - uv sync --locked --all-groups --python ${{ matrix.python-version }} - - name: Build sdist - if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.14' - run: | - uv build --sdist - - name: Upload sdist - if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.14' - uses: actions/upload-artifact@v5 - with: - name: dist-python-samplerate-ledfx - path: dist/*.tar.gz - if-no-files-found: error - - name: Build wheel for ${{ matrix.os }} Python ${{ matrix.python-version }} - run: | - uv build --wheel - - name: Test with pytest - run: | - uv run pytest + - uses: actions/checkout@v5 + with: + submodules: recursive - - name: Upload wheel - uses: actions/upload-artifact@v5 - with: - name: dist-python-samplerate-ledfx-${{ matrix.os }}-py${{ matrix.python-version }} - path: dist/*.whl - if-no-files-found: error + - name: Build wheels + uses: pypa/cibuildwheel@v3.3.0 + env: + CIBW_BUILD: cp39-* cp310-* cp311-* cp312-* cp313-* cp314-* + CIBW_SKIP: "*-musllinux_*" + with: + extras: uv + + - uses: actions/upload-artifact@v5 + with: + name: cibw-wheels-${{ matrix.os }}-${{ matrix.arch }} + path: ./wheelhouse/*.whl + + build_sdist: + name: Build source distribution + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + with: + submodules: recursive + + - name: Install uv + uses: astral-sh/setup-uv@v7 + + - name: Build sdist + run: uv build --sdist + + - uses: actions/upload-artifact@v5 + with: + name: cibw-sdist + path: dist/*.tar.gz + if-no-files-found: error publish: - needs: build + needs: [build_wheels, build_sdist] if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') runs-on: ubuntu-latest environment: @@ -61,16 +80,18 @@ jobs: permissions: id-token: write # Required for trusted publishing steps: - - name: Install uv - uses: astral-sh/setup-uv@v7 - - name: Download all artifacts - uses: actions/download-artifact@v5 - with: - path: dist - pattern: dist-* - merge-multiple: true - - name: Display structure of downloaded files - run: ls -R dist - - name: Publish to PyPI - run: | - uv publish --trusted-publishing always + - name: Install uv + uses: astral-sh/setup-uv@v7 + + - name: Download all artifacts + uses: actions/download-artifact@v5 + with: + path: dist + pattern: cibw-* + merge-multiple: true + + - name: Display structure of downloaded files + run: ls -R dist + + - name: Publish to PyPI + run: uv publish --trusted-publishing always diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 45dbbeb..239b595 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -11,6 +11,7 @@ FetchContent_MakeAvailable(pybind11) # libsamplerate set(BUILD_TESTING OFF CACHE BOOL "Disable libsamplerate test build") +set(CMAKE_POSITION_INDEPENDENT_CODE ON) FetchContent_Declare( libsamplerate diff --git a/pyproject.toml b/pyproject.toml index e1d2155..38c9210 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ dependencies = [ ] [dependency-groups] -dev = [ +test = [ "pytest", "pytest-asyncio", "uvloop>=0.16.0; sys_platform != \"win32\"", @@ -41,3 +41,11 @@ dev = [ readme = {file = ["README.rst"]} [tool.setuptools_scm] + +[tool.cibuildwheel] +test-groups = ["test"] +test-command = "pytest {project}/tests" +build-frontend = "build[uv]" +build = ["cp38-*", "cp39-*", "cp310-*", "cp311-*", "cp312-*", "cp313-*","cp314-*"] +# Skip 32-bit builds and musllinux wheels +skip = ["*-win32", "*-manylinux_i686", "*-musllinux*"] \ No newline at end of file diff --git a/uv.lock b/uv.lock index 7d571d3..0531764 100644 --- a/uv.lock +++ b/uv.lock @@ -500,7 +500,7 @@ dependencies = [ ] [package.dev-dependencies] -dev = [ +test = [ { name = "pytest", version = "8.3.5", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, { name = "pytest", version = "8.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.9.*'" }, { name = "pytest", version = "9.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, @@ -516,7 +516,7 @@ dev = [ requires-dist = [{ name = "numpy", specifier = ">=1.7.0" }] [package.metadata.requires-dev] -dev = [ +test = [ { name = "pytest" }, { name = "pytest-asyncio" }, { name = "uvloop", marker = "sys_platform != 'win32'", specifier = ">=0.16.0" },