Skip to content

Cleanup

Cleanup #898

Workflow file for this run

name: Python test / linting
env:
TRIGGER_ON_PR_PUSH: true # Set to true to enable triggers on PR pushes
RUSTFLAGS: -C debuginfo=0
RUST_BACKTRACE: 1
PYTHONUTF8: 1
LLVM_VERSION: "14.0.6"
on:
push:
branches: [ "main", "master", "development", "dev" ]
pull_request:
branches: [ "main", "master", "development", "dev" ]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
python-test:
runs-on: ${{ matrix.os }}
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
# Full Python version matrix on Ubuntu (fast)
os: [ubuntu-latest]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
include:
# Windows/macOS: only test oldest and newest stable Python (slow platforms)
- os: windows-latest
python-version: "3.10"
- os: windows-latest
python-version: "3.14"
- os: macOS-latest
python-version: "3.10"
- os: macOS-latest
python-version: "3.14"
steps:
- name: Free Disk Space (Ubuntu)
if: runner.os == 'Linux'
uses: jlumbroso/free-disk-space@v1.3.1
with:
android: true
dotnet: true
haskell: true
large-packages: false
docker-images: true
tool-cache: false
swap-storage: true
- name: Free Disk Space (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
Remove-Item -Path "C:\Android" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -Path "C:\Program Files\dotnet" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -Path "C:\hostedtoolcache\CodeQL" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -Path "C:\ProgramData\chocolatey" -Recurse -Force -ErrorAction SilentlyContinue
- uses: actions/checkout@v6
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Set up Visual Studio environment on Windows
if: runner.os == 'Windows'
uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
- name: Install the latest version of uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Set up Rust
run: rustup show
- name: Install just
uses: extractions/setup-just@v3
- name: Cache Rust
uses: Swatinem/rust-cache@v2
with:
workspaces: |
python/pecos-rslib
python/pecos-rslib-llvm
# Cache LLVM installation (fixed version, only varies by OS)
- name: Cache LLVM ${{ env.LLVM_VERSION }}
id: cache-llvm
uses: actions/cache@v4
with:
path: ~/.pecos/deps/llvm-14
key: llvm-${{ env.LLVM_VERSION }}-${{ runner.os }}-${{ runner.arch }}
# Install LLVM first (needed before CLI install since inkwell requires LLVM_SYS_140_PREFIX)
# Use cargo run for LLVM install — only builds pecos+pecos-build, not the full workspace
- name: Install LLVM ${{ env.LLVM_VERSION }} (Unix)
if: steps.cache-llvm.outputs.cache-hit != 'true' && runner.os != 'Windows'
run: cargo run -p pecos-cli --release -- install llvm
# Configure MSVC linker BEFORE any cargo build (Git's link.exe conflicts with MSVC's)
- name: Configure MSVC linker (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
$vsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
$vsPath = & $vsWhere -latest -property installationPath
$linkPath = Get-ChildItem -Path "$vsPath\VC\Tools\MSVC" -Recurse -Filter "link.exe" |
Where-Object { $_.FullName -like "*\bin\Hostx64\x64\*" } |
Select-Object -First 1 -ExpandProperty FullName
if ($linkPath) {
New-Item -ItemType Directory -Force -Path .cargo | Out-Null
$escapedPath = $linkPath.Replace('\', '/')
"[target.x86_64-pc-windows-msvc]`nlinker = `"$escapedPath`"" | Out-File -FilePath ".cargo\config.toml" -Encoding UTF8
} else {
Write-Error "Could not find MSVC link.exe"
exit 1
}
- name: Install LLVM ${{ env.LLVM_VERSION }} (Windows)
if: steps.cache-llvm.outputs.cache-hit != 'true' && runner.os == 'Windows'
run: cargo run -p pecos-cli --release -- install llvm
# Configure LLVM environment
- name: Configure LLVM environment (Unix)
if: runner.os != 'Windows'
run: |
PECOS_LLVM=$(cargo run -p pecos-cli --release -- llvm find 2>/dev/null)
echo "PECOS_LLVM=$PECOS_LLVM" >> $GITHUB_ENV
echo "LLVM_SYS_140_PREFIX=$PECOS_LLVM" >> $GITHUB_ENV
- name: Configure LLVM environment (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
$env:PECOS_LLVM = (cargo run -p pecos-cli --release -- llvm find 2>$null)
$env:LLVM_SYS_140_PREFIX = $env:PECOS_LLVM
"PECOS_LLVM=$env:PECOS_LLVM" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
"LLVM_SYS_140_PREFIX=$env:LLVM_SYS_140_PREFIX" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
# Add LLVM bin to PATH
$llvmBinDir = Join-Path -Path $env:PECOS_LLVM -ChildPath "bin"
if (Test-Path $llvmBinDir) {
"$llvmBinDir" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
}
# Rewrite .cargo/config.toml with both linker and LLVM config
# (pecos install llvm may have already written this, so overwrite cleanly)
$vsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
$vsPath = & $vsWhere -latest -property installationPath
$linkPath = Get-ChildItem -Path "$vsPath\VC\Tools\MSVC" -Recurse -Filter "link.exe" |
Where-Object { $_.FullName -like "*\bin\Hostx64\x64\*" } |
Select-Object -First 1 -ExpandProperty FullName
$escapedLinker = $linkPath.Replace('\', '/')
$escapedLLVM = $env:LLVM_SYS_140_PREFIX.Replace('\', '/')
@"
[target.x86_64-pc-windows-msvc]
linker = "$escapedLinker"
[env]
LLVM_SYS_140_PREFIX = { value = "$escapedLLVM", force = true }
"@ | Out-File -FilePath ".cargo\config.toml" -Encoding UTF8
# Now install CLI (LLVM env is set, inkwell can find it)
- name: Install PECOS CLI
run: cargo install --path crates/pecos-cli --force
# macOS: prevent Homebrew library path issues
- name: Configure macOS environment
if: runner.os == 'macOS'
run: |
# Prevent Homebrew library paths from causing @rpath/libunwind errors
# Reference: https://github.com/rust-lang/rust/issues/135372
echo "MPLBACKEND=Agg" >> $GITHUB_ENV
echo "OPENBLAS_NUM_THREADS=1" >> $GITHUB_ENV
echo "MKL_NUM_THREADS=1" >> $GITHUB_ENV
echo "NUMEXPR_NUM_THREADS=1" >> $GITHUB_ENV
echo "OMP_NUM_THREADS=1" >> $GITHUB_ENV
echo "LIBRARY_PATH=/usr/lib" >> $GITHUB_ENV
- name: Build PECOS (macOS)
if: runner.os == 'macOS'
run: |
# Prevent Homebrew library paths from causing @rpath/libunwind errors
unset LIBRARY_PATH LD_LIBRARY_PATH DYLD_LIBRARY_PATH DYLD_FALLBACK_LIBRARY_PATH PKG_CONFIG_PATH
export LIBRARY_PATH=/usr/lib
just build-debug
- name: Build PECOS
if: runner.os != 'macOS'
run: just build-debug
- name: Verify macOS extension module
if: runner.os == 'macOS'
run: |
EXT_MODULE=$(find .venv/lib -name "pecos_rslib*.so" 2>/dev/null | head -1)
if [ -n "$EXT_MODULE" ]; then
if otool -L "$EXT_MODULE" | grep -q "@rpath/libunwind"; then
echo "ERROR: Extension has @rpath/libunwind reference"
otool -L "$EXT_MODULE"
exit 1
fi
echo "macOS extension module OK"
fi
- name: Run Python tests
run: just pytest
- name: Run linting
run: just lint check