fix #11
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: Build and Test | |
| on: | |
| push: | |
| branches: [ main, develop ] | |
| pull_request: | |
| branches: [ main, develop ] | |
| jobs: | |
| test: | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 45 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, windows-latest, macos-latest] | |
| python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] | |
| exclude: | |
| # Exclude some combinations to reduce CI time | |
| - os: windows-latest | |
| python-version: '3.8' | |
| - os: macos-latest | |
| python-version: '3.8' | |
| - os: ubuntu-latest | |
| python-version: '3.8' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| # Platform-specific dependency installation | |
| - name: Install dependencies (Ubuntu) | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y build-essential cmake libeigen3-dev | |
| - name: Install dependencies (macOS) | |
| if: runner.os == 'macOS' | |
| run: | | |
| brew install cmake eigen | |
| - name: Install dependencies (Windows) | |
| if: runner.os == 'Windows' | |
| timeout-minutes: 20 | |
| run: | | |
| # Use chocolatey for faster installation | |
| choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System' | |
| # Install vcpkg and eigen3 with shallow clone | |
| git clone --depth 1 https://github.com/Microsoft/vcpkg.git C:\vcpkg | |
| C:\vcpkg\bootstrap-vcpkg.bat | |
| C:\vcpkg\vcpkg install eigen3:x64-windows --triplet x64-windows | |
| echo "EIGEN_INCLUDE_DIR=C:\vcpkg\installed\x64-windows\include\eigen3" >> $env:GITHUB_ENV | |
| - name: Install Python dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install numpy pybind11 pytest | |
| - name: Clean build directories (Unix) | |
| if: runner.os != 'Windows' | |
| run: | | |
| rm -rf condreg-cpp/build || true | |
| rm -rf condreg-py-interface/build || true | |
| rm -rf condreg-py-interface/condreg/*.so || true | |
| rm -rf condreg-py-interface/condreg/lib/*.so || true | |
| - name: Clean build directories (Windows) | |
| if: runner.os == 'Windows' | |
| run: | | |
| if (Test-Path "condreg-cpp\build") { Remove-Item -Recurse -Force "condreg-cpp\build" } | |
| if (Test-Path "condreg-py-interface\build") { Remove-Item -Recurse -Force "condreg-py-interface\build" } | |
| if (Test-Path "condreg-py-interface\condreg\*.pyd") { Remove-Item -Force "condreg-py-interface\condreg\*.pyd" } | |
| if (Test-Path "condreg-py-interface\condreg\lib\*.pyd") { Remove-Item -Force "condreg-py-interface\condreg\lib\*.pyd" } | |
| - name: Build C++ library | |
| timeout-minutes: 15 | |
| run: | | |
| cd condreg-py-interface | |
| python build_cpp.py | |
| - name: Verify C++ library build (Unix) | |
| if: runner.os != 'Windows' | |
| run: | | |
| cd condreg-cpp/build | |
| ls -la | |
| if [ ! -f "libcondreg.a" ] && [ ! -f "libcondreg.so" ]; then | |
| echo "Error: C++ library not found" | |
| exit 1 | |
| fi | |
| echo "C++ library build verified" | |
| - name: Verify C++ library build (Windows) | |
| if: runner.os == 'Windows' | |
| run: | | |
| cd condreg-cpp/build | |
| Get-ChildItem -Recurse | |
| if (-not (Test-Path "Release/condreg.lib") -and -not (Test-Path "Debug/condreg.lib") -and -not (Test-Path "condreg.lib")) { | |
| Write-Error "C++ library not found" | |
| exit 1 | |
| } | |
| Write-Output "C++ library build verified" | |
| - name: Build Python package | |
| run: | | |
| cd condreg-py-interface | |
| pip install -e . --verbose | |
| - name: Test import | |
| run: | | |
| python -c "import condreg; print('Import successful')" | |
| - name: Run tests | |
| run: | | |
| cd condreg-py-interface | |
| python -m pytest tests/ -v | |
| - name: Verify Python package | |
| if: runner.os != 'Windows' | |
| run: | | |
| echo "=== C++ library build successful ===" | |
| echo "=== Testing Python import ===" | |
| python -c " | |
| import sys | |
| sys.path.insert(0, '.') | |
| try: | |
| import condreg | |
| print('✓ Python import successful') | |
| import numpy as np | |
| X = np.random.randn(10, 5) | |
| result = condreg.condreg(X, kmax=2.0) | |
| print('✓ Basic functionality test passed') | |
| except Exception as e: | |
| print(f'✗ Python import/functionality test failed: {e}') | |
| import traceback | |
| traceback.print_exc() | |
| exit(1) | |
| " | |
| echo "=== Python package verification complete ===" | |
| build-wheels: | |
| name: Build wheels on ${{ matrix.os }} | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 60 | |
| strategy: | |
| matrix: | |
| os: [ubuntu-latest, windows-latest, macos-latest] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Clean platform-specific binaries | |
| run: | | |
| # Remove any existing platform-specific binaries to prevent cross-contamination | |
| find . -name "*.so" -delete 2>/dev/null || true | |
| find . -name "*.pyd" -delete 2>/dev/null || true | |
| find . -name "*.dll" -delete 2>/dev/null || true | |
| rm -rf condreg-py-interface/build 2>/dev/null || true | |
| rm -rf condreg-cpp/build 2>/dev/null || true | |
| echo "Current directory: $(pwd)" | |
| echo "Directory contents:" | |
| ls -la | |
| shell: bash | |
| - name: Build wheels | |
| uses: pypa/cibuildwheel@v2.22.0 | |
| timeout-minutes: 45 | |
| with: | |
| package-dir: ./condreg-py-interface | |
| output-dir: wheelhouse | |
| env: | |
| # Configure cibuildwheel | |
| CIBW_BUILD: cp38-* cp39-* cp310-* cp311-* cp312-* | |
| CIBW_SKIP: "*-win32 *-manylinux_i686 *-musllinux*" | |
| # Reduce build time by limiting architectures | |
| CIBW_ARCHS_LINUX: x86_64 | |
| CIBW_ARCHS_MACOS: x86_64 arm64 | |
| CIBW_ARCHS_WINDOWS: AMD64 | |
| # Install dependencies and build C++ library before building Python wheels | |
| CIBW_BEFORE_BUILD_LINUX: | | |
| set -e | |
| echo "=== Installing dependencies ===" | |
| yum install -y eigen3-devel cmake3 gcc-c++ make || | |
| (apt-get update && apt-get install -y libeigen3-dev cmake build-essential) | |
| echo "=== Cleaning previous builds ===" | |
| rm -rf condreg-cpp/build | |
| rm -rf build | |
| rm -rf condreg/*.so condreg/lib/*.so | |
| echo "=== Current directory: $(pwd) ===" | |
| echo "=== Directory contents: ===" | |
| ls -la | |
| echo "=== Checking for build_cpp.py ===" | |
| ls -la condreg-py-interface/build_cpp.py | |
| echo "=== Checking condreg-cpp directory ===" | |
| ls -la condreg-cpp/ | |
| echo "=== Checking CMake version ===" | |
| cmake --version || cmake3 --version || echo "No cmake found" | |
| echo "=== Checking GCC version ===" | |
| gcc --version || echo "No gcc found" | |
| echo "=== Checking Eigen installation ===" | |
| find /usr -name "Eigen" -type d 2>/dev/null || echo "Eigen directory not found" | |
| ls -la /usr/include/eigen3/ 2>/dev/null || echo "No eigen3 in /usr/include" | |
| echo "=== Building C++ library with Python script ===" | |
| export EIGEN_INCLUDE_DIR="/usr/include/eigen3" | |
| if ! python condreg-py-interface/build_cpp.py; then | |
| echo "Python build script failed, trying manual build..." | |
| cd condreg-cpp | |
| mkdir -p build | |
| cd build | |
| cmake_cmd="cmake" | |
| if command -v cmake3 >/dev/null 2>&1; then | |
| cmake_cmd="cmake3" | |
| fi | |
| echo "Using cmake command: $cmake_cmd" | |
| $cmake_cmd .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DEIGEN3_INCLUDE_DIR=/usr/include/eigen3 | |
| $cmake_cmd --build . --config Release | |
| cd ../.. | |
| fi | |
| echo "=== Verifying C++ library build ===" | |
| ls -la condreg-cpp/build/ || (echo "Build directory not found" && exit 1) | |
| if [ ! -f "condreg-cpp/build/libcondreg.a" ] && [ ! -f "condreg-cpp/build/libcondreg.so" ]; then | |
| echo "ERROR: C++ library not found after build" | |
| echo "Contents of build directory:" | |
| find condreg-cpp/build -type f || echo "No files found" | |
| exit 1 | |
| fi | |
| echo "=== C++ library build successful ===" | |
| CIBW_BEFORE_BUILD_MACOS: | | |
| set -e | |
| echo "=== Installing dependencies ===" | |
| brew install eigen cmake || echo "Dependencies may already be installed" | |
| echo "=== Cleaning previous builds ===" | |
| rm -rf condreg-cpp/build | |
| rm -rf build | |
| rm -rf condreg/*.so condreg/lib/*.so | |
| echo "=== Current directory: $(pwd) ===" | |
| echo "=== Directory contents: ===" | |
| ls -la | |
| echo "=== Checking for build_cpp.py ===" | |
| ls -la condreg-py-interface/build_cpp.py | |
| echo "=== Building C++ library with Python script ===" | |
| if ! python condreg-py-interface/build_cpp.py; then | |
| echo "Python build script failed, trying manual build..." | |
| cd condreg-cpp | |
| mkdir -p build | |
| cd build | |
| cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=ON | |
| cmake --build . --config Release | |
| cd ../.. | |
| fi | |
| echo "=== Verifying C++ library build ===" | |
| ls -la condreg-cpp/build/ || (echo "Build directory not found" && exit 1) | |
| if [ ! -f "condreg-cpp/build/libcondreg.a" ] && [ ! -f "condreg-cpp/build/libcondreg.so" ]; then | |
| echo "ERROR: C++ library not found after build" | |
| echo "Contents of build directory:" | |
| find condreg-cpp/build -type f || echo "No files found" | |
| exit 1 | |
| fi | |
| echo "=== C++ library build successful ===" | |
| CIBW_ENVIRONMENT_WINDOWS: EIGEN_INCLUDE_DIR=C:\vcpkg\installed\x64-windows\include\eigen3 | |
| CIBW_BEFORE_BUILD_WINDOWS: | | |
| echo "=== Installing dependencies ===" | |
| git clone --depth 1 https://github.com/Microsoft/vcpkg.git C:\vcpkg | |
| C:\vcpkg\bootstrap-vcpkg.bat | |
| C:\vcpkg\vcpkg install eigen3:x64-windows --triplet x64-windows | |
| echo "=== Cleaning previous builds ===" | |
| del /Q /S condreg-cpp\build 2>nul || echo "No build dir to clean" | |
| del /Q /S build 2>nul || echo "No build dir to clean" | |
| del /Q condreg\*.pyd condreg\lib\*.pyd 2>nul || echo "No pyd files to clean" | |
| echo "=== Current directory: %CD% ===" | |
| echo "=== Directory contents: ===" | |
| dir | |
| echo "=== Checking for build_cpp.py ===" | |
| dir condreg-py-interface\build_cpp.py | |
| echo "=== Building C++ library ===" | |
| set EIGEN_INCLUDE_DIR=C:\vcpkg\installed\x64-windows\include\eigen3 | |
| python condreg-py-interface\build_cpp.py | |
| echo "=== Verifying C++ library build ===" | |
| dir condreg-cpp\build\ || (echo "Build directory not found" && exit 1) | |
| if not exist "condreg-cpp\build\Release\condreg.lib" if not exist "condreg-cpp\build\Debug\condreg.lib" if not exist "condreg-cpp\build\condreg.lib" ( | |
| echo "ERROR: C++ library not found after build" | |
| echo "Contents of build directory:" | |
| dir /S condreg-cpp\build\ || echo "No files found" | |
| exit 1 | |
| ) | |
| echo "=== C++ library build successful ===" | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: wheels-${{ matrix.os }} | |
| path: ./wheelhouse/*.whl |