diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index a3def8d1..e06b40d1 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -7,6 +7,8 @@ on: - wheels-* tags: - 'v*' + pull_request: # REMOVE THIS BEFORE PR + branches: [master] jobs: build_wheels: @@ -21,9 +23,19 @@ jobs: os: ubuntu-24.04-arm - name: macos os: macos-13 + - name: windows-x64 + os: windows-latest + - name: windows-x32 + os: windows-latest + - name: windows-arm64 + # https://github.com/actions/partner-runner-images#available-images + os: windows-11-arm steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 + with: + # avoid leaking credentials in uploaded artifacts + persist-credentials: false - uses: actions/setup-python@v6 with: @@ -33,6 +45,8 @@ jobs: run: python -m pip install cibuildwheel~=3.1.1 - name: Build wheels + env: + CIBW_ARCHS_WINDOWS: ${{ matrix.name == 'windows-x32' && 'auto32' || 'native' }} run: python -m cibuildwheel --output-dir wheelhouse - uses: actions/upload-artifact@v4 @@ -45,7 +59,10 @@ jobs: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 + with: + # avoid leaking credentials in uploaded artifacts + persist-credentials: false - uses: actions/setup-python@v6 with: @@ -69,13 +86,30 @@ jobs: name: wheels-linux-ppc path: ./wheelhouse/*.whl + twine-check: + name: Twine check + # It is good to do this check on non-tagged commits. + # Note, pypa/gh-action-pypi-publish (see job below) does this automatically. + if: ${{ !startsWith(github.ref, 'refs/tags/v') }} + needs: [build_wheels, build_wheels_ppc] + runs-on: ubuntu-latest + + steps: + - uses: actions/download-artifact@v5 + with: + path: dist + pattern: wheels-* + merge-multiple: true + - name: check distribution files + run: pipx run twine check dist/* + pypi: if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') needs: [build_wheels, build_wheels_ppc] runs-on: ubuntu-24.04 steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@v5 with: path: dist pattern: wheels-* diff --git a/.gitignore b/.gitignore index 12c3a970..a57da364 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ /build/ /ci/ /dist/ +/wheelhouse/ /docs/_build/ /MANIFEST /venv* diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 00000000..204a201b --- /dev/null +++ b/build.ps1 @@ -0,0 +1,21 @@ +if (!(Test-Path -Path "build")) { + # in case the pygit2 package build/ workspace has not been created by cibuildwheel yet + mkdir build +} +if (Test-Path -Path "$env:LIBGIT2_SRC") { + Set-Location "$env:LIBGIT2_SRC" + # for local runs, reuse build/libgit_src if it exists + if (Test-Path -Path build) { + # purge previous build env (likely for a different arch type) + Remove-Item -Recurse -Force build + } + # ensure we are checked out to the right version + git fetch --depth=1 --tags + git checkout "v$env:LIBGIT2_VERSION" +} else { + # from a fresh run (like in CI) + git clone --depth=1 -b "v$env:LIBGIT2_VERSION" https://github.com/libgit2/libgit2.git $env:LIBGIT2_SRC + Set-Location "$env:LIBGIT2_SRC" +} +cmake -B build -S . -DBUILD_TESTS=OFF +cmake --build build/ --config=Release --target install diff --git a/pyproject.toml b/pyproject.toml index c1731053..e688d178 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,35 @@ archs = ["universal2"] environment = {LIBGIT2_VERSION="1.9.1", LIBSSH2_VERSION="1.11.1", OPENSSL_VERSION="3.3.3", LIBGIT2="/Users/runner/work/pygit2/pygit2/ci"} repair-wheel-command = "DYLD_LIBRARY_PATH=/Users/runner/work/pygit2/pygit2/ci/lib delocate-wheel --require-archs {delocate_archs} -w {dest_dir} {wheel}" +[tool.cibuildwheel.windows] +environment.LIBGIT2_SRC = "build/libgit2_src" +environment.LIBGIT2_VERSION = "1.9.1" +before-all = "powershell -File build.ps1" + +[[tool.cibuildwheel.overrides]] +select="*-win_amd64" +inherit.environment="append" +environment.CMAKE_GENERATOR = "Visual Studio 17 2022" +environment.CMAKE_GENERATOR_PLATFORM = "x64" +environment.CMAKE_INSTALL_PREFIX = "C:/libgit2_install_x86_64" +environment.LIBGIT2 = "C:/libgit2_install_x86_64" + +[[tool.cibuildwheel.overrides]] +select="*-win32" +inherit.environment="append" +environment.CMAKE_GENERATOR = "Visual Studio 17 2022" +environment.CMAKE_GENERATOR_PLATFORM = "Win32" +environment.CMAKE_INSTALL_PREFIX = "C:/libgit2_install_x86" +environment.LIBGIT2 = "C:/libgit2_install_x86" + +[[tool.cibuildwheel.overrides]] +select="*-win_arm64" +inherit.environment="append" +environment.CMAKE_GENERATOR = "Visual Studio 17 2022" +environment.CMAKE_GENERATOR_PLATFORM = "ARM64" +environment.CMAKE_INSTALL_PREFIX = "C:/libgit2_install_arm64" +environment.LIBGIT2 = "C:/libgit2_install_arm64" + [tool.ruff] extend-exclude = [ ".cache", ".coverage", "build", "site-packages", "venv*"] target-version = "py310" # oldest supported Python version diff --git a/setup.py b/setup.py index e2c62829..7e6d7034 100644 --- a/setup.py +++ b/setup.py @@ -28,6 +28,7 @@ # Import setuptools before distutils to avoid user warning import os import sys +import sysconfig from distutils import log # type: ignore[attr-defined] from distutils.command.build import build from distutils.command.sdist import sdist @@ -152,6 +153,16 @@ def run(self) -> None: cmdclass=cmdclass, cffi_modules=['pygit2/_run.py:ffi'], ext_modules=ext_modules, + options={ + 'bdist_wheel': { + # for ABI3 (future-compatible) wheels. + # NOTE: free-threaded CPython builds do not support the limited API yet. + # See https://github.com/python/cpython/issues/111506 + 'py_limited_api': False + if sysconfig.get_config_var('Py_GIL_DISABLED') + else 'cp310' # should correspond to `python_requires` below + } + }, # Requirements python_requires='>=3.10', setup_requires=['cffi>=2.0'],