Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .audit/oberstet_fix_1940.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
- [ ] I did **not** use any AI-assistance tools to help create this pull request.
- [x] I **did** use AI-assistance tools to *help* create this pull request.
- [x] I have read, understood and followed the project's AI_POLICY.md when creating code, documentation etc. for this pull request.

Submitted by: @oberstet
Date: 2026-10-18
Related issue(s): #1940
Branch: oberstet:fix_1940
2 changes: 1 addition & 1 deletion .github/scripts/build-arm64-wheel.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash
# Build ARM64 wheels inside Docker container with QEMU emulation
# Build ARM64 wheels inside Docker container on a native ARM64 runner (#1940)
# This script runs INSIDE the manylinux ARM64 container
set -ex

Expand Down
70 changes: 25 additions & 45 deletions .github/workflows/wheels-arm64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ jobs:
# IMPORTANT: we still need .cicd as a Git submodule in the using repo though!
# because e.g. identifiers.yml wants to access scripts/sanitize.sh !

# Built natively on GitHub-hosted ARM64 runners, not under QEMU on x86_64 (#1940):
# under emulation builds segfaulted intermittently (PyPy exit 139) and took up
# to 96 minutes. Same switch as zlmdb #183.
build-wheels:
name: Build ARM64 wheels (${{ matrix.target.name }})
needs: identifiers
runs-on: ubuntu-latest
runs-on: ubuntu-24.04-arm

env:
BASE_REPO: ${{ needs.identifiers.outputs.base_repo }}
Expand Down Expand Up @@ -158,47 +161,29 @@ jobs:
with:
submodules: recursive

# ============================================================
# QEMU + Docker Buildx Setup
# ============================================================

- name: Install modern QEMU (tonistiigi/binfmt)
- name: Verify the runner is native ARM64
run: |
echo "==> Installing modern QEMU 8.x via tonistiigi/binfmt"
echo "This provides much better stability for PyPy on ARM64 emulation"
docker run --rm --privileged tonistiigi/binfmt --install all
echo "✅ Modern QEMU installed"

- name: Set up QEMU for ARM64 emulation
uses: docker/setup-qemu-action@v3
with:
platforms: linux/arm64
echo "==> Runner architecture: $(uname -m)"
test "$(uname -m)" = "aarch64" || { echo "ERROR: expected a native aarch64 runner (#1940)"; exit 1; }

# Buildx builds the custom PyPy images below (natively, no emulation)
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Verify QEMU setup
run: |
echo "==> QEMU platforms available:"
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
docker buildx ls

# ============================================================
# Build custom PyPy images (only for build_type == custom)
# ============================================================

- name: Build custom PyPy manylinux image (with retry for QEMU flakiness)
- name: Build custom PyPy manylinux image (with retry)
if: matrix.target.build_type == 'custom'
uses: nick-fields/retry@v3
with:
# NVX (CFFI/flatc) AND autobahn's Rust base deps (cbor2 6.x, cryptography)
# all source-compile under QEMU ARM64 emulation — none ship a PyPy-aarch64
# wheel, so pip builds them from source, which is pathologically slow under
# emulation (a full run can exceed 60 min). Generous limits here are the
# interim, low-risk mitigation until we move ARM64 builds to native
# ubuntu-24.04-arm runners (removes emulation entirely). See #1947 and #1940.
timeout_minutes: 120
max_attempts: 9
# Under QEMU these builds took up to 96 minutes and segfaulted
# intermittently, hence 9 attempts of 120 minutes (#1947). Natively,
# keep the retry wrapper (as zlmdb #183) until native runs have been
# measured; then reduce (#1940). A timeout is not retried (retry_on: error).
timeout_minutes: 60
max_attempts: 3
retry_on: error
warning_on_retry: true
command: |
Expand All @@ -217,17 +202,15 @@ jobs:
# Build wheels inside ARM64 containers
# ============================================================

