Skip to content

Migrate py313 build

Migrate py313 build #3

Workflow file for this run

name: Compile, Test, and Deploy
on:
pull_request: {}
push:
branches:
- main
release:
types: [published]
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
run-python-tests:
runs-on: ${{ matrix.os }}
continue-on-error: true
defaults:
run:
working-directory: python
strategy:
matrix:
python-version:
- "3.14"
os: ["ubuntu-latest", windows-latest, macos-latest]
name: Test with Python ${{ matrix.python-version }} on ${{ matrix.os }}
steps:
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Copy README into place
run: cp ../README.md ./
- name: Install Linux dependencies
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y pkg-config
- name: Install test dependencies
env:
# on macOS and with Python 3.10: building NumPy from source fails without these options:
NPY_BLAS_ORDER: ""
NPY_LAPACK_ORDER: ""
run: |
python -m pip install --upgrade pip
pip install wheel
pip install setuptools
pip install -r dev-requirements.txt
- name: Build voyager locally
run: python -m pip install .
- name: Run tox tests
run: tox
run-python-tests-with-address-sanitizer:
defaults:
run:
working-directory: python
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version:
- "3.14"
os: ["ubuntu-latest"]
name: Test with Python ${{ matrix.python-version }} + Address Sanitizer
steps:
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Copy README into place
run: cp ../README.md ./
- name: Install Linux dependencies
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y pkg-config
- name: Install test dependencies
run: |
python -m pip install --upgrade pip
pip install wheel
pip install setuptools
pip install -r dev-requirements.txt
- name: Build voyager locally
env:
DEBUG: "0"
USE_ASAN: "1"
CC: clang
CXX: clang++
run: python -m pip install .
- name: Run tox tests with ASan loaded
# pytest can exit before all Python objects have been destroyed,
# so we tell ASan to ignore leaks.
run: |
ASAN_OPTIONS=detect_leaks=0 \
LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so) \
tox
run-benchmarks:
strategy:
matrix:
os: ["ubuntu-latest"]
runs-on: ${{ matrix.os }}
continue-on-error: true
if: github.event_name == 'pull_request'
name: Run benchmarks on ${{ matrix.os }}
steps:
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: "3.14"
- uses: actions/checkout@v3
with:
fetch-depth: 0
submodules: recursive
- name: Install Linux dependencies
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y pkg-config
- name: Install dev dependencies
run: |
python -m pip install --upgrade pip
pip install wheel
pip install -r python/dev-requirements.txt
- name: Run benchmarks
run: |
asv machine --yes
asv continuous --sort name --no-only-changed refs/remotes/origin/main ${{ github.sha }} | tee >(sed '1,/All benchmarks:/d' > $GITHUB_STEP_SUMMARY)
build-python-sdist:
needs: [run-python-tests, run-python-tests-with-address-sanitizer]
continue-on-error: false
runs-on: "ubuntu-latest"
if: true
name: Build Python source distribution
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions/setup-python@v3
with:
python-version: "3.14"
- name: Copy README into place
run: cp README.md python/
- name: Copy C++ code into place
run: rm -rfv python/src/cpp && cp -r cpp python/src
if: runner.os == 'Linux'
- name: Install build module
run: python -m pip install build
- name: Build source distribution
working-directory: python
run: python -m build --sdist --outdir ../dist
- uses: actions/upload-artifact@v4
with:
if-no-files-found: error
name: python-sdist
path: ./dist/*.tar.gz
build-python-wheels:
needs: [run-python-tests, run-python-tests-with-address-sanitizer]
runs-on: ${{ matrix.os }}
continue-on-error: false
if: true
strategy:
matrix:
include:
- { os: macos-latest, build: cp312-macosx_x86_64 }
- { os: macos-latest, build: cp313-macosx_x86_64 }
- { os: macos-latest, build: cp314-macosx_x86_64 }
- { os: macos-latest, build: cp312-macosx_universal2 }
- { os: macos-latest, build: cp313-macosx_universal2 }
- { os: macos-latest, build: cp314-macosx_universal2 }
- { os: macos-latest, build: cp312-macosx_arm64 }
- { os: macos-latest, build: cp313-macosx_arm64 }
- { os: macos-latest, build: cp314-macosx_arm64 }
- { os: windows-latest, build: cp312-win_amd64 }
- { os: windows-latest, build: cp313-win_amd64 }
- { os: windows-latest, build: cp314-win_amd64 }
- { os: ubuntu-latest, build: cp312-manylinux_x86_64 }
- { os: ubuntu-latest, build: cp312-manylinux_aarch64 }
- { os: ubuntu-latest, build: cp313-manylinux_x86_64 }
- { os: ubuntu-latest, build: cp313-manylinux_aarch64 }
- { os: ubuntu-latest, build: cp314-manylinux_x86_64 }
- { os: ubuntu-latest, build: cp314-manylinux_aarch64 }
name: Build wheel for ${{ matrix.build }}
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
# Used to host cibuildwheel, so version doesn't really matter
- uses: actions/setup-python@v3
with:
python-version: "3.14"
- name: Install cibuildwheel
run: python -m pip install 'cibuildwheel>=2.11.0'
- name: Copy README into place
run: cp README.md python/
- name: Set up QEMU for aarch64 on Linux
if: runner.os == 'Linux'
uses: docker/setup-qemu-action@v1
with:
platforms: all
- name: Copy C++ code into place
run: rm -rfv python/src/cpp && cp -r cpp python/src
if: runner.os == 'Linux'
- name: Show directory structure for debugging
run: ls -lR .
if: runner.os == 'Linux'
- name: Build wheels
working-directory: python
run: python -m cibuildwheel --output-dir ../wheelhouse
env:
CIBW_TEST_REQUIRES: -r dev-requirements.txt
CIBW_TEST_COMMAND: "pytest {project}/tests -x"
CIBW_BUILD: ${{ matrix.build }}
CIBW_ARCHS: auto64 # Only support building 64-bit wheels. It's 2022!
CIBW_ARCHS_LINUX: auto64 aarch64 # Useful for building linux images with Apple Silicon
CIBW_ARCHS_MACOS: x86_64 universal2 arm64 # Support Apple Silicon
CIBW_ARCHS_WINDOWS: AMD64
# on macOS and with Python 3.10: building NumPy from source fails without these options:
CIBW_ENVIRONMENT: NPY_BLAS_ORDER="" NPY_LAPACK_ORDER=""
CIBW_REPAIR_WHEEL_COMMAND_LINUX: pip install auditwheel-symbols && (auditwheel repair -w {dest_dir} {wheel} || auditwheel-symbols --manylinux 2010 {wheel})
CIBW_TEST_SKIP: "*aarch64"
MACOSX_DEPLOYMENT_TARGET: "10.14"
- uses: actions/upload-artifact@v4
with:
if-no-files-found: error
name: python-wheels-${{ matrix.build }}
path: ./wheelhouse/*.whl
upload-pypi:
defaults:
run:
working-directory: python
needs:
[
build-python-wheels,
build-python-sdist,
run-python-tests-with-address-sanitizer,
run-python-tests,
]
runs-on: "ubuntu-latest"
name: "Upload wheels and sdist to PyPI"
if: github.event_name == 'release' && github.event.action == 'published'
steps:
- uses: actions/download-artifact@v4
with:
pattern: python-wheels-*
path: dist
merge-multiple: true
- uses: actions/download-artifact@v4
with:
name: python-sdist
path: dist
- uses: pypa/gh-action-pypi-publish@v1.4.2
with:
user: __token__
password: ${{ secrets.PYPI_DEPLOY_TOKEN }}
# lint-java:
# runs-on: "ubuntu-latest"
# continue-on-error: true
# name: Lint Java
# defaults:
# run:
# working-directory: java
# steps:
# - uses: actions/checkout@v3
# - name: Set up JDK 17
# uses: actions/setup-java@v3
# with:
# java-version: "17"
# distribution: "corretto"
# - name: Check Formatting
# run: mvn --batch-mode com.spotify.fmt:fmt-maven-plugin:check
# lint-cpp:
# runs-on: "ubuntu-latest"
# continue-on-error: true
# name: Lint C++
# steps:
# - uses: actions/checkout@v3
# - name: Check C++ Formatting
# uses: jidicula/clang-format-action@v4.13.0
# with:
# clang-format-version: 16
# run-cpp-tests:
# runs-on: ${{ matrix.os }}
# continue-on-error: true
# defaults:
# run:
# working-directory: cpp
# strategy:
# matrix:
# os:
# - "ubuntu-latest"
# - windows-latest
# - macos-latest
# name: Test C++ on ${{ matrix.os }}
# steps:
# - uses: actions/checkout@v3
# with:
# submodules: recursive
# - name: Install CMake (Windows)
# if: matrix.os == 'windows-latest'
# run: cmake --version
# - name: Install CMake (MacOS)
# if: matrix.os == 'macos-latest'
# run: brew install cmake
# - name: Install CMake (Ubuntu)
# if: matrix.os == 'ubuntu-latest'
# run: sudo apt-get install -y cmake
# - name: Run tests
# run: make test
# run-java-tests:
# continue-on-error: true
# name: Test with Java ${{ matrix.java-version }} on ${{ matrix.os }}
# runs-on: ${{ matrix.os }}
# defaults:
# run:
# working-directory: java
# strategy:
# matrix:
# os: ["ubuntu-latest", windows-latest, macos-latest]
# java-version: ["11", "17"]
# steps:
# - uses: actions/checkout@v3
# - name: Set up JDK ${{ matrix.java-version }}
# uses: actions/setup-java@v3
# with:
# java-version: ${{ matrix.java-version }}
# distribution: "corretto"
# gpg-private-key: ${{ secrets.SONATYPE_GPG_PRIVATE_KEY }}
# gpg-passphrase: MAVEN_GPG_PASSPHRASE
# - uses: ilammy/msvc-dev-cmd@v1
# if: runner.os == 'Windows'
# - name: Compile
# run: make
# - name: Run Tests
# run: mvn --batch-mode test
# run-java-tests-with-address-sanitizer:
# if: false # Disabled due to ASan log spam in output
# continue-on-error: true
# name: Test with Java ${{ matrix.java-version }} + Address Sanitizer
# runs-on: ubuntu-latest
# defaults:
# run:
# working-directory: java
# strategy:
# matrix:
# java-version: ["11", "17"]
# steps:
# - uses: actions/checkout@v3
# - name: Set up JDK ${{ matrix.java-version }}
# uses: actions/setup-java@v4
# with:
# java-version: ${{ matrix.java-version }}
# distribution: "corretto"
# gpg-private-key: ${{ secrets.SONATYPE_GPG_PRIVATE_KEY }}
# gpg-passphrase: MAVEN_GPG_PASSPHRASE
# - name: Compile
# env:
# USE_ASAN: "1"
# run: make target/classes/linux-x64/libvoyager.so
# - name: Run Tests
# run: |
# ASAN_OPTIONS=detect_leaks=0
# LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so) \
# mvn --batch-mode test
# build-java-jars:
# continue-on-error: false
# name: Build JAR with on ${{ matrix.os }}
# runs-on: ${{ matrix.os }}
# defaults:
# run:
# working-directory: java
# strategy:
# matrix:
# os: ["ubuntu-latest", windows-latest, macos-latest]
# java-version: ["11"]
# steps:
# - uses: actions/checkout@v3
# - name: Set up JDK ${{ matrix.java-version }}
# uses: actions/setup-java@v3
# with:
# java-version: ${{ matrix.java-version }}
# distribution: "corretto"
# gpg-private-key: ${{ secrets.SONATYPE_GPG_PRIVATE_KEY }}
# gpg-passphrase: MAVEN_GPG_PASSPHRASE
# - name: Set up QEMU for aarch64 on Linux
# if: runner.os == 'Linux'
# uses: docker/setup-qemu-action@v1
# with:
# platforms: all
# - uses: ilammy/msvc-dev-cmd@v1
# if: runner.os == 'Windows'
# - name: Compile
# run: make
# - name: Package
# run: mvn --batch-mode package
# env:
# MAVEN_GPG_PASSPHRASE: ${{ secrets.SONATYPE_PASSPHRASE }}
# - uses: actions/upload-artifact@v4
# with:
# if-no-files-found: error
# name: java-${{ matrix.os }}
# path: java/target/voyager-*.jar
# combine-java-jars:
# name: Combine JARs
# runs-on: ubuntu-latest
# needs: build-java-jars
# steps:
# - uses: actions/download-artifact@v4
# with:
# path: artifacts
# - name: Unpack and Repack JARs
# shell: bash
# working-directory: artifacts
# run: |
# rm -fv java-*/*-sources.jar
# rm -fv java-*/*-javadoc.jar
# for artifact in java-*; do unzip -o $artifact/*.jar -d combined-jar; done
# # Quick test that the JARs were built for the correct architectures
# echo "Checking linux-x64/libvoyager.so for x86 architecture..."
# file combined-jar/linux-x64/libvoyager.so | grep x86
# echo "Checking mac-x64/libvoyager.dylib for x86 architecture..."
# file combined-jar/mac-x64/libvoyager.dylib | grep x86
# echo "Checking linux-aarch64/libvoyager.so for aarch64 architecture..."
# file combined-jar/linux-aarch64/libvoyager.so | grep aarch64
# echo "Checking mac-aarch64/libvoyager.dylib for arm64 architecture..."
# file combined-jar/mac-aarch64/libvoyager.dylib | grep arm64
# echo "Checking the Linux JARs to ensure a sufficiently old required GLIBC and GLIBCXX version in each..."
# echo "Checking linux-aarch64/libvoyager.so (should require at most GLIBC 2.27...)"
# objdump -T combined-jar/linux-aarch64/libvoyager.so | grep GLIBC | grep -v GLIBCXX | sed 's/.*GLIBC_\([.0-9]*\).*/\1/g' | cat - <(echo 2\.27) | sort -Vu | tail -n 1 | grep 2\.27 || (echo "Expected linux-aarch64 binary to require at most glibc 2.27. Ensure the dockcross container has not been updated." && false)
# echo "Checking linux-aarch64/libvoyager.so (should require at most GLIBCXX 3.4.22...)"
# objdump -T combined-jar/linux-aarch64/libvoyager.so | grep GLIBCXX | sed 's/.*GLIBCXX_\([.0-9]*\).*/\1/g' | cat - <(echo 3\.4\.22) | sort -Vu | tail -n 1 | grep 3\.4\.22 || (echo "Expected linux-aarch64 binary to require at most glibc++ 3.4.22. Ensure the dockcross container has not been updated." && false)
# echo "Checking linux-x64/libvoyager.so (should require at most GLIBC 2.27...)"
# objdump -T combined-jar/linux-x64/libvoyager.so | grep GLIBC | grep -v GLIBCXX | sed 's/.*GLIBC_\([.0-9]*\).*/\1/g' | cat - <(echo 2\.27) | sort -Vu | tail -n 1 | grep 2\.27 || (echo "Expected linux-x64 binary to require at most glibc 2.28. Ensure the dockcross container has not been updated." && false)
# echo "Checking linux-x64/libvoyager.so (should require at most GLIBCXX 3.4.22...)"
# objdump -T combined-jar/linux-x64/libvoyager.so | grep GLIBCXX | sed 's/.*GLIBCXX_\([.0-9]*\).*/\1/g' | cat - <(echo 3\.4\.22) | sort -Vu | tail -n 1 | grep 3\.4\.22 || (echo "Expected linux-x64 binary to require at most glibc++ 3.4.22. Ensure the dockcross container has not been updated." && false)
# zip -r $(ls java-* | grep jar | tail -n 1) combined-jar/*
# - uses: actions/upload-artifact@v4
# with:
# if-no-files-found: error
# name: java-all-platforms
# path: artifacts/*.jar
# upload-maven:
# name: Upload to Maven Central
# runs-on: ubuntu-latest
# needs: combine-java-jars
# if: github.event_name == 'release' && github.event.action == 'published'
# defaults:
# run:
# working-directory: java
# steps:
# - uses: actions/checkout@v3
# - uses: actions/download-artifact@v4
# with:
# name: java-all-platforms
# path: combined-jar
# - name: Set up JDK 11
# uses: actions/setup-java@v3
# with:
# java-version: 11
# distribution: "corretto"
# server-id: ossrh
# server-username: MAVEN_USERNAME
# server-password: MAVEN_USER_TOKEN
# gpg-private-key: ${{ secrets.SONATYPE_GPG_PRIVATE_KEY }}
# gpg-passphrase: MAVEN_GPG_PASSPHRASE
# - name: Deploy
# # Note: this will re-run the build even though we already have the JAR file ready to deploy
# run: |
# # Copy the native artifacts built for each platform into the appropriate place:
# unzip ../combined-jar/*.jar -d ../
# mkdir -p target/classes/
# cp -r ../combined-jar/linux* target/classes/
# cp -r ../combined-jar/mac* target/classes/
# cp -r ../combined-jar/win* target/classes/
# mvn --batch-mode deploy -Dmaven.test.skip=true
# env:
# MAVEN_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
# MAVEN_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
# MAVEN_GPG_PASSPHRASE: ${{ secrets.SONATYPE_PASSPHRASE }}
# MAVEN_USER_TOKEN: ${{ secrets.SONATYPE_USER_TOKEN }}