15. _Build Distribution #10
Workflow file for this run
This file contains hidden or 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: 15. _Build Distribution | |
| on: | |
| workflow_call: | |
| inputs: | |
| os_json: | |
| description: 'JSON string of OS to build on' | |
| required: false | |
| type: string | |
| default: '["ubuntu-latest", "macos-latest", "macos-15-intel", "windows-latest"]' | |
| python_json: | |
| description: 'JSON string of Python versions' | |
| required: false | |
| type: string | |
| default: '["3.9", "3.10", "3.11", "3.12"]' | |
| workflow_dispatch: | |
| inputs: | |
| os_json: | |
| description: 'JSON string of OS to build on' | |
| required: false | |
| default: '["ubuntu-latest", "macos-latest", "macos-15-intel", "windows-latest"]' | |
| python_json: | |
| description: 'JSON string of Python versions' | |
| required: false | |
| default: '["3.9", "3.10", "3.11", "3.12"]' | |
| jobs: | |
| build-linux: | |
| name: Build distribution on Linux (glibc 2.31) py${{ matrix.python-version }} | |
| # Only run if inputs.os_json contains 'ubuntu' or 'linux' | |
| if: contains(inputs.os_json, 'ubuntu') || contains(inputs.os_json, 'linux') | |
| runs-on: ubuntu-latest | |
| container: ubuntu:20.04 | |
| env: | |
| DEBIAN_FRONTEND: noninteractive | |
| TZ: Etc/UTC | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ${{ fromJson(inputs.python_json) }} | |
| steps: | |
| - name: Install system dependencies (Linux) | |
| run: | | |
| # Replace archive.ubuntu.com with azure.archive.ubuntu.com for better stability in GH Actions | |
| sed -i 's/http:\/\/archive.ubuntu.com\/ubuntu\//http:\/\/azure.archive.ubuntu.com\/ubuntu\//g' /etc/apt/sources.list | |
| # Retry apt-get update | |
| for i in 1 2 3 4 5; do apt-get update && break || sleep 5; done | |
| apt-get install -y \ | |
| git ca-certificates cmake build-essential tzdata curl \ | |
| libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev \ | |
| libffi-dev liblzma-dev libgdbm-dev libnss3-dev libncurses5-dev \ | |
| libncursesw5-dev tk-dev uuid-dev libexpat1-dev | |
| ln -fs /usr/share/zoneinfo/Etc/UTC /etc/localtime | |
| dpkg-reconfigure -f noninteractive tzdata | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| fetch-depth: 0 # Required for setuptools_scm to detect version from git tags | |
| - name: Build CPython (Dynamic Selection) | |
| run: | | |
| # Map short version to full version for our specific build environment | |
| PYTHON_VERSION="${{ matrix.python-version }}" | |
| case "$PYTHON_VERSION" in | |
| "3.9") PYTHON_FULL="3.9.18" ;; | |
| "3.10") PYTHON_FULL="3.10.13" ;; | |
| "3.11") PYTHON_FULL="3.11.8" ;; | |
| "3.12") PYTHON_FULL="3.12.2" ;; | |
| *) | |
| echo "Error: Unknown python version $PYTHON_VERSION" | |
| exit 1 | |
| ;; | |
| esac | |
| PYTHON_PREFIX="/opt/python/${PYTHON_FULL}" | |
| PYTHON_BIN="${PYTHON_PREFIX}/bin/python${{ matrix.python-version }}" | |
| if [ ! -x "$PYTHON_BIN" ]; then | |
| curl -fsSL -o /tmp/Python-${PYTHON_FULL}.tgz \ | |
| https://www.python.org/ftp/python/${PYTHON_FULL}/Python-${PYTHON_FULL}.tgz | |
| tar -xzf /tmp/Python-${PYTHON_FULL}.tgz -C /tmp | |
| cd /tmp/Python-${PYTHON_FULL} | |
| CFLAGS="-fPIC" \ | |
| ./configure --prefix="${PYTHON_PREFIX}" --with-ensurepip=install --enable-shared | |
| make -j"$(nproc)" | |
| make install | |
| fi | |
| echo "PYTHON_BIN=${PYTHON_BIN}" >> "$GITHUB_ENV" | |
| echo "LD_LIBRARY_PATH=${PYTHON_PREFIX}/lib:${LD_LIBRARY_PATH}" >> "$GITHUB_ENV" | |
| export LD_LIBRARY_PATH="${PYTHON_PREFIX}/lib:${LD_LIBRARY_PATH}" | |
| "$PYTHON_BIN" -V | |
| - name: Set up Go | |
| uses: actions/setup-go@v6 | |
| with: | |
| go-version: '1.25.1' | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| with: | |
| enable-cache: true | |
| - name: Create venv (Linux) | |
| run: uv venv --python "$PYTHON_BIN" | |
| - name: Seed pip (Linux) | |
| run: uv run python -m ensurepip --upgrade | |
| - name: Install dependencies | |
| run: uv sync | |
| - name: Install build dependencies | |
| run: uv pip install setuptools setuptools_scm pybind11 cmake wheel build | |
| - name: Build package | |
| run: uv run python -m build | |
| - name: Install patchelf (Linux) | |
| run: | | |
| PATCHELF_VERSION=0.18.0 | |
| curl -fsSL -o /tmp/patchelf-${PATCHELF_VERSION}.tar.gz \ | |
| https://github.com/NixOS/patchelf/releases/download/${PATCHELF_VERSION}/patchelf-${PATCHELF_VERSION}.tar.gz | |
| tar -xzf /tmp/patchelf-${PATCHELF_VERSION}.tar.gz -C /tmp | |
| cd /tmp/patchelf-${PATCHELF_VERSION} | |
| ./configure | |
| make -j"$(nproc)" | |
| make install | |
| patchelf --version | |
| - name: Repair wheels (Linux) | |
| run: | | |
| uv pip install auditwheel | |
| # Repair wheels and output to a temporary directory | |
| uv run auditwheel repair dist/*.whl -w dist_fixed | |
| # Remove original non-compliant wheels | |
| rm dist/*.whl | |
| # Move repaired wheels back to dist | |
| mv dist_fixed/*.whl dist/ | |
| rmdir dist_fixed | |
| - name: Store the distribution packages | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: python-package-distributions-linux-${{ matrix.python-version }} | |
| path: dist/ | |
| build-other: | |
| name: Build distribution on ${{ matrix.os }} | |
| # Filter out ubuntu-latest from this job since it's handled by build-linux | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: ${{ fromJson(inputs.os_json) }} | |
| python-version: ${{ fromJson(inputs.python_json) }} | |
| # Exclude ubuntu-latest from this matrix if it was passed in inputs | |
| exclude: | |
| - os: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| fetch-depth: 0 # Required for setuptools_scm to detect version from git tags | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Set up Go | |
| uses: actions/setup-go@v6 | |
| with: | |
| go-version: '1.25.1' | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| with: | |
| enable-cache: true | |
| - name: Install system dependencies (macOS) | |
| if: runner.os == 'macOS' | |
| run: brew install cmake | |
| - name: Install system dependencies (Windows) | |
| if: runner.os == 'Windows' | |
| run: | | |
| choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System' | |
| choco install mingw | |
| - name: Install dependencies | |
| run: uv sync | |
| - name: Install build dependencies | |
| run: uv pip install setuptools setuptools_scm pybind11 cmake wheel build | |
| - name: Build package | |
| run: uv run python -m build | |
| - name: Store the distribution packages | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: python-package-distributions-${{ matrix.os }}-${{ matrix.python-version }} | |
| path: dist/ |