Skip to content

feat: build and test on native arm64 runners - #176

Merged
PyYoshi merged 4 commits into
masterfrom
feat/native-arm64-runners
Oct 5, 2026
Merged

PyYoshi merged 4 commits into
masterfrom
feat/native-arm64-runners

Conversation

@PyYoshi

@PyYoshi PyYoshi commented Oct 5, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • pin GitHub-hosted runners to the newest generally available images instead of the moving <os>-latest labels: ubuntu-26.04, windows-2025, and macos-26
  • add native arm64 runners, ubuntu-26.04-arm and windows-11-arm, to both the test matrix and the wheel matrix
  • build Linux aarch64 wheels natively and drop the QEMU setup step
  • publish Windows ARM64 (win_arm64) wheels for the first time
  • name wheel artifacts after matrix.os so the two Linux and two Windows jobs do not collide; the publish job still downloads them with pattern: "*"

On windows-11-arm, uv resolved plain version requests such as 3.15t to emulated x86-64 interpreters. The first CI run therefore tested x86-64 rather than ARM64 there, and Python 3.15t / windows-11-arm failed while building nh3 for x86-64 with the runner's ARM64 Rust toolchain. The test job now requests cpython-<version>-windows-aarch64-none on that runner, and a new Check interpreter architecture step on every runner asserts that the interpreter architecture matches RUNNER_ARCH. The step uses sysconfig.get_platform(), except for the python.org universal2 interpreters on macOS runners, where it checks platform.machine() of the running process instead. The wheel jobs were unaffected because cibuildwheel uses the native pythonarm64 packages and the HostARM64\ARM64 MSVC toolchain.

With the [tool.cibuildwheel.linux] override removed, archs = "auto" selects only the native architecture of each runner:

Runner Wheels
ubuntu-26.04 manylinux x86_64
ubuntu-26.04-arm manylinux aarch64
windows-2025 win_amd64, win32
windows-11-arm win_arm64
macos-26 (Apple silicon) arm64, x86_64 (cross-built and tested under Rosetta, unchanged)

All standard GitHub-hosted runners, including the arm64 ones, are free and unlimited for public repositories.

Merge notes

  • Required status checks: the Protect master ruleset now requires the new job names. The policy is unchanged: Python 3.11–3.14 on every runner (now including the arm64 ones), plus Native ASan / UBSan, Verify distributions, and the five Wheels / <runner> jobs, for 27 checks in total.
  • Rebased onto master after feat: support Python 3.15 #175: the matrices keep Python 3.15 and 3.15t, so CI now also covers cp315/cp315t on arm64 Linux and Windows. The CHANGES.md entries share the existing Unreleased section. The README "Support Platforms" list now includes Windows ARM64.

Validation

  • the uchardet ASan/UBSan build and all 153 ctest cases pass in an ubuntu:26.04 container (GCC 15.2), which matches the new Native ASan / UBSan runner
  • cibuildwheel 4.3.0 selects cp311–cp315t win_arm64 identifiers with --archs ARM64, and its auto selection is native-only (plus x86 on Windows AMD64)
  • uv provides CPython 3.11–3.15, including the free-threaded builds, for Linux and Windows aarch64
  • the Ubuntu 26.04 (x64 and arm64), Windows 11 arm64, and macOS 26 images include the Rust toolchain, and Ubuntu also has libssl-dev. CI needs these when it builds dev dependencies that ship no free-threaded wheels.
  • actionlint reports only that ubuntu-26.04 and ubuntu-26.04-arm are unknown labels, because its built-in label list predates them
  • uv lock --check passes
  • after the rebase, cibuildwheel selects cp311–cp315t for both manylinux_aarch64 and win_arm64

References

Replace the moving <os>-latest labels with the newest generally available
images (Ubuntu 26.04, Windows Server 2025, and macOS 26) so runner
upgrades happen deliberately.
Add Ubuntu 26.04 arm64 and Windows 11 arm64 runners to the test and wheel
matrices. Linux aarch64 wheels are now built natively instead of under
QEMU, and Windows ARM64 wheels are published for the first time. macOS
already runs on Apple silicon and keeps building both x86_64 and arm64
wheels.

Name wheel artifacts after the runner label so the two Linux and two
Windows jobs do not collide.
@PyYoshi
PyYoshi force-pushed the feat/native-arm64-runners branch from eb0f833 to a2a59f2 Compare October 5, 2026 12:18
uv resolved the matrix versions to emulated x86-64 interpreters on the
windows-11-arm runner, so those jobs never exercised ARM64 and the
free-threaded 3.15 job failed while building an x86-64 dependency with
the ARM64 Rust toolchain. Request the aarch64 build explicitly there, and
check on every runner that the interpreter architecture matches the
runner.
macOS runners provide python.org universal2 interpreters, whose
sysconfig platform names neither architecture alone. Check the running
process architecture for those builds instead.
@PyYoshi
PyYoshi merged commit 670397d into master Oct 5, 2026
44 checks passed
@PyYoshi
PyYoshi deleted the feat/native-arm64-runners branch October 5, 2026 12:45
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