Build Wheels for Sequenzo #140
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
| # GitHub Actions workflow for Sequenzo package | |
| name: Build Wheels for Sequenzo | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| pull_request: | |
| branches: [ main ] | |
| workflow_dispatch: | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| jobs: | |
| build: | |
| name: Build ${{ matrix.os }} Py${{ matrix.python-version }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| python-version: ['3.9', '3.10', '3.11'] | |
| steps: | |
| - name: Checkout source with submodules | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Set up Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| # Add OpenMP support | |
| - name: Install OpenMP (macOS) | |
| if: runner.os == 'macOS' | |
| run: | | |
| brew install libomp | |
| echo "CC=clang" >> $GITHUB_ENV | |
| echo "CXX=clang++" >> $GITHUB_ENV | |
| echo "LDFLAGS=-L$(brew --prefix libomp)/lib" >> $GITHUB_ENV | |
| echo "CPPFLAGS=-I$(brew --prefix libomp)/include" >> $GITHUB_ENV | |
| echo "SEQUENZO_ENABLE_OPENMP=1" >> $GITHUB_ENV | |
| - name: Install OpenMP (Linux) | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libomp-dev | |
| echo "SEQUENZO_ENABLE_OPENMP=1" >> $GITHUB_ENV | |
| - name: Setup MSVC with OpenMP (Windows) | |
| if: runner.os == 'Windows' | |
| uses: ilammy/msvc-dev-cmd@v1 | |
| with: | |
| arch: x64 | |
| - name: Enable OpenMP (Windows) | |
| if: runner.os == 'Windows' | |
| run: | | |
| echo "SEQUENZO_ENABLE_OPENMP=1" >> $env:GITHUB_ENV | |
| # Install dependencies | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install --prefer-binary "numpy<2.0" "scipy<1.14" memory_profiler | |
| pip install --prefer-binary Cython pybind11 build "cibuildwheel==2.23.3" twine | |
| pip install --prefer-binary fastcluster || echo "fastcluster installation attempted" | |
| - name: Build Cython wheels on macOS | |
| if: runner.os == 'macOS' | |
| run: | | |
| python setup.py build_ext --inplace | |
| python -m build | |
| - name: Clean previous build outputs | |
| if: runner.os != 'macOS' | |
| run: | | |
| rm -rf build/ dist/ *.egg-info | |
| find . -name "*.so" -delete | |
| shell: bash | |
| - name: Build wheels with cibuildwheel | |
| if: runner.os != 'macOS' | |
| run: python -m cibuildwheel --output-dir dist | |
| env: | |
| CIBW_SKIP: "*-musllinux*" | |
| CIBW_ARCHS_WINDOWS: "AMD64" | |
| CIBW_ARCHS_LINUX: "x86_64" | |
| CIBW_BUILD_VERBOSITY: "1" | |
| # Environment variables | |
| CIBW_ENVIRONMENT_LINUX: SEQUENZO_ENABLE_OPENMP=1 | |
| CIBW_ENVIRONMENT_WINDOWS: SEQUENZO_ENABLE_OPENMP=1 DISTUTILS_USE_SDK=1 | |
| # Linux: install system dependencies | |
| CIBW_BEFORE_BUILD_LINUX: > | |
| yum install -y libgomp-devel || | |
| apt-get update && apt-get install -y libomp-dev || | |
| echo "System dependencies installation attempted" | |
| # Windows: use only precompiled packages | |
| CIBW_BEFORE_BUILD_WINDOWS: > | |
| pip install --only-binary=all memory_profiler numpy scipy || | |
| pip install memory_profiler --only-binary=all numpy || | |
| pip install memory_profiler | |
| # Universal dependency installation (fallback) | |
| CIBW_BEFORE_BUILD: > | |
| pip install --prefer-binary memory_profiler numpy scipy || | |
| pip install memory_profiler | |
| # Test command | |
| CIBW_TEST_COMMAND: > | |
| python -c "import sequenzo; print('Sequenzo import successful'); | |
| import importlib; | |
| mod = importlib.util.find_spec('sequenzo.clustering.clustering_c_code'); | |
| print('C++ extensions loaded' if mod else 'WARNING: C++ extensions not found')" | |
| - name: Show dist content | |
| run: ls -lah dist/ | |
| shell: bash | |
| - name: Check wheels | |
| run: twine check dist/* | |
| - name: Verify OpenMP Support | |
| run: | | |
| echo "=== Verifying built wheels ===" | |
| python -c " | |
| import subprocess | |
| import sys | |
| import os | |
| wheel_files = [f for f in os.listdir('dist') if f.endswith('.whl') and 'cp${{ matrix.python-version }}' in f.replace('.', '')] | |
| if wheel_files: | |
| wheel_file = wheel_files[0] | |
| print(f'Installing wheel: {wheel_file}') | |
| subprocess.run([sys.executable, '-m', 'pip', 'install', '--force-reinstall', f'dist/{wheel_file}'], check=True) | |
| import sequenzo | |
| print('Sequenzo import successful') | |
| try: | |
| import sequenzo.clustering.clustering_c_code as cc | |
| print('C++ extensions loaded successfully') | |
| except ImportError as e: | |
| print(f'WARNING: C++ extensions loading failed: {e}') | |
| else: | |
| print('ERROR: No matching wheel files found') | |
| " | |
| shell: bash | |
| - name: Upload wheels | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: wheels-${{ matrix.os }}-${{ matrix.python-version }} | |
| path: dist/ |