Build and Publish Bindings #63
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | |
| # Run JavaScript actions on Node.js 24. Opt-in flag documented in | |
| # https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/ | |
| # Forced default on 2026-06-02; remove this line after that date. | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| jobs: | |
| build-native: | |
| name: Build Native Libraries | |
| # Only run if Release workflow succeeded (or manual trigger) | |
| 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-arm64 | |
| runtime: osx-arm64 | |
| 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: Stage native library at shipping runtime path (Unix) | |
| if: matrix.os != 'windows-latest' | |
| shell: bash | |
| run: | | |
| # NativeLibraryTests asserts the library is loaded from the | |
| # runtimes/<rid>/native/ shipping layout (not a flat copy). | |
| # Staging to that location in CI matches the local-dev behavior | |
| # of NativeTestSupport.EnsureNativeLibraryPrepared(). | |
| find bindings/csharp/Undoc.Tests/bin/Release -type d -name "net*" | while read dir; do | |
| runtime_dir="$dir/runtimes/${{ matrix.runtime }}/native" | |
| mkdir -p "$runtime_dir" | |
| cp ./native-lib/* "$runtime_dir/" | |
| echo "Staged native library at $runtime_dir" | |
| ls -la "$runtime_dir" | |
| done | |
| - name: Stage native library at shipping runtime path (Windows) | |
| if: matrix.os == 'windows-latest' | |
| shell: pwsh | |
| run: | | |
| # Stage the native undoc.dll under runtimes/<rid>/native/ so it | |
| # does not collide with the managed Undoc.dll at the flat bin | |
| # root (case-insensitive Windows filesystem). | |
| Get-ChildItem -Path "bindings/csharp/Undoc.Tests/bin/Release" -Directory -Recurse | Where-Object { $_.Name -like "net*" } | ForEach-Object { | |
| $runtimeDir = Join-Path $_.FullName "runtimes/${{ matrix.runtime }}/native" | |
| New-Item -ItemType Directory -Path $runtimeDir -Force | Out-Null | |
| $srcFile = Get-ChildItem "./native-lib/*" | Select-Object -First 1 | |
| $destFile = Join-Path $runtimeDir "undoc.dll" | |
| Copy-Item $srcFile.FullName -Destination $destFile -Force | |
| Write-Host "Staged native library at $destFile" | |
| } | |
| - name: Run tests | |
| working-directory: bindings/csharp | |
| run: dotnet test Undoc.Tests/Undoc.Tests.csproj -c Release --no-build |