@@ -22,17 +22,14 @@ jobs:
2222 steps :
2323 - uses : actions/checkout@v4
2424 with :
25- fetch-depth : 0 # This ensures all tags are fetched
25+ fetch-depth : 0
2626
2727 - id : check
2828 run : |
29- # Check if this is a tag push
3029 if [[ "${{ github.ref }}" == refs/tags/v* ]]; then
3130 echo "is_tag=true" >> $GITHUB_OUTPUT
3231 echo "should_run=true" >> $GITHUB_OUTPUT
33- # Check if this is a branch push that's not associated with a tag creation
3432 elif [[ "${{ github.ref }}" == refs/heads/* ]] && [[ "${{ github.event_name }}" == "push" ]]; then
35- # If this commit has a tag pointing to it, skip branch-based run
3633 if git tag --points-at HEAD | grep -q "^v"; then
3734 echo "should_run=false" >> $GITHUB_OUTPUT
3835 else
4441 echo "is_tag=false" >> $GITHUB_OUTPUT
4542 fi
4643
44+ # Build wheels - one job per OS (cibuildwheel handles all Python versions)
4745 build_wheels :
4846 needs : check_duplicate
4947 if : ${{ needs.check_duplicate.outputs.should_run == 'true' }}
@@ -53,15 +51,14 @@ jobs:
5351 fail-fast : false
5452 matrix :
5553 os : [ubuntu-latest, macos-15-intel, windows-latest]
56- python-version : ['3.9', '3.10', '3.11', '3.12']
5754
5855 steps :
5956 - uses : actions/checkout@v4
6057
6158 - name : Set up Python
6259 uses : actions/setup-python@v5
6360 with :
64- python-version : ${{ matrix.python-version }}
61+ python-version : ' 3.11 '
6562
6663 - name : Install dependencies
6764 run : |
@@ -75,54 +72,42 @@ jobs:
7572 run : |
7673 sudo apt-get update
7774 sudo apt-get install -y libsuitesparse-dev libopenblas-dev libsuperlu-dev
78- # Check where SuperLU headers are located
7975 echo "SuperLU header locations:"
8076 sudo find /usr -name "slu_ddefs.h" | grep superlu
81- # Create symlinks if necessary
8277 SUPERLU_HEADER=$(sudo find /usr -name "slu_ddefs.h" | grep superlu | head -n 1)
8378 if [ -n "$SUPERLU_HEADER" ]; then
8479 SUPERLU_DIR=$(dirname "$SUPERLU_HEADER")
8580 echo "Found SuperLU headers at: $SUPERLU_DIR"
8681 if [ ! -d "/usr/include/superlu" ]; then
8782 sudo mkdir -p /usr/include/superlu
8883 sudo cp "$SUPERLU_DIR"/*.h /usr/include/superlu/
89- echo "Created SuperLU header symlinks in /usr/include/superlu/"
9084 fi
9185 fi
9286
93- # Windows specific setup - uses vendor libraries checked into the repo
87+ # Windows specific setup
9488 - name : Install Windows dependencies
9589 if : runner.os == 'Windows'
9690 shell : bash
9791 run : |
98- # MinGW-w64 is pre-installed on windows-latest runner
9992 echo "Checking MinGW..."
10093 gcc --version || (echo "MinGW not found, installing..." && choco install mingw -y --no-progress)
101- # Find MinGW bin directory and add to PATH
10294 MINGW_BIN=$(dirname "$(which gcc)")
10395 echo "MinGW bin: $MINGW_BIN"
10496 echo "$MINGW_BIN" >> $GITHUB_PATH
105- # Verify vendor libraries exist (these are checked into the repo)
10697 echo "Checking vendor libraries..."
10798 ls -la vendor/superlu/lib/ || echo "WARNING: SuperLU libs not found"
10899 ls -la vendor/superlu/bin/ || echo "WARNING: SuperLU bin not found"
109100 ls -la vendor/openblas/bin/ || echo "WARNING: OpenBLAS bin not found"
110- ls -la vendor/superlu/include/ || echo "WARNING: SuperLU headers not found"
111101
112102 # macOS specific setup
113103 - name : Install macOS dependencies
114104 if : runner.os == 'macOS'
115105 run : |
116106 brew install suite-sparse superlu openblas
117- # Debug: Check the openblas library location
118107 export OPENBLAS_PREFIX=$(brew --prefix openblas)
119108 echo "OpenBLAS prefix: $OPENBLAS_PREFIX"
120- echo "OpenBLAS library paths:"
121- find $OPENBLAS_PREFIX -name "*.dylib"
122- # Use the home directory for temporary symlinks (avoid permission issues)
123109 mkdir -p $HOME/homebrew_libs/openblas/lib
124110 ln -sf $OPENBLAS_PREFIX/lib/libopenblas.dylib $HOME/homebrew_libs/openblas/lib/
125- echo "Created symlink in $HOME/homebrew_libs/openblas/lib/"
126111 echo "OPENBLAS_PREFIX=$OPENBLAS_PREFIX" >> $GITHUB_ENV
127112 echo "HOME_LIBS=$HOME/homebrew_libs" >> $GITHUB_ENV
128113
@@ -131,46 +116,35 @@ jobs:
131116 env :
132117 CIBW_BUILD : ' cp39-* cp310-* cp311-* cp312-*'
133118 CIBW_SKIP : ' *-musllinux*'
134- # Add this to ensure extensions are built
135119 CIBW_BEFORE_BUILD : >
136120 pip install numpy cython
137- # Make compilation more verbose to see errors
138121 CIBW_BUILD_VERBOSITY : 1
139- CIBW_ARCHS_MACOS : ' x86_64' # Just x86_64 for CI builds
122+ CIBW_ARCHS_MACOS : ' x86_64'
140123 CIBW_ARCHS_LINUX : ' x86_64'
141- # Set CI flag for setup.py
142124 CIBW_ENVIRONMENT : >
143125 CI=true
144126 GITHUB_ACTIONS=true
145127 CFLAGS='-O3'
146128 CXXFLAGS='-O3'
147- # macOS specific environment variables
148129 CIBW_ENVIRONMENT_MACOS : >
149130 CI=true
150131 GITHUB_ACTIONS=true
151132 CFLAGS='-O3'
152133 CXXFLAGS='-O3'
153134 MACOSX_DEPLOYMENT_TARGET=15.0
154- # manylinux configuration - install required packages
155135 CIBW_MANYLINUX_X86_64_IMAGE : manylinux2014
156136 CIBW_BEFORE_ALL_LINUX : |
157137 yum install -y epel-release || true
158138 yum install -y openblas-devel SuperLU-devel suitesparse-devel ||
159139 yum install -y openblas-devel superlu-devel suitesparse-devel ||
160140 (apt-get update && apt-get install -y libsuitesparse-dev libsuperlu-dev libopenblas-dev)
161-
162- # Check SuperLU header location
163141 find /usr -name "slu_ddefs.h" || echo "SuperLU headers not found"
164-
165- # If header is found, create a symlink in a standard location
166142 HEADER_PATH=$(find /usr -name "slu_ddefs.h" | head -1)
167143 if [ -n "$HEADER_PATH" ]; then
168144 HEADER_DIR=$(dirname "$HEADER_PATH")
169145 mkdir -p /tmp/superlu_include
170- # Use a conditional copy to avoid errors when no headers match
171146 if [ -f "$HEADER_DIR/slu_ddefs.h" ]; then
172147 cp "$HEADER_DIR"/*.h /tmp/superlu_include/ 2>/dev/null || true
173- echo "Copied SuperLU headers to /tmp/superlu_include/"
174148 fi
175149 fi
176150 CIBW_BEFORE_ALL_MACOS : >
@@ -180,7 +154,6 @@ jobs:
180154 mkdir -p $HOME/homebrew_libs/openblas/lib;
181155 ln -sf $OPENBLAS_PREFIX/lib/libopenblas.dylib $HOME/homebrew_libs/openblas/lib/;
182156 echo "Created symlink in $HOME/homebrew_libs/openblas/lib/"
183- # Windows configuration - use vendor libraries from the repo with MinGW
184157 CIBW_ARCHS_WINDOWS : ' AMD64'
185158 CIBW_ENVIRONMENT_WINDOWS : >
186159 CI=true
@@ -195,15 +168,22 @@ jobs:
195168 run : |
196169 python -m cibuildwheel --output-dir wheelhouse
197170
198- # Store the built wheels
171+ # List built wheels for debugging
172+ - name : List built wheels
173+ shell : bash
174+ run : |
175+ echo "Built wheels:"
176+ ls -la wheelhouse/
177+
178+ # Store the built wheels (one artifact per OS, containing all Python versions)
199179 - name : Upload wheels as artifacts
200180 uses : actions/upload-artifact@v4
201181 with :
202- name : wheels-${{ matrix.os }}-${{ matrix.python-version }}
182+ name : wheels-${{ matrix.os }}
203183 path : |
204184 ./wheelhouse/*.whl
205185
206- # Test job that runs after the wheels are built
186+ # Test job - test each Python version per OS
207187 test_installation :
208188 needs : [check_duplicate, build_wheels]
209189 if : ${{ needs.check_duplicate.outputs.should_run == 'true' }}
@@ -215,42 +195,30 @@ jobs:
215195 # Linux x86_64
216196 - os : ubuntu-latest
217197 python-version : ' 3.9'
218- wheel-suffix : ' manylinux_2_17_x86_64.manylinux2014_x86_64'
219198 - os : ubuntu-latest
220199 python-version : ' 3.10'
221- wheel-suffix : ' manylinux_2_17_x86_64.manylinux2014_x86_64'
222200 - os : ubuntu-latest
223201 python-version : ' 3.11'
224- wheel-suffix : ' manylinux_2_17_x86_64.manylinux2014_x86_64'
225202 - os : ubuntu-latest
226203 python-version : ' 3.12'
227- wheel-suffix : ' manylinux_2_17_x86_64.manylinux2014_x86_64'
228204 # macOS x86_64 (Intel)
229205 - os : macos-15-intel
230206 python-version : ' 3.9'
231- wheel-suffix : ' macosx_15_0_x86_64'
232207 - os : macos-15-intel
233208 python-version : ' 3.10'
234- wheel-suffix : ' macosx_15_0_x86_64'
235209 - os : macos-15-intel
236210 python-version : ' 3.11'
237- wheel-suffix : ' macosx_15_0_x86_64'
238211 - os : macos-15-intel
239212 python-version : ' 3.12'
240- wheel-suffix : ' macosx_15_0_x86_64'
241213 # Windows x86_64
242214 - os : windows-latest
243215 python-version : ' 3.9'
244- wheel-suffix : ' win_amd64'
245216 - os : windows-latest
246217 python-version : ' 3.10'
247- wheel-suffix : ' win_amd64'
248218 - os : windows-latest
249219 python-version : ' 3.11'
250- wheel-suffix : ' win_amd64'
251220 - os : windows-latest
252221 python-version : ' 3.12'
253- wheel-suffix : ' win_amd64'
254222
255223 steps :
256224 - uses : actions/checkout@v4
@@ -263,9 +231,15 @@ jobs:
263231 - name : Download wheel artifacts
264232 uses : actions/download-artifact@v4
265233 with :
266- name : wheels-${{ matrix.os }}-${{ matrix.python-version }}
234+ name : wheels-${{ matrix.os }}
267235 path : ./wheelhouse
268236
237+ - name : List available wheels
238+ shell : bash
239+ run : |
240+ echo "Available wheels:"
241+ ls -la wheelhouse/
242+
269243 - name : Install Linux dependencies
270244 if : runner.os == 'Linux'
271245 run : |
@@ -277,90 +251,64 @@ jobs:
277251 run : |
278252 brew install suite-sparse superlu openblas
279253
280- - name : Inspect linux wheel contents
281- if : runner.os == 'Linux'
282- run : |
283- python -m pip install wheel-inspect
284- PYTHON_VERSION_NO_DOT=$(echo ${{ matrix.python-version }} | tr -d '.')
285- WHEEL_FILE=$(ls wheelhouse/sparse_numba-*-cp${PYTHON_VERSION_NO_DOT}-*-${{ matrix.wheel-suffix }}.whl | head -n 1)
286- python -m wheel_inspect $WHEEL_FILE
287- unzip -l $WHEEL_FILE | grep "cy_.*wrapper"
288-
289- - name : Inspect macOS wheel contents
290- if : runner.os == 'macOS'
291- run : |
292- python -m pip install wheel-inspect
293- PYTHON_VERSION_NO_DOT=$(echo ${{ matrix.python-version }} | tr -d '.')
294- WHEEL_FILE=$(ls wheelhouse/sparse_numba-*-cp${PYTHON_VERSION_NO_DOT}-*-${{ matrix.wheel-suffix }}.whl | head -n 1)
295- unzip -l $WHEEL_FILE | grep "cy_.*wrapper"
296-
297254 - name : Install the wheel (Unix)
298255 if : runner.os != 'Windows'
299256 run : |
300257 python -m pip install --upgrade pip
301258 python -m pip install numpy numba
302- # List available wheels to debug
303- echo "Available wheels:"
304- ls -la wheelhouse/
305- # Install the specific wheel for this platform/Python combination
259+ # Find matching wheel using pip directly (handles platform tags automatically)
306260 PYTHON_VERSION_NO_DOT=$(echo ${{ matrix.python-version }} | tr -d '.')
307- WHEEL_FILE=$(ls wheelhouse/sparse_numba-*-cp${PYTHON_VERSION_NO_DOT}-*-${{ matrix.wheel-suffix }}.whl | head -n 1)
308-
261+ WHEEL_FILE=$(ls wheelhouse/sparse_numba-*-cp${PYTHON_VERSION_NO_DOT}-*.whl | head -n 1)
309262 if [ -z "$WHEEL_FILE" ]; then
310- echo "Error: No matching wheel found for Python ${{ matrix.python-version }} and suffix ${{ matrix.wheel-suffix }}"
263+ echo "Error: No matching wheel found for Python ${{ matrix.python-version }}"
264+ echo "Available wheels:"
265+ ls wheelhouse/*.whl
311266 exit 1
312267 fi
313268 echo "Installing wheel: $WHEEL_FILE"
314- python -m pip install $WHEEL_FILE --verbose
269+ python -m pip install " $WHEEL_FILE" --verbose
315270
316271 - name : Install the wheel (Windows)
317272 if : runner.os == 'Windows'
318273 shell : pwsh
319274 run : |
320275 python -m pip install --upgrade pip
321276 python -m pip install numpy numba
322- # List available wheels
323- Write-Host "Available wheels:"
324- Get-ChildItem wheelhouse/ -Filter *.whl
325- # Find and install the matching wheel
326277 $pyver = "${{ matrix.python-version }}" -replace '\.', ''
327- $wheel = Get-ChildItem wheelhouse/sparse_numba-*-cp${pyver}-*-${{ matrix.wheel-suffix }} .whl | Select-Object -First 1
278+ $wheel = Get-ChildItem wheelhouse/sparse_numba-*-cp${pyver}-*.whl | Select-Object -First 1
328279 if (-not $wheel) {
329280 Write-Error "No matching wheel found"
281+ Get-ChildItem wheelhouse/*.whl
330282 exit 1
331283 }
332284 Write-Host "Installing wheel: $($wheel.FullName)"
333285 python -m pip install $wheel.FullName --verbose
334286
335287 - name : Run tests (Unix)
336288 if : runner.os != 'Windows'
289+ env :
290+ KMP_DUPLICATE_LIB_OK : ' TRUE'
337291 run : |
338- # Create a clean virtual environment
339292 python -m venv test_venv
340293 source test_venv/bin/activate
341294 python -m pip install --upgrade pip
342295 python -m pip install numpy numba
343- # Install wheel
344296 PYTHON_VERSION_NO_DOT=$(echo ${{ matrix.python-version }} | tr -d '.')
345- pip install wheelhouse/sparse_numba-*-cp${PYTHON_VERSION_NO_DOT}-*-*.whl
346- # Copy the test script to a new location
297+ pip install wheelhouse/sparse_numba-*-cp${PYTHON_VERSION_NO_DOT}-*.whl
347298 mkdir -p /tmp/test_dir
348299 cp run_tests.py /tmp/test_dir/
349- # Change to the new directory and run tests
350300 cd /tmp/test_dir
351- python run_tests.py
301+ KMP_DUPLICATE_LIB_OK=TRUE python run_tests.py
352302
353303 - name : Run tests (Windows)
354304 if : runner.os == 'Windows'
355305 shell : pwsh
356306 run : |
357- # Install directly (no venv needed for isolation in CI)
358307 python -m pip install --upgrade pip
359308 python -m pip install numpy numba
360309 $pyver = "${{ matrix.python-version }}" -replace '\.', ''
361- $wheel = Get-ChildItem wheelhouse/sparse_numba-*-cp${pyver}-*-* .whl | Select-Object -First 1
310+ $wheel = Get-ChildItem wheelhouse/sparse_numba-*-cp${pyver}-*.whl | Select-Object -First 1
362311 python -m pip install $wheel.FullName
363- # Copy test script to temp dir and run from there
364312 $testDir = Join-Path $env:RUNNER_TEMP "test_dir"
365313 New-Item -ItemType Directory -Force -Path $testDir
366314 Copy-Item run_tests.py $testDir/
@@ -435,6 +383,8 @@ jobs:
435383 mkdir -p final_dist
436384 cp wheelhouse/*.whl final_dist/
437385 cp dist/*.tar.gz final_dist/
386+ echo "Files to upload:"
387+ ls -la final_dist/
438388
439389 - name : Publish to PyPI
440390 uses : pypa/gh-action-pypi-publish@release/v1
0 commit comments