feat: buildwheel in ghrunner (#221)
This commit is contained in:
parent
de1e7050d7
commit
7bc4838aca
|
|
@ -0,0 +1,102 @@
|
|||
name: "(Reusable) Build, Publish and Smoke-test a Wheel"
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
runner:
|
||||
description: "GitHub Actions runner label"
|
||||
required: true
|
||||
type: string
|
||||
pypi_repository_url:
|
||||
description: "PyPI repository URL (empty string means official PyPI)"
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
secrets:
|
||||
PYPI_API_TOKEN:
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
build_publish_test:
|
||||
name: Build / publish / smoke-test on ${{ inputs.runner }}
|
||||
runs-on: ${{ inputs.runner }}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Set up Python (for cibuildwheel controller)
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Install cibuildwheel
|
||||
run: |
|
||||
pip install --upgrade pip
|
||||
pip install cibuildwheel==3.4.0
|
||||
|
||||
- name: Build wheels using cibuildwheel
|
||||
run: |
|
||||
python -m cibuildwheel --output-dir wheelhouse
|
||||
# Save list of built wheels for publishing
|
||||
ls wheelhouse/*.whl | tee $GITHUB_STEP_SUMMARY
|
||||
echo "wheels=$(ls wheelhouse/*.whl | tr '\n' ' ')" >> $GITHUB_ENV
|
||||
|
||||
- name: Publish to PyPI
|
||||
if: success() && github.event_name == 'workflow_dispatch'
|
||||
env:
|
||||
TWINE_USERNAME: __token__
|
||||
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
||||
TWINE_REPOSITORY_URL: ${{ inputs.pypi_repository_url }}
|
||||
run: |
|
||||
pip install twine
|
||||
twine upload --skip-existing --verbose wheelhouse/*.whl
|
||||
|
||||
- name: Smoke test from PyPI
|
||||
if: success() && github.event_name == 'workflow_dispatch'
|
||||
shell: bash
|
||||
env:
|
||||
PYPI_REPOSITORY_URL: ${{ inputs.pypi_repository_url }}
|
||||
run: |
|
||||
# Extract version from wheel filename (e.g. zvec-0.2.1.dev24-cp311-...whl -> 0.2.1.dev24)
|
||||
WHEEL_FILE=$(ls wheelhouse/zvec-*.whl | head -1)
|
||||
ZVEC_VERSION=$(basename "$WHEEL_FILE" | sed 's/zvec-\([^-]*\)-.*/\1/')
|
||||
|
||||
# Build index-url flags: use TestPyPI when repository URL is set, otherwise official PyPI
|
||||
if [ -n "$PYPI_REPOSITORY_URL" ]; then
|
||||
INDEX_FLAGS="--index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/"
|
||||
echo "Waiting for zvec==$ZVEC_VERSION to become available on TestPyPI..."
|
||||
else
|
||||
INDEX_FLAGS=""
|
||||
echo "Waiting for zvec==$ZVEC_VERSION to become available on PyPI..."
|
||||
fi
|
||||
# Poll until the version is available (max 5 minutes)
|
||||
FOUND=0
|
||||
for i in $(seq 1 30); do
|
||||
if pip install $INDEX_FLAGS --dry-run "zvec==$ZVEC_VERSION" > /dev/null 2>&1; then
|
||||
echo "Version $ZVEC_VERSION is available."
|
||||
FOUND=1
|
||||
break
|
||||
fi
|
||||
echo "Attempt $i/30: not yet available, retrying in 10s..."
|
||||
sleep 10
|
||||
done
|
||||
|
||||
if [ "$FOUND" -eq 0 ]; then
|
||||
echo "ERROR: Timed out (5 min) waiting for zvec==$ZVEC_VERSION on PyPI. Aborting smoke test."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create a clean venv and install
|
||||
python -m venv test_env
|
||||
source test_env/bin/activate
|
||||
pip install --upgrade pip
|
||||
pip install $INDEX_FLAGS "zvec==$ZVEC_VERSION"
|
||||
pip install --upgrade pip
|
||||
pip install $INDEX_FLAGS "zvec==$ZVEC_VERSION"
|
||||
# Run a simple smoke test
|
||||
python -c "import zvec; print('Import OK:', zvec.__version__)"
|
||||
|
|
@ -8,97 +8,28 @@ permissions:
|
|||
|
||||
jobs:
|
||||
build_wheels_linux_x64:
|
||||
name: Build wheels on self-hosted manylinux_2_28_x64 for TestPyPi
|
||||
runs-on: linux_x64
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Set up Python (for cibuildwheel controller)
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Install cibuildwheel
|
||||
run: |
|
||||
pip install --upgrade pip
|
||||
pip install cibuildwheel==2.17.0
|
||||
- name: Build wheels using cibuildwheel
|
||||
run: |
|
||||
python -m cibuildwheel --output-dir wheelhouse
|
||||
# Save list of built wheels for publishing
|
||||
ls wheelhouse/*.whl | tee $GITHUB_STEP_SUMMARY
|
||||
echo "wheels=$(ls wheelhouse/*.whl | tr '\n' ' ')" >> $GITHUB_ENV
|
||||
- name: Publish to TestPyPI
|
||||
if: success() && github.event_name == 'workflow_dispatch'
|
||||
env:
|
||||
TWINE_USERNAME: __token__
|
||||
TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
|
||||
TWINE_REPOSITORY_URL: https://test.pypi.org/legacy/
|
||||
run: |
|
||||
pip install twine
|
||||
twine upload --skip-existing --verbose wheelhouse/*.whl
|
||||
- name: (Optional) Install and test from TestPyPI
|
||||
if: success() && github.event_name == 'workflow_dispatch'
|
||||
run: |
|
||||
# Create a clean venv
|
||||
python -m venv test_env
|
||||
source test_env/bin/activate
|
||||
pip install --upgrade pip
|
||||
# Install from TestPyPI (must allow pre-releases if version has dev/alpha)
|
||||
pip install numpy
|
||||
pip install --index-url https://test.pypi.org/simple/ zvec
|
||||
# Run a simple smoke test
|
||||
python -c "import zvec; print('Import OK:', zvec.__version__)"
|
||||
shell: bash
|
||||
name: Build wheels on ubuntu-24.04 (x64) for TestPyPi
|
||||
uses: ./.github/workflows/_build_wheel_job.yml
|
||||
with:
|
||||
runner: ubuntu-24.04
|
||||
pypi_repository_url: https://test.pypi.org/legacy/
|
||||
secrets:
|
||||
PYPI_API_TOKEN: ${{ secrets.TEST_PYPI_API_TOKEN }}
|
||||
|
||||
build_wheels_linux_arm64:
|
||||
name: Build wheels on self-hosted manylinux_2_28_arm64 for TestPyPi
|
||||
runs-on: linux_arm64
|
||||
name: Build wheels on ubuntu-24.04-arm (arm64) for TestPyPi
|
||||
uses: ./.github/workflows/_build_wheel_job.yml
|
||||
with:
|
||||
runner: ubuntu-24.04-arm
|
||||
pypi_repository_url: https://test.pypi.org/legacy/
|
||||
secrets:
|
||||
PYPI_API_TOKEN: ${{ secrets.TEST_PYPI_API_TOKEN }}
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Set up Python (for cibuildwheel controller)
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Install cibuildwheel
|
||||
run: |
|
||||
pip install --upgrade pip
|
||||
pip install cibuildwheel==2.17.0
|
||||
- name: Build wheels using cibuildwheel
|
||||
run: |
|
||||
python -m cibuildwheel --output-dir wheelhouse
|
||||
# Save list of built wheels for publishing
|
||||
ls wheelhouse/*.whl | tee $GITHUB_STEP_SUMMARY
|
||||
echo "wheels=$(ls wheelhouse/*.whl | tr '\n' ' ')" >> $GITHUB_ENV
|
||||
- name: Publish to TestPyPI
|
||||
if: success() && github.event_name == 'workflow_dispatch'
|
||||
env:
|
||||
TWINE_USERNAME: __token__
|
||||
TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
|
||||
TWINE_REPOSITORY_URL: https://test.pypi.org/legacy/
|
||||
run: |
|
||||
pip install twine
|
||||
twine upload --skip-existing --verbose wheelhouse/*.whl
|
||||
- name: (Optional) Install and test from TestPyPI
|
||||
if: success() && github.event_name == 'workflow_dispatch'
|
||||
run: |
|
||||
# Create a clean venv
|
||||
python -m venv test_env
|
||||
source test_env/bin/activate
|
||||
pip install --upgrade pip
|
||||
# Install from TestPyPI (must allow pre-releases if version has dev/alpha)
|
||||
pip install numpy
|
||||
pip install --index-url https://test.pypi.org/simple/ zvec
|
||||
# Run a simple smoke test
|
||||
python -c "import zvec; print('Import OK:', zvec.__version__)"
|
||||
shell: bash
|
||||
build_wheels_macos_arm64:
|
||||
name: Build wheels on macos-15 (arm64) for TestPyPi
|
||||
uses: ./.github/workflows/_build_wheel_job.yml
|
||||
with:
|
||||
runner: macos-15
|
||||
pypi_repository_url: https://test.pypi.org/legacy/
|
||||
secrets:
|
||||
PYPI_API_TOKEN: ${{ secrets.TEST_PYPI_API_TOKEN }}
|
||||
|
|
|
|||
|
|
@ -8,101 +8,25 @@ permissions:
|
|||
|
||||
jobs:
|
||||
build_wheels_linux_x64:
|
||||
name: Build wheels on self-hosted manylinux_2_28_x64
|
||||
runs-on: linux_x64
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Set up Python (for cibuildwheel controller)
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Install cibuildwheel
|
||||
run: |
|
||||
pip install --upgrade pip
|
||||
pip install cibuildwheel==2.17.0
|
||||
|
||||
- name: Build wheels using cibuildwheel
|
||||
run: |
|
||||
python -m cibuildwheel --output-dir wheelhouse
|
||||
# Save list of built wheels for publishing
|
||||
ls wheelhouse/*.whl | tee $GITHUB_STEP_SUMMARY
|
||||
echo "wheels=$(ls wheelhouse/*.whl | tr '\n' ' ')" >> $GITHUB_ENV
|
||||
|
||||
- name: Publish to PyPI
|
||||
if: success() && github.event_name == 'workflow_dispatch'
|
||||
env:
|
||||
TWINE_USERNAME: __token__
|
||||
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
||||
TWINE_REPOSITORY: pypi
|
||||
run: |
|
||||
pip install twine
|
||||
twine upload --skip-existing --verbose wheelhouse/*.whl
|
||||
|
||||
- name: (Optional) Install and test from PyPI
|
||||
if: success() && github.event_name == 'workflow_dispatch'
|
||||
run: |
|
||||
# Create a clean venv
|
||||
python -m venv test_env
|
||||
source test_env/bin/activate
|
||||
pip install --upgrade pip
|
||||
# Install from PyPI
|
||||
pip install zvec
|
||||
# Run a simple smoke test
|
||||
python -c "import zvec; print('Import OK:', zvec.__version__)"
|
||||
shell: bash
|
||||
name: Build wheels on ubuntu-24.04 (x64) for PyPi
|
||||
uses: ./.github/workflows/_build_wheel_job.yml
|
||||
with:
|
||||
runner: ubuntu-24.04
|
||||
secrets:
|
||||
PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
|
||||
|
||||
build_wheels_linux_arm64:
|
||||
name: Build wheels on self-hosted manylinux_2_28_arm64
|
||||
runs-on: linux_arm64
|
||||
name: Build wheels on ubuntu-24.04-arm (arm64) for PyPi
|
||||
uses: ./.github/workflows/_build_wheel_job.yml
|
||||
with:
|
||||
runner: ubuntu-24.04-arm
|
||||
secrets:
|
||||
PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Set up Python (for cibuildwheel controller)
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.11'
|
||||
|
||||
- name: Install cibuildwheel
|
||||
run: |
|
||||
pip install --upgrade pip
|
||||
pip install cibuildwheel==2.17.0
|
||||
|
||||
- name: Build wheels using cibuildwheel
|
||||
run: |
|
||||
python -m cibuildwheel --output-dir wheelhouse
|
||||
# Save list of built wheels for publishing
|
||||
ls wheelhouse/*.whl | tee $GITHUB_STEP_SUMMARY
|
||||
echo "wheels=$(ls wheelhouse/*.whl | tr '\n' ' ')" >> $GITHUB_ENV
|
||||
|
||||
- name: Publish to PyPI
|
||||
if: success() && github.event_name == 'workflow_dispatch'
|
||||
env:
|
||||
TWINE_USERNAME: __token__
|
||||
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
||||
TWINE_REPOSITORY: pypi
|
||||
run: |
|
||||
pip install twine
|
||||
twine upload --skip-existing --verbose wheelhouse/*.whl
|
||||
|
||||
- name: (Optional) Install and test from PyPI
|
||||
if: success() && github.event_name == 'workflow_dispatch'
|
||||
run: |
|
||||
# Create a clean venv
|
||||
python -m venv test_env
|
||||
source test_env/bin/activate
|
||||
pip install --upgrade pip
|
||||
# Install from PyPI
|
||||
pip install zvec
|
||||
# Run a simple smoke test
|
||||
python -c "import zvec; print('Import OK:', zvec.__version__)"
|
||||
shell: bash
|
||||
build_wheels_macos_arm64:
|
||||
name: Build wheels on macos-15 (arm64) for PyPi
|
||||
uses: ./.github/workflows/_build_wheel_job.yml
|
||||
with:
|
||||
runner: macos-15
|
||||
secrets:
|
||||
PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ test = [
|
|||
"pytest >=8.0",
|
||||
"pytest-cov >=4.1",
|
||||
"pytest-mock >=3.12",
|
||||
"cibuildwheel == 2.17.0",
|
||||
"cibuildwheel == 3.4.0",
|
||||
]
|
||||
docs = [
|
||||
"mkdocs >=1.5",
|
||||
|
|
@ -70,7 +70,7 @@ dev = [
|
|||
"pytest >=8.0",
|
||||
"pytest-cov >=4.1",
|
||||
"pytest-mock >=3.12",
|
||||
"cibuildwheel == 2.17.0",
|
||||
"cibuildwheel == 3.4.0",
|
||||
# Inherit docs deps
|
||||
"mkdocs >=1.5",
|
||||
"mkdocs-material >=9.5",
|
||||
|
|
@ -130,6 +130,7 @@ BUILD_PYTHON_BINDINGS = "ON"
|
|||
[tool.setuptools_scm]
|
||||
local_scheme = "no-local-version"
|
||||
version_scheme = "guess-next-dev"
|
||||
fallback_version = "0.2.1b1"
|
||||
######################################################################################################
|
||||
# TESTING & QUALITY
|
||||
######################################################################################################
|
||||
|
|
@ -169,11 +170,12 @@ build = [
|
|||
]
|
||||
build-frontend = "build"
|
||||
test-requires = ["pytest", "numpy"]
|
||||
test-command = "cd {project} && pytest python/tests -v --tb=short"
|
||||
build-verbosity = 1
|
||||
|
||||
[tool.cibuildwheel.linux]
|
||||
archs = ["auto"]
|
||||
test-command = "cd {project} && pytest python/tests -v --tb=short"
|
||||
environment = { CMAKE_GENERATOR = "Unix Makefiles", CMAKE_BUILD_PARALLEL_LEVEL = "16" }
|
||||
manylinux-x86_64-image = "manylinux_2_28"
|
||||
manylinux-aarch64-image = "manylinux_2_28"
|
||||
# Skip 32-bit builds and musllinux
|
||||
|
|
@ -181,7 +183,9 @@ skip = ["*-manylinux_i686", "*-musllinux*"]
|
|||
|
||||
[tool.cibuildwheel.macos]
|
||||
archs = ["arm64"]
|
||||
environment = { MACOSX_DEPLOYMENT_TARGET = "11.0" }
|
||||
# Inherits CMAKE_GENERATOR and CMAKE_BUILD_PARALLEL_LEVEL from [tool.cibuildwheel] won't work;
|
||||
# platform-level environment overrides the top-level entirely, so all vars must be listed here
|
||||
environment = { CMAKE_GENERATOR = "Unix Makefiles", CMAKE_BUILD_PARALLEL_LEVEL = "16", MACOSX_DEPLOYMENT_TARGET = "11.0" }
|
||||
######################################################################################################
|
||||
# CODE QUALITY & FORMATTING (Ruff)
|
||||
######################################################################################################
|
||||
|
|
|
|||
Loading…
Reference in New Issue