Use uv to build manylinux wheels #1148
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Wheel Builder | |
permissions: | |
contents: read | |
on: | |
workflow_dispatch: | |
inputs: | |
version: | |
description: The version to build | |
# Do not add any non-tag push events without updating pypi-publish.yml. If | |
# you do, it'll upload wheels to PyPI. | |
push: | |
tags: | |
- '*.*' | |
- '*.*.*' | |
pull_request: | |
paths: | |
- .github/workflows/wheel-builder.yml | |
- .github/requirements/** | |
- pyproject.toml | |
- vectors/pyproject.toml | |
env: | |
BUILD_REQUIREMENTS_PATH: .github/requirements/build-requirements.txt | |
UV_REQUIREMENTS_PATH: .github/requirements/uv-requirements.txt | |
jobs: | |
sdist: | |
runs-on: ubuntu-latest | |
name: sdists | |
steps: | |
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 | |
with: | |
# The tag to build or the tag received by the tag event | |
ref: ${{ github.event.inputs.version || github.ref }} | |
persist-credentials: false | |
- run: python -m pip install -r $UV_REQUIREMENTS_PATH | |
- name: Make sdist (cryptography) | |
run: uv build --build-constraint=$BUILD_REQUIREMENTS_PATH --require-hashes --sdist | |
- name: Make sdist and wheel (vectors) | |
run: uv build --build-constraint=$BUILD_REQUIREMENTS_PATH --require-hashes vectors/ | |
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 | |
with: | |
name: "cryptography-sdist" | |
path: dist/cryptography* | |
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 | |
with: | |
name: "vectors-sdist-wheel" | |
path: vectors/dist/cryptography* | |
manylinux: | |
needs: [sdist] | |
runs-on: ${{ matrix.MANYLINUX.RUNNER }} | |
container: | |
image: ghcr.io/pyca/${{ matrix.MANYLINUX.CONTAINER }} | |
volumes: | |
- /staticnodehost:/staticnodecontainer:rw,rshared | |
- /staticnodehost:/__e/node20:ro,rshared | |
strategy: | |
fail-fast: false | |
matrix: | |
PYTHON: | |
- { VERSION: "cp311-cp311", ABI_VERSION: 'py37' } | |
- { VERSION: "cp311-cp311", ABI_VERSION: 'py39' } | |
- { VERSION: "pp310-pypy310_pp73" } | |
MANYLINUX: | |
- { NAME: "manylinux2014_x86_64", CONTAINER: "cryptography-manylinux2014:x86_64", RUNNER: "ubuntu-latest" } | |
- { NAME: "manylinux_2_28_x86_64", CONTAINER: "cryptography-manylinux_2_28:x86_64", RUNNER: "ubuntu-latest"} | |
- { NAME: "musllinux_1_2_x86_64", CONTAINER: "cryptography-musllinux_1_2:x86_64", RUNNER: "ubuntu-latest"} | |
- { NAME: "manylinux2014_aarch64", CONTAINER: "cryptography-manylinux2014_aarch64", RUNNER: [self-hosted, Linux, ARM64] } | |
- { NAME: "manylinux_2_28_aarch64", CONTAINER: "cryptography-manylinux_2_28:aarch64", RUNNER: [self-hosted, Linux, ARM64]} | |
- { NAME: "musllinux_1_2_aarch64", CONTAINER: "cryptography-musllinux_1_2:aarch64", RUNNER: [self-hosted, Linux, ARM64]} | |
exclude: | |
# There are no readily available musllinux PyPy distributions | |
- PYTHON: { VERSION: "pp310-pypy310_pp73" } | |
MANYLINUX: { NAME: "musllinux_1_2_x86_64", CONTAINER: "cryptography-musllinux_1_2:x86_64", RUNNER: "ubuntu-latest"} | |
- PYTHON: { VERSION: "pp310-pypy310_pp73" } | |
MANYLINUX: { NAME: "musllinux_1_2_aarch64", CONTAINER: "cryptography-musllinux_1_2:aarch64", RUNNER: [self-hosted, Linux, ARM64]} | |
# We also don't build pypy wheels for anything except the latest manylinux | |
- PYTHON: { VERSION: "pp310-pypy310_pp73" } | |
MANYLINUX: { NAME: "manylinux2014_x86_64", CONTAINER: "cryptography-manylinux2014:x86_64", RUNNER: "ubuntu-latest"} | |
- PYTHON: { VERSION: "pp310-pypy310_pp73" } | |
MANYLINUX: { NAME: "manylinux2014_aarch64", CONTAINER: "cryptography-manylinux2014_aarch64", RUNNER: [self-hosted, Linux, ARM64]} | |
name: "${{ matrix.PYTHON.VERSION }} for ${{ matrix.MANYLINUX.NAME }}" | |
steps: | |
- name: Ridiculous-er workaround for static node20 | |
run: | | |
cp -R /staticnode/* /staticnodecontainer/ | |
- name: Ridiculous alpine workaround for actions support on arm64 | |
run: | | |
# This modifies /etc/os-release so the JS actions | |
# from GH can't detect that it's on alpine:aarch64. It will | |
# then use a glibc nodejs, which works fine when gcompat | |
# is installed in the container (which it is) | |
sed -i "s:ID=alpine:ID=NotpineForGHA:" /etc/os-release | |
if: startsWith(matrix.MANYLINUX.NAME, 'musllinux') && endsWith(matrix.MANYLINUX.NAME, 'aarch64') | |
- name: Get build-requirements.txt from repository | |
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 | |
with: | |
# The tag to build or the tag received by the tag event | |
ref: ${{ github.event.inputs.version || github.ref }} | |
persist-credentials: false | |
sparse-checkout: | | |
${{ env.BUILD_REQUIREMENTS_PATH }} | |
sparse-checkout-cone-mode: false | |
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 | |
with: | |
name: cryptography-sdist | |
- run: mkdir tmpwheelhouse | |
- name: Build the wheel | |
run: | | |
if [ -n "${{ matrix.PYTHON.ABI_VERSION }}" ]; then | |
PY_LIMITED_API="--config-settings=build-args=--features=pyo3/abi3-${{ matrix.PYTHON.ABI_VERSION }}" | |
fi | |
OPENSSL_DIR="/opt/pyca/cryptography/openssl" \ | |
OPENSSL_STATIC=1 \ | |
uv build --python=/opt/python/${{ matrix.PYTHON.VERSION }}/bin/python --wheel --require-hashes --build-constraint=$BUILD_REQUIREMENTS_PATH $PY_LIMITED_API cryptography*.tar.gz -o tmpwheelhouse/ | |
env: | |
RUSTUP_HOME: /root/.rustup | |
- run: auditwheel repair --plat ${{ matrix.MANYLINUX.NAME }} tmpwheelhouse/cryptography*.whl -w wheelhouse/ | |
- run: unzip wheelhouse/*.whl -d execstack.check | |
- run: | | |
results=$(readelf -lW execstack.check/cryptography/hazmat/bindings/*.so) | |
count=$(echo "$results" | grep -c 'GNU_STACK.*[R ][W ]E' || true) | |
if [ "$count" -ne 0 ]; then | |
exit 1 | |
else | |
exit 0 | |
fi | |
- run: uv venv --python=/opt/python/${{ matrix.PYTHON.VERSION }}/bin/python | |
- run: uv pip install --require-hashes -r $BUILD_REQUIREMENTS_PATH | |
- run: uv pip install cryptography --no-index -f wheelhouse/ | |
- run: | | |
echo "from cryptography.hazmat.backends.openssl.backend import backend;print('Loaded: ' + backend.openssl_version_text());print('Linked Against: ' + backend._ffi.string(backend._lib.OPENSSL_VERSION_TEXT).decode('ascii'))" | uv run - | |
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 | |
with: | |
name: "cryptography-${{ github.event.inputs.version }}-${{ matrix.MANYLINUX.NAME }}-${{ matrix.PYTHON.VERSION }}-${{ matrix.PYTHON.ABI_VERSION }}" | |
path: wheelhouse/ | |
macos: | |
needs: [sdist] | |
runs-on: macos-13 | |
strategy: | |
fail-fast: false | |
matrix: | |
PYTHON: | |
- VERSION: '3.11' | |
ABI_VERSION: 'py37' | |
# Despite the name, this is built for the macOS 11 SDK on arm64 and 10.9+ on intel | |
DOWNLOAD_URL: 'https://www.python.org/ftp/python/3.11.3/python-3.11.3-macos11.pkg' | |
BIN_PATH: '/Library/Frameworks/Python.framework/Versions/3.11/bin/python3' | |
DEPLOYMENT_TARGET: '10.12' | |
# This archflags is default, but let's be explicit | |
ARCHFLAGS: '-arch x86_64 -arch arm64' | |
# See https://github.com/pypa/cibuildwheel/blob/c8876b5c54a6c6b08de5d4b1586906b56203bd9e/cibuildwheel/macos.py#L257-L269 | |
# This will change in the future as we change the base Python we | |
# build against | |
_PYTHON_HOST_PLATFORM: 'macosx-10.9-universal2' | |
- VERSION: '3.11' | |
ABI_VERSION: 'py39' | |
# Despite the name, this is built for the macOS 11 SDK on arm64 and 10.9+ on intel | |
DOWNLOAD_URL: 'https://www.python.org/ftp/python/3.11.3/python-3.11.3-macos11.pkg' | |
BIN_PATH: '/Library/Frameworks/Python.framework/Versions/3.11/bin/python3' | |
DEPLOYMENT_TARGET: '10.12' | |
# This archflags is default, but let's be explicit | |
ARCHFLAGS: '-arch x86_64 -arch arm64' | |
# See https://github.com/pypa/cibuildwheel/blob/c8876b5c54a6c6b08de5d4b1586906b56203bd9e/cibuildwheel/macos.py#L257-L269 | |
# This will change in the future as we change the base Python we | |
# build against | |
_PYTHON_HOST_PLATFORM: 'macosx-10.9-universal2' | |
- VERSION: 'pypy-3.10' | |
BIN_PATH: 'pypy3' | |
DEPLOYMENT_TARGET: '10.12' | |
_PYTHON_HOST_PLATFORM: 'macosx-10.9-x86_64' | |
ARCHFLAGS: '-arch x86_64' | |
name: "${{ matrix.PYTHON.VERSION }} ABI ${{ matrix.PYTHON.ABI_VERSION }} macOS ${{ matrix.PYTHON.ARCHFLAGS }}" | |
steps: | |
- name: Get build-requirements.txt from repository | |
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 | |
with: | |
# The tag to build or the tag received by the tag event | |
ref: ${{ github.event.inputs.version || github.ref }} | |
persist-credentials: false | |
sparse-checkout: | | |
${{ env.BUILD_REQUIREMENTS_PATH }} | |
${{ env.UV_REQUIREMENTS_PATH }} | |
sparse-checkout-cone-mode: false | |
- name: Setup python | |
run: | | |
curl "$PYTHON_DOWNLOAD_URL" -o python.pkg | |
sudo installer -pkg python.pkg -target / | |
env: | |
PYTHON_DOWNLOAD_URL: ${{ matrix.PYTHON.DOWNLOAD_URL }} | |
if: contains(matrix.PYTHON.VERSION, 'pypy') == false | |
- name: Setup pypy | |
uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 | |
with: | |
python-version: ${{ matrix.PYTHON.VERSION }} | |
if: contains(matrix.PYTHON.VERSION, 'pypy') | |
- uses: dawidd6/action-download-artifact@bf251b5aa9c2f7eeb574a96ee720e24f801b7c11 # v6 | |
with: | |
repo: pyca/infra | |
workflow: build-macos-openssl.yml | |
branch: main | |
workflow_conclusion: success | |
name: openssl-macos-universal2 | |
path: "../openssl-macos-universal2/" | |
github_token: ${{ secrets.GITHUB_TOKEN }} | |
- uses: dtolnay/rust-toolchain@1482605bfc5719782e1267fd0c0cc350fe7646b8 | |
with: | |
toolchain: stable | |
# Add the arm64 target in addition to the native arch (x86_64) | |
target: aarch64-apple-darwin | |
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 | |
with: | |
name: cryptography-sdist | |
- run: ${{ matrix.PYTHON.BIN_PATH }} -m pip install -r ${{ env.UV_REQUIREMENTS_PATH }} | |
- run: mkdir wheelhouse | |
- name: Build the wheel | |
run: | | |
if [ -n "${{ matrix.PYTHON.ABI_VERSION }}" ]; then | |
PY_LIMITED_API="--config-settings=build-args=--features=pyo3/abi3-${{ matrix.PYTHON.ABI_VERSION }}" | |
fi | |
OPENSSL_DIR="$(readlink -f ../openssl-macos-universal2/)" \ | |
OPENSSL_STATIC=1 \ | |
uv build --wheel --require-hashes --build-constraint=$BUILD_REQUIREMENTS_PATH $PY_LIMITED_API cryptography*.tar.gz -o wheelhouse/ | |
env: | |
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.PYTHON.DEPLOYMENT_TARGET }} | |
ARCHFLAGS: ${{ matrix.PYTHON.ARCHFLAGS }} | |
_PYTHON_HOST_PLATFORM: ${{ matrix.PYTHON._PYTHON_HOST_PLATFORM }} | |
- run: uv venv | |
- run: uv pip install --require-hashes -r $BUILD_REQUIREMENTS_PATH | |
- run: uv pip install cryptography --no-index -f wheelhouse/ | |
- name: Show the wheel's minimum macOS SDK and architectures | |
run: | | |
find .venv/lib/*/site-packages/cryptography/hazmat/bindings -name '*.so' -exec vtool -show {} \; | |
- run: | | |
echo "from cryptography.hazmat.backends.openssl.backend import backend;print('Loaded: ' + backend.openssl_version_text());print('Linked Against: ' + backend._ffi.string(backend._lib.OPENSSL_VERSION_TEXT).decode('ascii'))" | uv run - | |
- run: | | |
echo "CRYPTOGRAPHY_WHEEL_NAME=$(basename $(ls wheelhouse/cryptography*.whl))" >> $GITHUB_ENV | |
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 | |
with: | |
name: "${{ env.CRYPTOGRAPHY_WHEEL_NAME }}" | |
path: wheelhouse/ | |
windows: | |
needs: [sdist] | |
runs-on: windows-latest | |
strategy: | |
fail-fast: false | |
matrix: | |
WINDOWS: | |
- {ARCH: 'x86', WINDOWS: 'win32', RUST_TRIPLE: 'i686-pc-windows-msvc'} | |
- {ARCH: 'x64', WINDOWS: 'win64', RUST_TRIPLE: 'x86_64-pc-windows-msvc'} | |
PYTHON: | |
- {VERSION: "3.11", "ABI_VERSION": "py37"} | |
- {VERSION: "3.11", "ABI_VERSION": "py39"} | |
- {VERSION: "pypy-3.10"} | |
exclude: | |
# We need to exclude the below configuration because there is no 32-bit pypy3 | |
- WINDOWS: {ARCH: 'x86', WINDOWS: 'win32', RUST_TRIPLE: 'i686-pc-windows-msvc'} | |
PYTHON: {VERSION: "pypy-3.10"} | |
name: "${{ matrix.PYTHON.VERSION }} ${{ matrix.WINDOWS.WINDOWS }} ${{ matrix.PYTHON.ABI_VERSION }}" | |
steps: | |
- name: Get build-requirements.txt from repository | |
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 | |
with: | |
# The tag to build or the tag received by the tag event | |
ref: ${{ github.event.inputs.version || github.ref }} | |
persist-credentials: false | |
sparse-checkout: | | |
${{ env.BUILD_REQUIREMENTS_PATH }} | |
${{ env.UV_REQUIREMENTS_PATH }} | |
sparse-checkout-cone-mode: false | |
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 | |
with: | |
name: cryptography-sdist | |
- name: Setup python | |
uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 | |
with: | |
python-version: ${{ matrix.PYTHON.VERSION }} | |
architecture: ${{ matrix.WINDOWS.ARCH }} | |
- uses: dtolnay/rust-toolchain@1482605bfc5719782e1267fd0c0cc350fe7646b8 | |
with: | |
toolchain: stable | |
target: ${{ matrix.WINDOWS.RUST_TRIPLE }} | |
- uses: dawidd6/action-download-artifact@bf251b5aa9c2f7eeb574a96ee720e24f801b7c11 # v6 | |
with: | |
repo: pyca/infra | |
workflow: build-windows-openssl.yml | |
branch: main | |
workflow_conclusion: success | |
name: "openssl-${{ matrix.WINDOWS.WINDOWS }}" | |
path: "C:/openssl-${{ matrix.WINDOWS.WINDOWS }}/" | |
github_token: ${{ secrets.GITHUB_TOKEN }} | |
- name: Configure OpenSSL | |
run: | | |
echo "OPENSSL_DIR=C:/openssl-${{ matrix.WINDOWS.WINDOWS }}" >> $GITHUB_ENV | |
echo "OPENSSL_STATIC=1" >> $GITHUB_ENV | |
shell: bash | |
- run: pip install -r ${{ env.UV_REQUIREMENTS_PATH }} | |
- run: mkdir wheelhouse | |
- run: | | |
if [ -n "${{ matrix.PYTHON.ABI_VERSION }}" ]; then | |
PY_LIMITED_API="--config-settings=build-args=--features=pyo3/abi3-${{ matrix.PYTHON.ABI_VERSION }}" | |
fi | |
uv build --wheel --require-hashes --build-constraint=$BUILD_REQUIREMENTS_PATH cryptography*.tar.gz $PY_LIMITED_API -o wheelhouse/ | |
shell: bash | |
- run: uv venv | |
- run: uv pip install --require-hashes -r ${{ env.BUILD_REQUIREMENTS_PATH }} | |
- run: uv pip install cryptography --no-index -f wheelhouse/ | |
- name: Print the OpenSSL we built and linked against | |
run: | | |
echo "from cryptography.hazmat.backends.openssl.backend import backend;print('Loaded: ' + backend.openssl_version_text());print('Linked Against: ' + backend._ffi.string(backend._lib.OPENSSL_VERSION_TEXT).decode('ascii'))" | uv run - | |
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 | |
with: | |
name: "cryptography-${{ github.event.inputs.version }}-${{ matrix.WINDOWS.WINDOWS }}-${{ matrix.PYTHON.VERSION }}-${{ matrix.PYTHON.ABI_VERSION }}" | |
path: wheelhouse\ |