name: Build and Publish Bindings
on:
workflow_run:
workflows: ["Release"]
types: [completed]
workflow_dispatch:
inputs:
publish:
description: 'Publish to package registries'
required: false
default: 'false'
env:
CARGO_TERM_COLOR: always
jobs:
build-native:
name: Build Native Libraries
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
artifact: libundoc.so
runtime: linux-x64
- os: ubuntu-latest
target: x86_64-unknown-linux-musl
artifact: libundoc.so
runtime: linux-musl-x64
- os: windows-latest
target: x86_64-pc-windows-msvc
artifact: undoc.dll
runtime: win-x64
- os: macos-latest
target: x86_64-apple-darwin
artifact: libundoc.dylib
runtime: osx-x64
- os: macos-latest
target: aarch64-apple-darwin
artifact: libundoc.dylib
runtime: osx-arm64
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Install musl-tools
if: contains(matrix.target, 'musl')
run: sudo apt-get update && sudo apt-get install -y musl-tools
- name: Build native library
run: cargo build --release --target ${{ matrix.target }} --features ffi
env:
RUSTFLAGS: ${{ contains(matrix.target, 'musl') && '-C target-feature=-crt-static' || '' }}
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: native-${{ matrix.runtime }}
path: target/${{ matrix.target }}/release/${{ matrix.artifact }}
retention-days: 7
build-python:
name: Build Python Wheel
needs: build-native
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Download all native libraries
uses: actions/download-artifact@v4
with:
pattern: native-*
path: ./native-libs/
- name: Copy native libraries to package
run: |
mkdir -p bindings/python/src/undoc/lib/linux-x64
mkdir -p bindings/python/src/undoc/lib/linux-musl-x64
mkdir -p bindings/python/src/undoc/lib/win-x64
mkdir -p bindings/python/src/undoc/lib/osx-x64
mkdir -p bindings/python/src/undoc/lib/osx-arm64
cp ./native-libs/native-linux-x64/* bindings/python/src/undoc/lib/linux-x64/
cp ./native-libs/native-linux-musl-x64/* bindings/python/src/undoc/lib/linux-musl-x64/
cp ./native-libs/native-win-x64/* bindings/python/src/undoc/lib/win-x64/
cp ./native-libs/native-osx-x64/* bindings/python/src/undoc/lib/osx-x64/
cp ./native-libs/native-osx-arm64/* bindings/python/src/undoc/lib/osx-arm64/
echo "Native libraries copied:"
find bindings/python/src/undoc/lib -type f
- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install build wheel
- name: Build wheel
working-directory: bindings/python
run: python -m build
- name: Verify wheel contents
run: |
echo "Wheel contents:"
python3 -m zipfile -l bindings/python/dist/*.whl
echo ""
echo "Checking for all platform libraries:"
python3 -m zipfile -l bindings/python/dist/*.whl | grep -E "(libundoc|undoc\.dll)" || echo "WARNING: Missing some native libraries!"
- name: Upload wheel
uses: actions/upload-artifact@v4
with:
name: python-wheel
path: bindings/python/dist/*.whl
retention-days: 7
build-nuget:
name: Build NuGet Package
needs: build-native
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Create runtime directories
run: |
mkdir -p bindings/csharp/Undoc/runtimes/win-x64/native
mkdir -p bindings/csharp/Undoc/runtimes/linux-x64/native
mkdir -p bindings/csharp/Undoc/runtimes/linux-musl-x64/native
mkdir -p bindings/csharp/Undoc/runtimes/osx-x64/native
mkdir -p bindings/csharp/Undoc/runtimes/osx-arm64/native
- name: Download Windows native library
uses: actions/download-artifact@v4
with:
name: native-win-x64
path: bindings/csharp/Undoc/runtimes/win-x64/native/
- name: Download Linux native library
uses: actions/download-artifact@v4
with:
name: native-linux-x64
path: bindings/csharp/Undoc/runtimes/linux-x64/native/
- name: Download Linux musl native library
uses: actions/download-artifact@v4
with:
name: native-linux-musl-x64
path: bindings/csharp/Undoc/runtimes/linux-musl-x64/native/
- name: Download macOS x64 native library
uses: actions/download-artifact@v4
with:
name: native-osx-x64
path: bindings/csharp/Undoc/runtimes/osx-x64/native/
- name: Download macOS ARM64 native library
uses: actions/download-artifact@v4
with:
name: native-osx-arm64
path: bindings/csharp/Undoc/runtimes/osx-arm64/native/
- name: Build NuGet package
working-directory: bindings/csharp
run: dotnet pack Undoc/Undoc.csproj -c Release -o ./artifacts
- name: Upload NuGet package
uses: actions/upload-artifact@v4
with:
name: nuget-package
path: bindings/csharp/artifacts/*.nupkg
retention-days: 7
publish-pypi:
name: Publish to PyPI
needs: build-python
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event.inputs.publish == 'true' }}
steps:
- name: Download Python wheel
uses: actions/download-artifact@v4
with:
name: python-wheel
path: dist/
- name: List wheel contents
run: |
echo "Wheel file:"
ls -la dist/
echo ""
echo "Wheel contents:"
python3 -m zipfile -l dist/*.whl
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
packages-dir: dist/
skip-existing: true
publish-nuget:
name: Publish to NuGet
needs: build-nuget
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event.inputs.publish == 'true' }}
steps:
- name: Download NuGet package
uses: actions/download-artifact@v4
with:
name: nuget-package
path: ./
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Publish to NuGet
run: dotnet nuget push "*.nupkg" --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate
test-python:
name: Test Python Bindings
needs: build-python
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
python-version: '3.11'
- os: windows-latest
python-version: '3.11'
- os: macos-latest
python-version: '3.11'
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Download wheel
uses: actions/download-artifact@v4
with:
name: python-wheel
path: ./wheels/
- name: Install package
shell: bash
run: |
pip install pytest
pip install ./wheels/*.whl
- name: Run tests
working-directory: bindings/python
shell: bash
run: pytest tests/ -v --ignore=tests/test_integration.py
test-nuget:
name: Test NuGet Package
needs: build-nuget
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
artifact: native-linux-x64
runtime: linux-x64
- os: windows-latest
artifact: native-win-x64
runtime: win-x64
- os: macos-latest
artifact: native-osx-x64
runtime: osx-x64
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: Download native library
uses: actions/download-artifact@v4
with:
name: ${{ matrix.artifact }}
path: ./native-lib/
- name: Build test project (with project reference)
working-directory: bindings/csharp
run: dotnet build Undoc.Tests/Undoc.Tests.csproj -c Release
- name: Copy native library to test output (Unix)
if: matrix.os != 'windows-latest'
shell: bash
run: |
find bindings/csharp/Undoc.Tests/bin/Release -type d -name "net*" | while read dir; do
cp ./native-lib/* "$dir/"
echo "Copied native library to $dir"
ls -la "$dir"
done
- name: Copy native library to test output (Windows)
if: matrix.os == 'windows-latest'
shell: pwsh
run: |
# On Windows, native undoc.dll conflicts with managed Undoc.dll (case-insensitive)
# Rename to undoc_native.dll to avoid overwriting the managed assembly
Get-ChildItem -Path "bindings/csharp/Undoc.Tests/bin/Release" -Directory -Recurse | Where-Object { $_.Name -like "net*" } | ForEach-Object {
$srcFile = Get-ChildItem "./native-lib/*" | Select-Object -First 1
$destFile = Join-Path $_.FullName "undoc_native.dll"
Copy-Item $srcFile.FullName -Destination $destFile -Force
Write-Host "Copied native library to $destFile"
Write-Host "Test output directory (Undoc files):"
Get-ChildItem $_.FullName | Where-Object { $_.Name -like "Undoc*" -or $_.Name -like "undoc*" }
}
- name: Run tests
working-directory: bindings/csharp
run: dotnet test Undoc.Tests/Undoc.Tests.csproj -c Release --no-build