Skip to content

fix

fix #14

Workflow file for this run

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:/eigen3/include
EIGEN3_INCLUDE_DIR=C:/eigen3/include
CMAKE_PREFIX_PATH=C:/vcpkg/installed/x64-windows
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 "=== Setting up Eigen for Python build ==="
mkdir C:\eigen3 2>nul || echo "Directory exists"
mkdir C:\eigen3\include 2>nul || echo "Directory exists"
xcopy /E /I /Y C:\vcpkg\installed\x64-windows\include\eigen3 C:\eigen3\include
echo "=== Verifying Eigen installation ==="
dir C:\eigen3\include\Eigen
echo "=== Also copying to vcpkg standard location ==="
xcopy /E /I /Y C:\vcpkg\installed\x64-windows\include\eigen3 C:\vcpkg\installed\x64-windows\include
dir C:\vcpkg\installed\x64-windows\include\Eigen
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