Skip to content

nuget build & publish #22

nuget build & publish

nuget build & publish #22

Workflow file for this run

name: Build Nuget
on:
workflow_dispatch:
inputs:
publish:
description: 'Publish package?'
required: true
default: false
type: boolean
jobs:
build:
runs-on: ${{ matrix.os }}
env:
NATIVE_BACKENDS: puerts papi-lua papi-quickjs papi-v8 papi-nodejs papi-python
strategy:
matrix:
include:
- os: ubuntu-latest
platform: linux
arch: x64
- os: windows-2022
platform: win
arch: x64
- os: macos-15
platform: osx
arch: auto
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v6
with:
python-version: '3.14'
- name: Install libc++-dev (Linux only)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y clang libc++-dev libc++abi-dev
- name: Build all native backends (Linux)
if: runner.os == 'Linux'
run: |
set -ex
backends="${NATIVE_BACKENDS}"
repo_root=$(pwd)
for backend in $backends; do
echo "Building $backend for ${{ matrix.platform }}-${{ matrix.arch }}"
cd "$repo_root/unity/native/$backend"
node ../../cli make --platform ${{ matrix.platform }} --arch ${{ matrix.arch }}
cd "$repo_root"
done
- name: Build all native backends (macOS)
if: runner.os == 'macOS'
run: |
set -ex
backends="${NATIVE_BACKENDS}"
repo_root=$(pwd)
for backend in $backends; do
echo "Building $backend for ${{ matrix.platform }}"
cd "$repo_root/unity/native/$backend"
# if python backend, specify arch to arm64
if [ "$backend" = "papi-python" ] && [ "${{ matrix.arch }}" = "auto" ]; then
node ../../cli make --platform ${{ matrix.platform }} --arch arm64
else
node ../../cli make --platform ${{ matrix.platform }}
fi
cd "$repo_root"
done
- name: Build all native backends (Windows)
if: runner.os == 'Windows'
run: |
$ErrorActionPreference = "Stop"
$backends = $env:NATIVE_BACKENDS.Split(" ")
$repoRoot = (Get-Location)
foreach ($backend in $backends) {
Write-Host "Building $backend for ${{ matrix.platform }}-${{ matrix.arch }}"
Set-Location "$repoRoot/unity/native/$backend"
node ../../cli make --platform ${{ matrix.platform }} --arch ${{ matrix.arch }}
Set-Location $repoRoot
}
shell: pwsh
# See: https://github.com/Tencent/puerts/blob/e230b37c313c62185ceb5207c37e79e53e1afada/unity/cli/make.mjs#L173
# mv(`${CMAKE_BUILD_PATH}/${options.config}/lib${cmakeAddedLibraryName}.dylib`, `${CMAKE_BUILD_PATH}/${options.config}/${cmakeAddedLibraryName}.bundle`);
# generated builds unity/upms/*/Plugins/macOS/*.bundle
# Rename macOS bundle format to dylib files to ensure upload-artifact works correctly
- name: Process macOS native artifacts
if: runner.os == 'macOS' && matrix.arch == 'auto'
run: |
set -ex
for dir in unity/upms/*/Plugins/macOS; do
if [ -d "$dir" ]; then
for file in "$dir"/*.bundle; do
[ -f "$file" ] && mv -n "$file" "${file%.bundle}.dylib"
echo "Renamed $file to ${file%.bundle}.dylib"
done
fi
done
# puerts\unity\native\papi-nodejs\.backends\papi-nodejs\lib\Linux\libnode.so.93
# puerts\unity\native\papi-nodejs\.backends\papi-nodejs\lib\Win64\libnode.dll
# puerts\unity\native\papi-nodejs\.backends\papi-nodejs\lib\macOS\libnode.93.dylib
- name: Process libraries dependencies
run: |
# Move libnode libraries to build directories
if ("${{ matrix.platform }}" -eq "linux" -and (Test-Path "unity/native/papi-nodejs/build_linux_x64_papi-nodejs")) {
Move-Item -Path "unity/native/papi-nodejs/.backends/papi-nodejs/lib/Linux/libnode.so.93" -Destination "unity/native/papi-nodejs/build_linux_x64_papi-nodejs/libnode.so.93" -Force
}
if ("${{ matrix.platform }}" -eq "win" -and (Test-Path "unity/native/papi-nodejs/build_win_x64_papi-nodejs/Release")) {
Move-Item -Path "unity/native/papi-nodejs/.backends/papi-nodejs/lib/Win64/libnode.dll" -Destination "unity/native/papi-nodejs/build_win_x64_papi-nodejs/Release/libnode.dll" -Force
}
if ("${{ matrix.platform }}" -eq "osx" -and (Test-Path "unity/upms/nodejs/Plugins/macOS")) {
Move-Item -Path "unity/native/papi-nodejs/.backends/papi-nodejs/lib/macOS/libnode.93.dylib" -Destination "unity/upms/nodejs/Plugins/macOS/libnode.93.dylib" -Force
}
if ("${{ matrix.platform }}" -eq "win") {
# Remove python's PuertsCore.dll on Windows
$puertsCorePath = "unity/native/papi-python/build_win_x64_papi-python/Release/PuertsCore.dll"
if (Test-Path $puertsCorePath) {
Remove-Item $puertsCorePath -Force
Write-Host "Removed $puertsCorePath to avoid duplicate PuertsCore.dll."
}
}
shell: pwsh
- name: Upload all native artifacts
uses: actions/upload-artifact@v4
with:
name: natives-${{ matrix.platform }}-${{ matrix.arch }}
path: |
unity/upms/core/Plugins/**/*.dylib
unity/upms/v8/Plugins/**/*.dylib
unity/upms/nodejs/Plugins/**/*.dylib
unity/upms/lua/Plugins/**/*.dylib
unity/upms/python/Plugins/**/*.dylib
unity/upms/quickjs/Plugins/**/*.dylib
unity/native/papi-lua/build_${{ matrix.platform }}_${{ matrix.arch }}_*/Release/*.dll
unity/native/papi-lua/build_${{ matrix.platform }}_${{ matrix.arch }}_*/lib*.so
unity/native/papi-nodejs/build_${{ matrix.platform }}_${{ matrix.arch }}_*/Release/*.dll
unity/native/papi-nodejs/build_${{ matrix.platform }}_${{ matrix.arch }}_*/lib*.so
unity/native/papi-nodejs/build_linux_x64_papi-nodejs/libnode.so.93
unity/native/papi-quickjs/build_${{ matrix.platform }}_${{ matrix.arch }}_*/Release/*.dll
unity/native/papi-quickjs/build_${{ matrix.platform }}_${{ matrix.arch }}_*/lib*.so
unity/native/papi-v8/build_${{ matrix.platform }}_${{ matrix.arch }}_*/Release/*.dll
unity/native/papi-v8/build_${{ matrix.platform }}_${{ matrix.arch }}_*/lib*.so
unity/native/papi-python/build_${{ matrix.platform }}_${{ matrix.arch }}_*/Release/*.dll
unity/native/papi-python/build_${{ matrix.platform }}_${{ matrix.arch }}_*/lib*.so
unity/native/puerts/build_${{ matrix.platform }}_${{ matrix.arch }}_*/Release/*.dll
unity/native/puerts/build_${{ matrix.platform }}_${{ matrix.arch }}_*/lib*.so
pack_nuget:
name: Pack NuGet
needs: build
runs-on: windows-2022
steps:
- uses: actions/checkout@v4
- name: Download all native artifacts
uses: actions/download-artifact@v4
with:
path: unity/nuget/downloaded_natives
- name: List downloaded artifacts
run: |
ls unity/nuget/downloaded_natives
tree unity/nuget/downloaded_natives /F
shell: pwsh
- name: Download Python (Windows)
run: |
$destPath = "unity\nuget\downloaded_natives\natives-win-x64\native\papi-python\build_win_x64_papi-python\Release"
New-Item -ItemType Directory -Force -Path $destPath
$downloadedEmbedZip = "$env:TEMP\python-3.14.2-embed-amd64.zip"
$downloadUrl = "https://www.python.org/ftp/python/3.14.2/python-3.14.2-embed-amd64.zip"
Invoke-WebRequest -Uri $downloadUrl -OutFile $downloadedEmbedZip
Expand-Archive -Path $downloadedEmbedZip -DestinationPath $destPath -Force
shell: pwsh
- name: Download Python Standalone (Linux)
run: |
$destPath = "unity/nuget/downloaded_natives/natives-linux-x64/native/papi-python/build_linux_x64_papi-python"
$tempExtract = "$env:TEMP/python-linux-extract"
New-Item -ItemType Directory -Force -Path $destPath
New-Item -ItemType Directory -Force -Path $tempExtract
# Download from python-build-standalone (install_only_stripped for smaller size)
$pythonUrl = "https://github.com/astral-sh/python-build-standalone/releases/download/20251217/cpython-3.14.2+20251217-x86_64-unknown-linux-gnu-install_only_stripped.tar.gz"
$downloadedTar = "$env:TEMP/python-linux.tar.gz"
Invoke-WebRequest -Uri $pythonUrl -OutFile $downloadedTar
# Extract to temp directory
tar -xzf $downloadedTar -C $tempExtract --strip-components=1
# Copy only necessary runtime files (exclude dev files, tests, etc.)
# Copy shared libraries
New-Item -ItemType Directory -Force -Path "$destPath/lib"
Copy-Item -Path "$tempExtract/lib/libpython3.14.so*" -Destination "$destPath/lib/" -Force
Copy-Item -Path "$tempExtract/lib/lib*.so*" -Destination "$destPath/lib/" -Force -ErrorAction SilentlyContinue
# Copy Python standard library (exclude tests and unnecessary modules)
$stdlibPath = "$destPath/lib/python3.14"
New-Item -ItemType Directory -Force -Path $stdlibPath
# Copy essential stdlib directories
$essentialDirs = @(
"collections", "encodings", "importlib", "json", "logging",
"email", "urllib", "http", "xml", "html", "ctypes", "sqlite3",
"asyncio", "concurrent", "multiprocessing", "threading"
)
foreach ($dir in $essentialDirs) {
$srcDir = "$tempExtract/lib/python3.14/$dir"
if (Test-Path $srcDir) {
Copy-Item -Path $srcDir -Destination $stdlibPath -Recurse -Force
}
}
# Copy essential .py files from root
Copy-Item -Path "$tempExtract/lib/python3.14/*.py" -Destination $stdlibPath -Force -ErrorAction SilentlyContinue
# Copy lib-dynload (compiled extension modules)
Copy-Item -Path "$tempExtract/lib/python3.14/lib-dynload" -Destination $stdlibPath -Recurse -Force -ErrorAction SilentlyContinue
shell: pwsh
- name: Download Python Standalone (macOS)
run: |
# For macOS, we need to put files in the upms structure first
# The TransformNativeAssetsTask will handle moving them to the correct location
$destPath = "unity/nuget/downloaded_natives/natives-osx-auto/upms/python/Plugins/macOS/arm64"
$tempExtract = "$env:TEMP/python-macos-extract"
New-Item -ItemType Directory -Force -Path $destPath
New-Item -ItemType Directory -Force -Path $tempExtract
# Download macOS arm64 version from python-build-standalone (install_only_stripped)
$pythonUrl = "https://github.com/astral-sh/python-build-standalone/releases/download/20251217/cpython-3.14.2+20251217-aarch64-apple-darwin-install_only_stripped.tar.gz"
$downloadedTar = "$env:TEMP/python-macos.tar.gz"
Invoke-WebRequest -Uri $pythonUrl -OutFile $downloadedTar
# Extract to temp directory
tar -xzf $downloadedTar -C $tempExtract --strip-components=1
# Copy only necessary runtime files
# Copy shared libraries
New-Item -ItemType Directory -Force -Path "$destPath/lib"
Copy-Item -Path "$tempExtract/lib/libpython3.14.dylib" -Destination "$destPath/lib/" -Force
Copy-Item -Path "$tempExtract/lib/lib*.dylib" -Destination "$destPath/lib/" -Force -ErrorAction SilentlyContinue
# Copy Python standard library (exclude tests and unnecessary modules)
$stdlibPath = "$destPath/lib/python3.14"
New-Item -ItemType Directory -Force -Path $stdlibPath
# Copy essential stdlib directories
$essentialDirs = @(
"collections", "encodings", "importlib", "json", "logging",
"email", "urllib", "http", "xml", "html", "ctypes", "sqlite3",
"asyncio", "concurrent", "multiprocessing", "threading"
)
foreach ($dir in $essentialDirs) {
$srcDir = "$tempExtract/lib/python3.14/$dir"
if (Test-Path $srcDir) {
Copy-Item -Path $srcDir -Destination $stdlibPath -Recurse -Force
}
}
# Copy essential .py files from root
Copy-Item -Path "$tempExtract/lib/python3.14/*.py" -Destination $stdlibPath -Force -ErrorAction SilentlyContinue
# Copy lib-dynload (compiled extension modules)
Copy-Item -Path "$tempExtract/lib/python3.14/lib-dynload" -Destination $stdlibPath -Recurse -Force -ErrorAction SilentlyContinue
shell: pwsh
- name: Run NuGet Packaging and Publishing
if: ${{ github.event.inputs.publish == 'true' }}
run: |
cd unity/nuget
.\build.ps1 --NativeAssetsDirectory "$pwd\downloaded_natives" --ProjectsRoot "$pwd" --Source "https://api.nuget.org/v3/index.json" --ApiKey "${{ secrets.NUGET_API_KEY }}"
shell: pwsh
- name: Run NuGet Packaging
if: ${{ github.event.inputs.publish == 'false' }}
run: |
cd unity/nuget
.\build.ps1 --NativeAssetsDirectory "$pwd\downloaded_natives" --ProjectsRoot "$pwd"
shell: pwsh
- name: Upload NuGet Packages
uses: actions/upload-artifact@v4
with:
name: nuget-packages
path: |
unity/nuget/packageOutput/*.nupkg
unity/nuget/packageOutput/*.snupkg