Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add wheel building and deployment via GitHub Actions and cibuildwheel #601

Merged
merged 13 commits into from Oct 24, 2021

Conversation

grlee77
Copy link
Contributor

@grlee77 grlee77 commented Oct 6, 2021

This PR is adapted from scikit-image/scikit-image#5397.

Apparently we had added pyproject.toml here long ago and then removed it due to some issues with pip at that time. This PR reintroduces it so that the correct NumPy version will be used during these builds (it is based on SciPy's, but without the Pythran or Pybind11 requirements).

This also has automated deployment when pushing a version tag. If the automated deploy fails, we can still retrieve the wheels from the artifacts.

comment out the deployment steps for now while testing

add missing dependency installs
comment out pip install of cython. should get picked up from pyproject.toml

comment out CPython 3.10 build on Windows and MacOS
@grlee77 grlee77 added the build label Oct 6, 2021
@grlee77
Copy link
Contributor Author

grlee77 commented Oct 6, 2021

there are a lot of unrelated test failures related to coverage that I will have to take a look at.

The status of the wheel builds can be seen in my fork

@grlee77
Copy link
Contributor Author

grlee77 commented Oct 6, 2021

Could use feedback on which manylinux we should be using (many cases are still manylinux1).

Copy link
Member

@rgommers rgommers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @grlee77, this looks great! Happy to copy this approach and drop MacPython.

+1 for copying SciPy's pyproject.toml approach rather than using oldest-supported-numpy. It's slightly more work, but allows to use higher minimum numpy versions and thereby possible avoiding some C API/ABI issues.

Could use feedback on which manylinux we should be using (many cases are still manylinux1).

We can go manylinux2014-only soon, numpy has dropped the rest in its main branch already. But we'd rather not be the first ones to actually do this probably, so can be left to a separate PR after numpy et al. have done it.

# we specify an unpinned NumPy which allows source distributions
# to be used and allows wheels to be used as soon as they
# become available.
"numpy; python_version>='3.10'",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add 3.10 now, or leave that to a quick follow-up PR? We need 3.10 wheels, forgot about those till this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having a look at this now.

.github/workflows/wheel_tests_and_release.yml Outdated Show resolved Hide resolved
.github/workflows/wheel_tests_and_release.yml Show resolved Hide resolved
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
with:
platforms: arm64
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reminds me: we're going to need macOS arm64 too soon. Best to leave for a separate PR. Although would be good to check that it's possible with cibuildwheel or in the works (the multibuild support is available now).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like macOS arm64 should be possible for Python 3.8, 3.9 and 3.10: https://github.com/pypa/cibuildwheel#what-does-it-do

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added universal2 and arm64 wheels on MacOS and it succeeded (see: https://github.com/grlee77/pywt/actions/runs/1334259199). Do you recommend providing the universal2 wheels in addition to the separate x86_64 and arm64 ones?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, universal2 is useful I think, since it's the default for the Python.org installers and because it's the best wheel to grab if you don't know beforehand what you need.

- cibuildwheel
tags:
- 'v*'
- 'buildwheels*'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this for? There seems to be no guard for this kind of tag anywhere, so does it upload a release for them to PyPI without a normal version number?

Same question for the cibuildwheel branch name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove the cibuildwheel branch condition before merging. That was just to make it run everytime I push an update while testing.

Pushing a buildwheels* tag should not trigger deployment. I think the following conditions requires the tag start with v. I assume the repository_owner check is to prevent it running on forks.

  deploy:
    name: Release
    needs: [build_linux_37_and_above_wheels, build_macos_wheels, build_windows_wheels]
    if: github.repository_owner == 'PyWavelets' && startsWith(github.ref, 'refs/tags/v') && always()

I think the needs section ensures that it only gets run if the wheel builds all succeeded.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be removed in a follow-up PR, it's harmless to have in here.

@rgommers rgommers added this to the v1.2 milestone Oct 6, 2021
@rgommers
Copy link
Member

rgommers commented Oct 6, 2021

These jobs are crazy slow:

image

Looks like they're all using QEMU instead of only the arm64 job - I hope that is not on purpose?

@grlee77
Copy link
Contributor Author

grlee77 commented Oct 6, 2021

Looks like they're all using QEMU instead of only the arm64 job - I hope that is not on purpose?

It seems to be just running tests on aarch64 that is taking 80-90% of the time.

Example for x86_64

 Building cp39-manylinux_x86_64 wheel
CPython 3.9 manylinux x86_64

Setting up build environment...
                                                              ✓ 0.11s
Building wheel...
                                                             ✓ 54.20s
Repairing wheel...
                                                              ✓ 1.49s
Testing wheel...
                                                             ✓ 96.92s

but for aarch64


Building cp39-manylinux_aarch64 wheel
CPython 3.9 manylinux aarch64

Setting up build environment...
                                                              ✓ 1.09s
Building wheel...
                                                            ✓ 644.47s
Repairing wheel...
                                                             ✓ 10.83s
Testing wheel...
                                                           ✓ 3253.64s

For some reason on Python 3.10 the aarch64 tests took even longer (2.5 hours!)

@grlee77
Copy link
Contributor Author

grlee77 commented Oct 6, 2021

Those 4 linux jobs in the screenshot are divided among Python versions. But each version runs on three architextures (x86_64, i686 and aarch64). It is mainly the aarch64 one that is taking a long time.

Perhaps we can conditionally skip running the full test suite on aarch64 and just run a simple test script checking the package import and a few simple calls.

@rgommers
Copy link
Member

rgommers commented Oct 6, 2021

each version runs on three architextures (x86_64, i686 and aarch64). It is mainly the aarch64 one that is taking a long time.

Ah that makes sense.

Perhaps we can conditionally skip running the full test suite on aarch64 and just run a simple test script checking the package import and a few simple calls.

If it's just once per release, then it's not a problem. But if it runs more often, I agree we should skip it by default.

@grlee77
Copy link
Contributor Author

grlee77 commented Oct 6, 2021

If it's just once per release, then it's not a problem. But if it runs more often, I agree we should skip it by default.

Yeah, it is just for releases (or if we push a buildwheel tag to test things). Let's just leave it as-is. IIRC, the timeout is 5 or 6 hours, so we are still not too close to that.

@@ -20,7 +20,7 @@ jobs:
# Ensure that a wheel builder finishes even if another fails
fail-fast: false
matrix:
python-version: [3.7, 3.8, 3.9]
python-version: [3.7, 3.8, 3.9, 3.10]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be "3.10" (with quotes). Now it causes:

Version 3.1 was not found in the local cache
Error: Version 3.1 with arch x64 not found

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I fixed that, but then ran into a problem with pip trying to install Matplotlib on OS X with 3.10. I assume that will resolve itself once Matplotlib makes a release with python 3.10 wheels. I should perhaps remove the addition of Python 3.10 tests.yml from this PR and leave that to a follow-up.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separating out the Python 3.10 support sounds good. We can leave Matplotlib out for 3.10 probably - we don't need it to make a release.

3.10 was interpreted as 3.1 and failed
will added it to both tests and wheel building in a separate PR
@grlee77
Copy link
Contributor Author

grlee77 commented Oct 24, 2021

This is probably ready to go unless you want me to modify which wheels get built on macOS. I think some other projects are shipping only the universal2 wheels, so do we want to do the same?

I removed 3.10 from this PR and will and it in a follow-up.

@rgommers
Copy link
Member

This is probably ready to go unless you want me to modify which wheels get built on macOS. I think some other projects are shipping only the universal2 wheels, so do we want to do the same?

I think thin wheels are good to have, they are smaller and therefore should be preferred over universal2 in the long run. The choice for universal2 in Python packaging was mostly out of convenience (less changes to make because the old universal support was already present), but from a technical perspective it doesn't make too much sense to almost double the size of wheels for some convenience.

Copy link
Member

@rgommers rgommers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, let's give this a go. Thanks a lot @grlee77!

@rgommers rgommers merged commit 2c3910f into PyWavelets:master Oct 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants