Skip to content

CI: build wheels natively per arch (fix duplicate/colliding wheels; add win_arm64) - #317

Merged
alecjacobson merged 3 commits into
mainfrom
fix-wheels-arch-matrix
Sep 1, 2026
Merged

CI: build wheels natively per arch (fix duplicate/colliding wheels; add win_arm64)#317
alecjacobson merged 3 commits into
mainfrom
fix-wheels-arch-matrix

Conversation

@alecjacobson

Copy link
Copy Markdown
Contributor

The bug (diagnosed from the 2.6.3 release)

The build_wheels matrix had a cross arch: [x86_64, arm64] dimension, but only CIBW_ARCHS_MACOS: ${{ matrix.arch }} was wired to it — there was no CIBW_ARCHS_LINUX / CIBW_ARCHS_WINDOWS. So on the x86 ubuntu-24.04 and windows-latest runners, the arch: arm64 leg ignored matrix.arch and rebuilt the native x86_64 / amd64 wheel, just stored under an artifact named …-arm64-….

Confirmed from the 2.6.3 run's artifacts:

  • wheels-windows-latest-arm64-cp310/…-cp310-win_amd64.whl
  • wheels-ubuntu-24.04-arm64-cp310/…-cp310-manylinux…x86_64.whl

Consequences:

  • 10 duplicate wheels (5 manylinux-x86_64 + 5 win_amd64). During the release job's download-artifact@v4 --merge-multiple, the duplicate filenames collided and intermittently produced a truncated wheel → twine check BadZipFile → failed PyPI publish (this is what failed the 2.6.3 release twice; also the 10 × 400 Bad Request "file already exists" on the manual upload).
  • No real win_arm64 wheels were ever built (Windows-on-ARM users get nothing). Linux aarch64 was fine only because of the separate native ubuntu-24.04-arm runner.

The fix

  • Drop the broken cross-arch dimension; use one runner per native target architecture (cibuildwheel builds the runner's native arch by default). Artifact names are now unique per (os, python), so nothing collides on merge.
  • Add a native windows-11-arm leg for real win_arm64 wheels (CPython 3.11+ only). It's marked continue-on-error because embree / predicates use x86 SIMD and may not build on ARM64 yet — so if that leg fails, it won't block the release; CI will tell us whether the toolchain is ready.

Net platform coverage vs. what's actually on PyPI today: identical, plus win_arm64 (and 10 fewer redundant build jobs).

Version bump to test the pipeline

Bumps pyproject.toml to 2.6.4.dev0. Merging this to main will exercise the fixed publish pipeline end-to-end: check_version sees the bump, and (with the collisions gone) the release job should tag 2.6.4.dev0, create a pre-release GitHub Release, and upload to PyPI cleanly. .dev0 is flagged as a pre-release, so it won't become the default pip install libigl.

🤖 Generated with Claude Code

Horde and others added 3 commits September 1, 2026 02:55
…add win_arm64

The build matrix had a cross `arch: [x86_64, arm64]` dimension, but only
CIBW_ARCHS_MACOS was wired to it. On the x86 ubuntu-24.04 / windows-latest
runners the `arch: arm64` leg therefore ignored the arch and rebuilt the native
x86_64 / amd64 wheel, just under an artifact named "...-arm64-...". That caused:

- duplicate manylinux-x86_64 and win_amd64 wheels (10 of them), which collided
  during the release job's `download-artifact --merge-multiple` and intermittently
  produced a truncated wheel -> `twine check` BadZipFile -> failed PyPI publish;
- no real win_arm64 wheels ever being built.

Replace the broken cross-arch dimension with one runner per native target
architecture (cibuildwheel builds the native arch by default), and add a native
windows-11-arm leg for real win_arm64 wheels (3.11+ only; marked
continue-on-error since embree/predicates use x86 SIMD and may not build yet).
Artifact names are now unique per (os, python), so nothing collides on merge.

Bump version to 2.6.4.dev0 so merging this exercises the fixed publish pipeline
end-to-end (a pre-release upload to PyPI).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The windows-11-arm leg fails building embree: embree only enables its NEON
(sse2neon) code path when its CMake detects an ARM target, and on Windows/MSVC
ARM64 that detection falls back to SSE2 ("Detected default ISA: SSE2"), so it
compiles x86 SSE sources and MSVC's immintrin.h rejects them on ARM64. (macOS
arm64 works because embree's arm/NEON path is detected and supported there.)

Pass CMAKE_ARGS=-DLIBIGL_EMBREE=OFF only on the windows-11-arm leg so win_arm64
wheels build without the igl.embree submodule. Other platforms keep embree.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
cibuildwheel runs `pytest {project}/tests` on every wheel, and the win_arm64
wheel is built without embree (no MSVC/ARM64 embree). The unconditional
`import igl.embree` at module scope aborted collection there. Guard the import
(HAS_EMBREE) and skip test_embree / test_new_embree_algorithms when it's absent.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@alecjacobson
alecjacobson merged commit 808eb6b into main Sep 1, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant