Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 156 additions & 0 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,159 @@ jobs:
OUTPUT=$(python -c "from cuvis_il import cuvis_il; print(cuvis_il.cuvis_version_swig())")
echo "Version output: $OUTPUT"
echo "$OUTPUT" | grep -q "CUBERT SDK" || (echo "Version check failed!" && exit 1)

setup-windows-deps:
needs: prepare
runs-on: windows-latest
steps:
- name: Cache CUVIS SDK zip
id: cache-cuvis-zip
uses: actions/cache@v4
with:
path: ${{ github.workspace }}\cuvis_sdk.zip
key: cuvis-sdk-zip-windows-${{ needs.prepare.outputs.cuvis_version }}

- name: Download CUVIS SDK zip
if: steps.cache-cuvis-zip.outputs.cache-hit != 'true'
shell: pwsh
env:
CUVIS_VERSION: ${{ needs.prepare.outputs.cuvis_version }}
run: |
$v = $env:CUVIS_VERSION
$vn = $v -replace '\.', ''
Invoke-WebRequest "https://cloud.cubert-gmbh.de/s/cuvis_sdk_release_ver_$vn/download" -OutFile cuvis_sdk.zip

build-and-test-windows:
needs: [prepare, setup-windows-deps]
strategy:
fail-fast: false
matrix:
python: ["3.10", "3.11", "3.12", "3.13", "3.14"]
include:
- { python: "3.10", numpy: "2.0.0" }
- { python: "3.11", numpy: "2.0.0" }
- { python: "3.12", numpy: "2.0.0" }
- { python: "3.13", numpy: "2.1.0" }
- { python: "3.14", numpy: "2.3.2" }
runs-on: windows-latest

steps:
- name: Install SWIG 4.2.1
shell: pwsh
run: |
winget install --id SWIG.SWIG --version 4.2.1 --silent --accept-package-agreements --accept-source-agreements
$swigPkg = Get-ChildItem "$env:LOCALAPPDATA\Microsoft\WinGet\Packages" -Directory | Where-Object { $_.Name -like "SWIG.SWIG_*" } | Select-Object -First 1
$swigExe = Get-ChildItem $swigPkg.FullName -Recurse -Filter "swig.exe" | Select-Object -First 1
echo "SWIG_EXECUTABLE=$($swigExe.FullName)" >> $env:GITHUB_ENV
echo "SWIG_DIR=$(Join-Path $swigExe.DirectoryName 'Lib')" >> $env:GITHUB_ENV

- name: Restore CUVIS SDK zip
uses: actions/cache@v4
with:
path: ${{ github.workspace }}\cuvis_sdk.zip
key: cuvis-sdk-zip-windows-${{ needs.prepare.outputs.cuvis_version }}
fail-on-cache-miss: true

- name: Install CUVIS SDK
shell: pwsh
env:
CUVIS_VERSION: ${{ needs.prepare.outputs.cuvis_version }}
run: |
$v = $env:CUVIS_VERSION
Expand-Archive "${{ github.workspace }}\cuvis_sdk.zip" -DestinationPath cuvis_sdk
$installer = Get-ChildItem "cuvis_sdk\Cuvis $v\" -Recurse -Filter "Cuvis_C_SDK_Installer_*.exe" | Select-Object -First 1
Write-Output "Installing: $($installer.FullName)"

$logDir = Join-Path $env:RUNNER_TEMP 'cuvis_install'
New-Item -ItemType Directory -Force -Path $logDir | Out-Null
$nsisLog = Join-Path $logDir 'install.log'
$cuvisDir = 'C:\Program Files\Cuvis'
$cuvisBin = Join-Path $cuvisDir 'bin'

# WORKAROUND for a bug in the current Cuvis_C_SDK_Installer (NSIS): $SILENT is never set under /S,
# so its bundled runtime driver MSIs (C:\Program Files\Cuvis\Runtime\*.msi, e.g. WavesSetup222.msi)
# launch via `msiexec /i ... /passive` instead of /quiet. /passive pops a GUI that nobody dismisses
# on a headless runner, so the installer's ExecWait hangs forever. We kill those stuck interactive
# msiexec processes so the installer finishes, then re-install the runtime MSIs ourselves with /qn.
# Those driver components are secondary -> their failure must not fail the job.
# Upstream fix for future installer versions: branch the runtime-MSI calls on ${Silent}, use /quiet.
$proc = Start-Process $installer.FullName -ArgumentList '/S', "/LOG=$nsisLog", '/NORESTART' -PassThru
$timeoutSec = 600; $elapsed = 0; $grace = 20; $firstSeen = @{}
while (-not $proc.HasExited -and $elapsed -lt $timeoutSec) {
Start-Sleep -Seconds 10; $elapsed += 10
Get-CimInstance Win32_Process | Where-Object {
$_.Name -eq 'msiexec.exe' -and $_.CommandLine -and
$_.CommandLine -match 'Cuvis' -and $_.CommandLine -match '\.msi' -and $_.CommandLine -notmatch '/q' } |
ForEach-Object {
if (-not $firstSeen.ContainsKey($_.ProcessId)) {
$firstSeen[$_.ProcessId] = $elapsed
Write-Output "Detected interactive runtime sub-installer (PID $($_.ProcessId)): $($_.CommandLine)"
} elseif ($elapsed - $firstSeen[$_.ProcessId] -ge $grace) {
Write-Output "Killing stuck sub-installer PID $($_.ProcessId) so the main installer can continue."
Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue
}
}
Write-Output "== t=${elapsed}s : installer running =="
}

if ($proc.HasExited) { Write-Output "Installer exit code: $($proc.ExitCode)" }
else { Write-Output "::warning::Installer still running at ${timeoutSec}s - terminating."; Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue }

if (-not (Test-Path "$cuvisBin\*.dll")) {
Write-Output "::error::core CUVIS SDK missing under $cuvisBin"
if (Test-Path $nsisLog) { Write-Output '----- NSIS install.log -----'; Get-Content $nsisLog }
exit 1
}

Get-ChildItem (Join-Path $cuvisDir 'Runtime') -Filter *.msi -ErrorAction SilentlyContinue | ForEach-Object {
$msiLog = Join-Path $logDir ($_.BaseName + '.log')
$p = Start-Process msiexec -Wait -PassThru -ArgumentList '/i', "`"$($_.FullName)`"", '/qn', '/norestart', '/l*v', "`"$msiLog`""
Write-Output "Runtime component $($_.Name) -> msiexec exit $($p.ExitCode)"
}

Write-Output "CUVIS SDK installed:"; Get-ChildItem $cuvisBin | Select-Object -First 20 | Format-Table -Auto | Out-String | Write-Output

- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive

- name: Setup Python ${{ matrix.python }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}

- name: Create venv and install Python build dependencies
shell: pwsh
run: |
python -m venv venv
.\venv\Scripts\Activate.ps1
python -m pip install --upgrade pip setuptools wheel build
python -m pip install numpy==${{ matrix.numpy }}

- name: CMake configure and build
shell: pwsh
env:
CUVIS: C:\Program Files\Cuvis
run: |
$env:PATH += ";C:\Program Files\Cuvis\bin"
cmake "-DCMAKE_BUILD_TYPE=Release" "-DDOXYGEN_BUILD_DOCUMENTATION=FALSE" "-DSWIG_DIR=$env:SWIG_DIR" "-DSWIG_EXECUTABLE=$env:SWIG_EXECUTABLE" "-DPython_ROOT_DIR=${{ github.workspace }}\venv" "-DCMAKE_PREFIX_PATH=$env:CUVIS" -B build .
cmake --build build --target cuvis_pyil --config Release

- name: Copy built files and install package
shell: bash
run: |
chmod +x ./copy_pyil_files.sh
./copy_pyil_files.sh build/Release
source venv/Scripts/activate
pip install .

