diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 801c39c1..907d4988 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -94,3 +94,51 @@ jobs: --test_verbose_timeout_warnings \ //... working-directory: src + python: + strategy: + matrix: + runs-on: + - ubuntu-latest + # `large` is x86-64 and `xlarge` is AArch64. + - macos-latest-large + # macos-latest-xlarge may timeout. + # https://github.com/google/s2geometry/issues/409 + - macos-latest-xlarge + fail-fast: false + runs-on: ${{ matrix.runs-on }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-tags: true + persist-credentials: false + - uses: pypa/cibuildwheel@8d2b08b68458a16aeb24b64e68a09ab1c8e82084 # v3.4.1 + with: + package-dir: ./ + output-dir: dist/ + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: dist-${{ runner.os }}-${{ runner.arch }} + path: ./dist/ + python-publish: + if: (github.event_name == 'release') && (github.event.action == 'released') + needs: [python] + runs-on: ubuntu-latest + permissions: + id-token: write + attestations: write + # Requires environment protection rules in GitHub Settings: + # Settings > Environments > pypi > Add required reviewers + environment: + name: pypi + url: https://pypi.org/p/s2geometry + steps: + - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + with: + pattern: dist* + path: dist/ + merge-multiple: true + - uses: actions/attest-build-provenance@96278af6caaf10aea03fd8d33a09a777ca52d62f # v3.2.0 + with: + subject-path: "dist/*" + # To upload to PyPI without a token, add this workflow file as a Trusted Publisher in the project settings on the PyPI website + - uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f8120cb..b6a0e117 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,9 @@ cmake_minimum_required(VERSION 3.18) +# avoids error: aligned allocation function of type 'void *(std::size_t, std::align_val_t)' is only available on macOS 10.13 or newer +# see https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md#macos +set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "Minimum macOS version") + project(s2-geometry VERSION 0.12.0) diff --git a/pyproject.toml b/pyproject.toml index 5e019ca2..36278aa7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,17 +29,18 @@ content-type = "text/plain" [project.urls] Source = "https://github.com/google/s2geometry" -[project.optional-dependencies] +[dependency-groups] test = [ "pytest", + "abi3audit" ] [build-system] requires = [ - "wheel", + "cmake_build_extension", "setuptools", "setuptools_scm[toml]", - "cmake_build_extension", + "swig", ] build-backend = "setuptools.build_meta" @@ -60,3 +61,13 @@ namespaces = false # The same as the default. See #450. # https://setuptools-scm.readthedocs.io/en/latest/config/#setuptools_scm._config.DEFAULT_TAG_REGEX tag_regex = "^(?:[\\w-]+-)?(?P[vV]?\\d+(?:\\.\\d+){0,2}[^\\+]*)(?:\\+.*)?$" + +[tool.cibuildwheel] +# we only need to build with CPython 3.10 (because of the limited API / stable ABI) +build = "cp310-*" +test-groups = ["test"] +test-command = "pytest {project}/src/python/s2geometry_test.py && abi3audit --strict --report {project}/dist/*.whl" + +[tool.cibuildwheel.macos] +# skip wheel delocation (command can't find the binary) +repair-wheel-command = "" diff --git a/setup.py b/setup.py index 242882ab..e19ce643 100644 --- a/setup.py +++ b/setup.py @@ -16,16 +16,20 @@ # (it could be a subfolder) source_dir=str(Path(__file__).parent.absolute()), cmake_configure_options=[ - # This option points CMake to the right Python interpreter, and helps - # the logic of FindPython3.cmake to find the active version - f"-DPython3_ROOT_DIR={Path(sys.prefix)}", - '-DCALL_FROM_SETUP_PY:BOOL=ON', - '-DBUILD_SHARED_LIBS:BOOL=OFF', - '-DCMAKE_POSITION_INDEPENDENT_CODE=ON', - '-DWITH_PYTHON=ON' - ] - ) + # This option points CMake to the right Python interpreter, and helps + # the logic of FindPython3.cmake to find the active version + f"-DPython3_ROOT_DIR={Path(sys.prefix)}", + "-DCALL_FROM_SETUP_PY:BOOL=ON", + "-DBUILD_SHARED_LIBS:BOOL=OFF", + "-DCMAKE_POSITION_INDEPENDENT_CODE=ON", + "-DWITH_PYTHON=ON", + "-DBUILD_TESTS=OFF", + "-DFETCH_ABSEIL=ON", + "-DWITH_PYTHON_LIMITED_API=ON", + ] + ), ], + options={"bdist_wheel": {"py_limited_api": "cp310"}}, cmdclass=dict( # Enable the CMakeExtension entries defined above build_ext=cmake_build_extension.BuildExtension,