- name: Build ARM64 wheels with NVX extension (with retry for QEMU flakiness)
- name: Build ARM64 wheels with NVX extension (with retry)
uses: nick-fields/retry@v3
with:
# NVX (CFFI/flatc) AND autobahn's Rust base deps (cbor2 6.x, cryptography)
# all source-compile under QEMU ARM64 emulation — none ship a PyPy-aarch64
# wheel, so pip builds them from source, which is pathologically slow under
# emulation (a full run can exceed 60 min). Generous limits here are the
# interim, low-risk mitigation until we move ARM64 builds to native
# ubuntu-24.04-arm runners (removes emulation entirely). See #1947 and #1940.
timeout_minutes: 120
max_attempts: 9
# Under QEMU these builds took up to 96 minutes and segfaulted
# intermittently, hence 9 attempts of 120 minutes (#1947). Natively,
# keep the retry wrapper (as zlmdb #183) until native runs have been
# measured; then reduce (#1940). A timeout is not retried (retry_on: error).
timeout_minutes: 60
max_attempts: 3
retry_on: error
warning_on_retry: true
command: |
Expand All @@ -248,7 +231,8 @@ jobs:
# Create wheelhouse directory on host
mkdir -p wheelhouse

# Run build script inside ARM64 container via QEMU
# Run build script inside the ARM64 container (natively; the
# platform flag only asserts the image architecture)
docker run --rm \
--platform linux/arm64 \
-v $PWD:/io \
Expand Down Expand Up @@ -462,7 +446,7 @@ jobs:
echo "Platform Tag: ${{ matrix.target.manylinux_tag }}" >> $BUILD_INFO
echo "glibc Version: ${{ matrix.target.glibc_version }}" >> $BUILD_INFO
echo "Python Implementation: ${{ matrix.target.python_impl }}" >> $BUILD_INFO
echo "Build Method: GitHub Actions + QEMU + Docker (ARM64 emulation)" >> $BUILD_INFO
echo "Build Method: GitHub Actions native ARM64 runner (ubuntu-24.04-arm) + Docker" >> $BUILD_INFO
echo "NVX Acceleration: ENABLED (binary wheels with native extensions)" >> $BUILD_INFO
echo "" >> $BUILD_INFO

Expand All @@ -472,10 +456,6 @@ jobs:
echo "- $(basename "$whl")" >> $BUILD_INFO
done

echo "" >> $BUILD_INFO
echo "Note: These wheels were built using QEMU emulation on x86_64 runners." >> $BUILD_INFO
echo " They are fully functional native ARM64 binaries." >> $BUILD_INFO

echo ""
echo "==> Generated build-info.txt:"
cat $BUILD_INFO
Expand Down
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Changelog
* Run the unit tests (Twisted/trial and asyncio/pytest) in CI on every supported Python: CPython 3.11–3.14 and PyPy 3.11, instead of on CPython 3.14 only, and with all four compression extensions installed (``python-snappy`` is added to the ``dev`` extra; ``just check-compressors`` verifies all four are available) (#1986)
* Adopt the contribution workflow shared by all WAMP projects: ``CONTRIBUTING.md``, the pull request template and ``.audit/README.md`` are now deployed byte-identically from wamp-cicd (GitHub issue first, red → green tests, AI-assistance disclosure) and kept in sync by a CI drift check; everything specific to Autobahn|Python moved to a new ``DEVELOPMENT.md`` (also included in the docs). ``.cicd`` is pinned to wamp-cicd ``38ded6a``, the same commit across the WAMP fleet (#1956)
* Remove the opt-in entropy depletion tests (``autobahn/test/test_rng.py``, enabled by ``AUTOBAHN_CI_ENABLE_RNG_DEPLETION_TESTS``, never run in CI): they read ``/proc/sys/kernel/random/entropy_avail``, which has been a constant 256 since Linux 5.18, and ``/dev/random`` no longer blocks since Linux 5.6, so one test passed whatever happened and the other always failed (#1278)
* Build the ARM64 Linux wheels natively on GitHub's ``ubuntu-24.04-arm`` runners instead of under QEMU emulation on x86_64 runners, as zlmdb does since #183. Under emulation the builds took around 40 minutes (up to 96) and segfaulted intermittently, so each build had 9 attempts of 120 minutes; the same container images and build script are used, and a build attempt now gets 60 minutes and 3 tries (#1940)
* Add an ``import-smoke-lowest`` CI job (``just test-imports-lowest``) that runs the import smoke test on CPython 3.11 with every direct dependency resolved to the lowest version ``pyproject.toml`` allows (``uv --resolution lowest-direct``), so stale version floors are caught. The import smoke test now also covers the Twisted and asyncio bindings, each module imported in a fresh interpreter (#1955)

**asyncio**
Expand Down
Loading