- name: Smoke test - verify import and version
shell: pwsh
env:
CUVIS: C:\Program Files\Cuvis\bin
run: |
.\venv\Scripts\Activate.ps1
$output = python -c "from cuvis_il import cuvis_il; print(cuvis_il.cuvis_version_swig())"
Write-Output "Version output: $output"
if ($output -notmatch "CUBERT SDK") { Write-Output "Version check failed!"; exit 1 }
177 changes: 176 additions & 1 deletion .github/workflows/publish_version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,183 @@ jobs:
name: wheel-ubuntu${{ matrix.ubuntu }}-py${{ matrix.python }}-${{ matrix.arch }}
path: dist/*.whl

setup-windows-deps:
needs: prepare
runs-on: windows-latest
steps:
- name: Cache CUVIS SDK zip
id: cache-cuvis-zip
uses: actions/cache@v4
with:
path: ${{ github.workspace }}\cuvis_sdk.zip
key: cuvis-sdk-zip-windows-${{ needs.prepare.outputs.cuvis_version }}

- name: Download CUVIS SDK zip
if: steps.cache-cuvis-zip.outputs.cache-hit != 'true'
shell: pwsh
env:
CUVIS_VERSION: ${{ needs.prepare.outputs.cuvis_version }}
run: |
$v = $env:CUVIS_VERSION
$vn = $v -replace '\.', ''
Invoke-WebRequest "https://cloud.cubert-gmbh.de/s/cuvis_sdk_release_ver_$vn/download" -OutFile cuvis_sdk.zip

build-windows:
needs: [prepare, setup-windows-deps]
strategy:
fail-fast: false
matrix:
python: ["3.10", "3.11", "3.12", "3.13", "3.14"]
include:
- { python: "3.10", numpy: "2.0.0" }
- { python: "3.11", numpy: "2.0.0" }
- { python: "3.12", numpy: "2.0.0" }
- { python: "3.13", numpy: "2.1.0" }
- { python: "3.14", numpy: "2.3.2" }
runs-on: windows-latest

permissions:
contents: read

steps:
- name: Install SWIG 4.2.1
shell: pwsh
run: |
winget install --id SWIG.SWIG --version 4.2.1 --silent --accept-package-agreements --accept-source-agreements
$swigPkg = Get-ChildItem "$env:LOCALAPPDATA\Microsoft\WinGet\Packages" -Directory | Where-Object { $_.Name -like "SWIG.SWIG_*" } | Select-Object -First 1
$swigExe = Get-ChildItem $swigPkg.FullName -Recurse -Filter "swig.exe" | Select-Object -First 1
echo "SWIG_EXECUTABLE=$($swigExe.FullName)" >> $env:GITHUB_ENV
echo "SWIG_DIR=$(Join-Path $swigExe.DirectoryName 'Lib')" >> $env:GITHUB_ENV

- name: Restore CUVIS SDK zip
uses: actions/cache@v4
with:
path: ${{ github.workspace }}\cuvis_sdk.zip
key: cuvis-sdk-zip-windows-${{ needs.prepare.outputs.cuvis_version }}
fail-on-cache-miss: true

- name: Install CUVIS SDK
shell: pwsh
env:
CUVIS_VERSION: ${{ needs.prepare.outputs.cuvis_version }}
run: |
$v = $env:CUVIS_VERSION
Expand-Archive "${{ github.workspace }}\cuvis_sdk.zip" -DestinationPath cuvis_sdk
$installer = Get-ChildItem "cuvis_sdk\Cuvis $v\" -Recurse -Filter "Cuvis_C_SDK_Installer_*.exe" | Select-Object -First 1
Write-Output "Installing: $($installer.FullName)"

$logDir = Join-Path $env:RUNNER_TEMP 'cuvis_install'
New-Item -ItemType Directory -Force -Path $logDir | Out-Null
$nsisLog = Join-Path $logDir 'install.log'
$cuvisDir = 'C:\Program Files\Cuvis'
$cuvisBin = Join-Path $cuvisDir 'bin'

# WORKAROUND for a bug in the current Cuvis_C_SDK_Installer (NSIS): $SILENT is never set under /S,
# so its bundled runtime driver MSIs (C:\Program Files\Cuvis\Runtime\*.msi, e.g. WavesSetup222.msi)
# launch via `msiexec /i ... /passive` instead of /quiet. /passive pops a GUI that nobody dismisses
# on a headless runner, so the installer's ExecWait hangs forever. We kill those stuck interactive
# msiexec processes so the installer finishes, then re-install the runtime MSIs ourselves with /qn.
# Those driver components are secondary -> their failure must not fail the job.
# Upstream fix for future installer versions: branch the runtime-MSI calls on ${Silent}, use /quiet.
$proc = Start-Process $installer.FullName -ArgumentList '/S', "/LOG=$nsisLog", '/NORESTART' -PassThru
$timeoutSec = 600; $elapsed = 0; $grace = 20; $firstSeen = @{}
while (-not $proc.HasExited -and $elapsed -lt $timeoutSec) {
Start-Sleep -Seconds 10; $elapsed += 10
Get-CimInstance Win32_Process | Where-Object {
$_.Name -eq 'msiexec.exe' -and $_.CommandLine -and
$_.CommandLine -match 'Cuvis' -and $_.CommandLine -match '\.msi' -and $_.CommandLine -notmatch '/q' } |
ForEach-Object {
if (-not $firstSeen.ContainsKey($_.ProcessId)) {
$firstSeen[$_.ProcessId] = $elapsed
Write-Output "Detected interactive runtime sub-installer (PID $($_.ProcessId)): $($_.CommandLine)"
} elseif ($elapsed - $firstSeen[$_.ProcessId] -ge $grace) {
Write-Output "Killing stuck sub-installer PID $($_.ProcessId) so the main installer can continue."
Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue
}
}
Write-Output "== t=${elapsed}s : installer running =="
}

if ($proc.HasExited) { Write-Output "Installer exit code: $($proc.ExitCode)" }
else { Write-Output "::warning::Installer still running at ${timeoutSec}s - terminating."; Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue }

if (-not (Test-Path "$cuvisBin\*.dll")) {
Write-Output "::error::core CUVIS SDK missing under $cuvisBin"
if (Test-Path $nsisLog) { Write-Output '----- NSIS install.log -----'; Get-Content $nsisLog }
exit 1
}

Get-ChildItem (Join-Path $cuvisDir 'Runtime') -Filter *.msi -ErrorAction SilentlyContinue | ForEach-Object {
$msiLog = Join-Path $logDir ($_.BaseName + '.log')
$p = Start-Process msiexec -Wait -PassThru -ArgumentList '/i', "`"$($_.FullName)`"", '/qn', '/norestart', '/l*v', "`"$msiLog`""
Write-Output "Runtime component $($_.Name) -> msiexec exit $($p.ExitCode)"
}

Write-Output "CUVIS SDK installed:"; Get-ChildItem $cuvisBin | Select-Object -First 20 | Format-Table -Auto | Out-String | Write-Output

- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ inputs.ref || github.ref }}
submodules: recursive

- name: Setup Python ${{ matrix.python }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}

- name: Create venv and install Python build dependencies
shell: pwsh
run: |
python -m venv venv
.\venv\Scripts\Activate.ps1
python -m pip install --upgrade pip setuptools wheel build
python -m pip install numpy==${{ matrix.numpy }}

- name: CMake configure and build
shell: pwsh
env:
CUVIS: C:\Program Files\Cuvis
run: |
$env:PATH += ";C:\Program Files\Cuvis\bin"
cmake "-DCMAKE_BUILD_TYPE=Release" "-DDOXYGEN_BUILD_DOCUMENTATION=FALSE" "-DSWIG_DIR=$env:SWIG_DIR" "-DSWIG_EXECUTABLE=$env:SWIG_EXECUTABLE" "-DPython_ROOT_DIR=${{ github.workspace }}\venv" "-DCMAKE_PREFIX_PATH=$env:CUVIS" -B build .
cmake --build build --target cuvis_pyil --config Release

- name: Copy built files and package wheel
shell: bash
run: |
rm -rf ./cuvis_il/*cuvis*
rm -rf ./dist/*.whl
chmod +x ./copy_pyil_files.sh
./copy_pyil_files.sh build/Release
source venv/Scripts/activate
python -m build --wheel --no-isolation

- name: Tag wheel with correct Python and platform tags
shell: bash
run: |
source venv/Scripts/activate
PYTHON_TAG="py$(echo '${{ matrix.python }}' | tr -d '.')"
WHEELS=$(find dist -type f -name "*.whl")
WHEEL_COUNT=$(echo "$WHEELS" | wc -l)
if [ "$WHEEL_COUNT" -ne 1 ]; then
echo "Expected exactly 1 wheel, found $WHEEL_COUNT"
exit 1
fi
echo "Tagging $WHEELS with --python-tag=$PYTHON_TAG --platform-tag=win_amd64"
python -m wheel tags --remove \
--python-tag="$PYTHON_TAG" \
--platform-tag=win_amd64 \
"$WHEELS"

- name: Upload wheel artifact
uses: actions/upload-artifact@v4
with:
name: wheel-windows-py${{ matrix.python }}
path: dist/*.whl

preflight:
needs: [prepare, build]
needs: [prepare, build, build-windows]
runs-on: ubuntu-latest

permissions:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "cuvis_il"
version = "3.5.3.1"
version = "3.5.3.2"
description = "Compiled Python Bindings for the CUVIS SDK."
readme = "README.md"
requires-python = ">=3.9"
Expand Down
Loading