Skip to content

chore(deps): bump rapier3d from 0.22.0 to 0.34.0 #1364

chore(deps): bump rapier3d from 0.22.0 to 0.34.0

chore(deps): bump rapier3d from 0.22.0 to 0.34.0 #1364

Workflow file for this run

name: CI
on:
push:
branches:
- main
- 'release-please--**'
pull_request:
branches: [ main ]
merge_group:
types: [checks_requested]
permissions:
contents: read
actions: read
pull-requests: read
concurrency:
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
# sdl2-sys bundled build ships an older SDL2 CMakeLists.txt that uses
# cmake_minimum_required(VERSION 3.1.3). Newer CMake versions (4.0+)
# removed compatibility with policies < 3.5; this env var restores it.
CMAKE_POLICY_VERSION_MINIMUM: "3.5"
jobs:
# Fast sanity checks to fail quickly before heavy matrix jobs
preflight:
name: Preflight (Ubuntu Stable)
runs-on: ubuntu-latest
env:
RUSTC_WRAPPER: sccache
SCCACHE_GHA_ENABLED: "true"
steps:
- uses: actions/checkout@v7
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: Set up sccache
uses: mozilla-actions/sccache-action@v0.0.10
- name: Restore Rust cache
uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libgl1-mesa-dev libglu1-mesa-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxxf86vm-dev libasound2-dev libudev-dev
- name: Set up Python (for codegen)
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Validate architecture docs
run: python3 scripts/generate-architecture-docs.py --check
- name: Validate AGENTS.md constraints
run: bash scripts/check-agents-md.sh
- name: Run SDK codegen (generates .g.rs files needed by workspace)
run: |
python codegen/validate_coverage.py
python codegen/gen_csharp.py
python codegen/gen_python.py
python codegen/gen_ts_node.py
python codegen/gen_ts_web.py
python codegen/gen_kotlin.py
- name: Upload shared codegen artifact
uses: actions/upload-artifact@v4
with:
name: codegen-generated
path: |
sdks/csharp/generated/
sdks/python/goudengine/generated/
sdks/python/goudengine/__init__.py
sdks/typescript/src/generated/
sdks/typescript/native/src/*.g.rs
sdks/typescript/native/src/lib.rs
if-no-files-found: error
retention-days: 1
- name: Quick Rust check
run: cargo check --workspace --all-targets
- name: Check formatting
run: |
cargo fmt -p goud-engine-core -- --check
# Format generated napi-rs files (gitignored, no --check needed)
cargo fmt -p goud-engine-node
- name: Run clippy
run: cargo clippy --all-targets --all-features -- -D warnings
# Rust checks and tests
rust-check:
name: Rust ${{ matrix.rust }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
needs: [preflight]
env:
RUSTC_WRAPPER: sccache
SCCACHE_GHA_ENABLED: ${{ (github.event_name != 'pull_request' || (matrix.os == 'ubuntu-latest' && matrix.rust == 'stable' && matrix.lane == 'full')) && 'true' || 'false' }}
strategy:
fail-fast: ${{ github.event_name == 'pull_request' }}
matrix:
include: ${{ fromJSON(github.event_name == 'pull_request' && '[{"os":"ubuntu-latest","rust":"stable","lane":"full","run_windows_native_clippy":false},{"os":"ubuntu-latest","rust":"nightly","lane":"smoke","run_windows_native_clippy":false},{"os":"macos-latest","rust":"stable","lane":"smoke","run_windows_native_clippy":false},{"os":"windows-latest","rust":"stable","lane":"clippy-only","run_windows_native_clippy":true}]' || '[{"os":"ubuntu-latest","rust":"stable","lane":"full","run_windows_native_clippy":false},{"os":"macos-latest","rust":"stable","lane":"full","run_windows_native_clippy":false},{"os":"windows-latest","rust":"stable","lane":"full","run_windows_native_clippy":true},{"os":"ubuntu-latest","rust":"nightly","lane":"smoke","run_windows_native_clippy":false},{"os":"macos-latest","rust":"nightly","lane":"smoke","run_windows_native_clippy":false}]') }}
steps:
- name: Free disk space (Ubuntu)
if: matrix.os == 'ubuntu-latest' && matrix.lane == 'full'
run: |
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL
sudo docker image prune --all --force || true
df -h /
- uses: actions/checkout@v7
- name: Download shared codegen artifact
uses: actions/download-artifact@v4
with:
name: codegen-generated
path: sdks
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust }}
components: clippy
- name: Set up sccache
uses: mozilla-actions/sccache-action@v0.0.10
- name: Restore Rust cache
uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install system dependencies (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y libgl1-mesa-dev libglu1-mesa-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxxf86vm-dev libasound2-dev libudev-dev libxkbcommon-x11-dev
- name: Run clippy (Windows stable)
if: matrix.run_windows_native_clippy
run: cargo clippy --all-targets --features native -- -D warnings
shell: bash
- name: Nightly check/build smoke
if: matrix.rust == 'nightly'
run: |
cargo check --workspace --all-targets --all-features
cargo build --workspace --all-targets --all-features
- name: Stable smoke checks
if: matrix.rust == 'stable' && matrix.lane == 'smoke'
run: |
cargo check --workspace --all-targets --all-features
cargo test --lib sdk -- --nocapture
cargo test --test ffi_safety -- --nocapture
- name: Stable full suite (non-doc tests)
if: matrix.rust == 'stable' && matrix.lane == 'full'
run: cargo test --workspace --lib --bins --tests -- --nocapture
- name: Headless profile tests
if: matrix.rust == 'stable' && matrix.lane == 'full' && matrix.os == 'ubuntu-latest'
run: cargo test --features headless --lib -- null --nocapture
- name: Documentation tests (once per lane)
if: matrix.rust == 'stable' && matrix.lane == 'full' && matrix.os == 'ubuntu-latest'
run: cargo test --workspace --doc -- --nocapture
# Only run on stable for coverage
- name: Install cargo-tarpaulin
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && github.event_name == 'merge_group'
uses: taiki-e/install-action@cargo-tarpaulin
- name: Generate coverage
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && github.event_name == 'merge_group'
run: |
cargo tarpaulin \
--out xml html \
--output-dir coverage-report \
--all-features \
-p goud-engine-core \
--timeout 300 \
--branch \
--exclude-files "*/build.rs" \
--exclude-files "*/tests/*" \
--exclude-files "*/examples/*" \
--exclude-files "*/ffi/**" \
--exclude-files "*/sdk.rs"
- name: Check branch coverage threshold (70%)
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && github.event_name == 'merge_group' && always()
run: |
if [ ! -f coverage-report/cobertura.xml ]; then
echo "WARNING: Coverage report not found, skipping branch check"
exit 0
fi
BRANCH_RATE=$(python3 -c "
import xml.etree.ElementTree as ET
tree = ET.parse('coverage-report/cobertura.xml')
rate = tree.getroot().attrib.get('branch-rate')
if rate is None:
print('SKIP')
else:
print(f'{float(rate) * 100:.2f}')
")
if [ "$BRANCH_RATE" = "SKIP" ]; then
echo "WARNING: branch-rate attribute not found in cobertura.xml"
exit 0
fi
echo "Branch coverage: ${BRANCH_RATE}%"
if python3 -c "exit(0 if float('${BRANCH_RATE}') >= 70.0 else 1)"; then
echo "PASS: Branch coverage meets 70% threshold"
else
echo "WARNING: Branch coverage ${BRANCH_RATE}% is below 70% target (informational)"
fi
- name: Upload coverage report
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && github.event_name == 'merge_group' && always()
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage-report/
retention-days: 1
- name: Upload coverage to Codecov
if: matrix.rust == 'stable' && matrix.os == 'ubuntu-latest' && github.event_name == 'merge_group'
uses: codecov/codecov-action@v7
with:
file: ./coverage-report/cobertura.xml
flags: rust
name: rust-coverage
fail_ci_if_error: false
# Cargo deny check (license/security)
cargo-deny:
name: Cargo Deny Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: EmbarkStudios/cargo-deny-action@v2
with:
log-level: warn
command: check
arguments: --all-features
# Codegen drift detection — ensures generated SDK code is up to date
codegen-drift-check:
name: Codegen Drift Check
runs-on: ubuntu-latest
needs: [preflight]
env:
RUSTC_WRAPPER: sccache
SCCACHE_GHA_ENABLED: ${{ github.event_name != 'pull_request' && 'true' || 'false' }}
steps:
- uses: actions/checkout@v7
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Set up sccache
uses: mozilla-actions/sccache-action@v0.0.10
- name: Restore Rust cache
uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libgl1-mesa-dev libglu1-mesa-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxxf86vm-dev libasound2-dev libudev-dev
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Build (generates ffi_manifest.json)
run: cargo build
- name: Run full codegen pipeline
run: ./codegen.sh
- name: Validate codegen
run: |
python codegen/validate.py
python codegen/validate_coverage.py
- name: Lint layer dependencies
run: cargo run -p lint-layers
- name: Check for codegen drift
run: bash scripts/check-generated-artifacts.sh
- name: Verify SDK READMEs are up to date
run: python3 codegen/gen_sdk_readmes.py --check
# Build native release libraries once per OS and share across SDK jobs
native-release:
name: Native Release Artifact on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
needs: [preflight]
env:
RUSTC_WRAPPER: sccache
SCCACHE_GHA_ENABLED: ${{ github.event_name != 'pull_request' && 'true' || 'false' }}
strategy:
fail-fast: ${{ github.event_name == 'pull_request' }}
matrix:
os: ${{ fromJSON(github.event_name == 'pull_request' && '["ubuntu-latest","macos-latest"]' || '["ubuntu-latest","macos-latest","windows-latest"]') }}
steps:
- uses: actions/checkout@v7
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Set up sccache
uses: mozilla-actions/sccache-action@v0.0.10
- name: Restore Rust cache
uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Download shared codegen artifact
uses: actions/download-artifact@v4
with:
name: codegen-generated
path: sdks
- name: Install system dependencies (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y libgl1-mesa-dev libglu1-mesa-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxxf86vm-dev libasound2-dev libudev-dev libxkbcommon-x11-dev
- name: Build native library
run: cargo build --release
- name: Stage native release artifact
run: |
mkdir -p native-release
if [[ "$RUNNER_OS" == "Linux" ]]; then
cp target/release/libgoud_engine.so native-release/
elif [[ "$RUNNER_OS" == "macOS" ]]; then
cp target/release/libgoud_engine.dylib native-release/
else
cp target/release/goud_engine.dll native-release/
fi
shell: bash
- name: Upload native release artifact
uses: actions/upload-artifact@v4
with:
name: native-release-${{ matrix.os }}
path: native-release/
if-no-files-found: error
retention-days: 1
# Python SDK checks and tests
python-sdk-check:
name: Python SDK on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
needs: [preflight, native-release]
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
python-version: ['3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v7
- name: Download shared codegen artifact
uses: actions/download-artifact@v4
with:
name: codegen-generated
path: sdks
- name: Install system dependencies (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y libgl1-mesa-dev libglu1-mesa-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxxf86vm-dev libasound2-dev libudev-dev libxkbcommon-x11-dev
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install Python coverage tooling
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11'
run: python -m pip install coverage
- name: Download native release artifact
uses: actions/download-artifact@v4
with:
name: native-release-${{ matrix.os }}
path: native-release
- name: Set up library path (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: echo "LD_LIBRARY_PATH=${{ github.workspace }}/native-release:$LD_LIBRARY_PATH" >> $GITHUB_ENV
- name: Set up library path (macOS)
if: matrix.os == 'macos-latest'
run: echo "DYLD_LIBRARY_PATH=${{ github.workspace }}/native-release:$DYLD_LIBRARY_PATH" >> $GITHUB_ENV
- name: Run Python SDK tests
env:
PYTHONPATH: ${{ github.workspace }}/sdks/python
GOUD_ENGINE_LIB: ${{ github.workspace }}/native-release
run: |
python --version
python sdks/python/test_bindings.py
python sdks/python/test_network_loopback.py
- name: Test Python demo imports
env:
PYTHONPATH: ${{ github.workspace }}/sdks/python
GOUD_ENGINE_LIB: ${{ github.workspace }}/native-release
run: |
cd examples/python
python << 'EOF'
import sys
sys.path.insert(0, '../../sdks/python')
from goudengine import (
GoudGame, Entity, Transform2D, Sprite, Vec2, Color
)
print('Python SDK imports successful')
# Basic component tests
t = Transform2D.from_position(100, 200)
print(f'Transform2D: {t}')
s = Sprite(texture_handle=42)
print(f'Sprite: {s}')
print('All Python SDK basic tests passed!')
EOF
- name: Generate Python coverage report
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11'
env:
PYTHONPATH: ${{ github.workspace }}/sdks/python
GOUD_ENGINE_LIB: ${{ github.workspace }}/native-release
run: |
python -m coverage erase
python -m coverage run --source=sdks/python/goudengine sdks/python/test_bindings.py
python -m coverage run --append --source=sdks/python/goudengine sdks/python/test_network_loopback.py
python -m coverage report --fail-under=80
python -m coverage xml -o sdks/python/coverage.xml
- name: Upload Python coverage results
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11'
uses: actions/upload-artifact@v4
with:
name: python-coverage
path: sdks/python/coverage.xml
if-no-files-found: error
retention-days: 3
# .NET SDK checks and tests
dotnet-check:
name: .NET SDK on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
needs: [preflight, native-release]
strategy:
fail-fast: ${{ github.event_name == 'pull_request' }}
matrix:
os: ${{ fromJSON(github.event_name == 'pull_request' && '["ubuntu-latest","macos-latest"]' || '["ubuntu-latest","macos-latest","windows-latest"]') }}
steps:
- uses: actions/checkout@v7
- name: Download shared codegen artifact
uses: actions/download-artifact@v4
with:
name: codegen-generated
path: sdks
- name: Install system dependencies (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y libgl1-mesa-dev libglu1-mesa-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxxf86vm-dev libasound2-dev libudev-dev
- name: Download native release artifact
uses: actions/download-artifact@v4
with:
name: native-release-${{ matrix.os }}
path: native-release
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Set up library path (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: echo "LD_LIBRARY_PATH=${{ github.workspace }}/native-release:$LD_LIBRARY_PATH" >> $GITHUB_ENV
- name: Set up library path (macOS)
if: matrix.os == 'macos-latest'
run: echo "DYLD_LIBRARY_PATH=${{ github.workspace }}/native-release:$DYLD_LIBRARY_PATH" >> $GITHUB_ENV
- name: Cache NuGet packages
uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
restore-keys: |
${{ runner.os }}-nuget-
- name: Restore dependencies
working-directory: sdks/csharp
run: dotnet restore ../csharp.tests/GoudEngine.Tests.csproj
- name: Build
working-directory: sdks/csharp
run: dotnet build ../csharp.tests/GoudEngine.Tests.csproj --no-restore --configuration Release
- name: Copy native library to test directory (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: cp native-release/libgoud_engine.so sdks/csharp.tests/bin/Release/net8.0/
- name: Copy native library to test directory (macOS)
if: matrix.os == 'macos-latest'
run: cp native-release/libgoud_engine.dylib sdks/csharp.tests/bin/Release/net8.0/
- name: Copy native library to test directory (Windows)
if: matrix.os == 'windows-latest'
run: copy native-release\goud_engine.dll sdks\csharp.tests\bin\Release\net8.0\libgoud_engine.dll
- name: Test
working-directory: sdks/csharp
run: dotnet test ../csharp.tests/GoudEngine.Tests.csproj --no-build --configuration Release --verbosity normal --logger "trx;LogFileName=test-results.trx" /p:CollectCoverage=true /p:CoverletOutput=../csharp.tests/TestResults/${{ matrix.os }}/coverage/ /p:CoverletOutputFormat=cobertura
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: dotnet-test-results-${{ matrix.os }}
path: '**/test-results.trx'
retention-days: 3
- name: Upload C# coverage results
uses: actions/upload-artifact@v4
if: always()
with:
name: dotnet-coverage-${{ matrix.os }}
path: 'sdks/csharp.tests/TestResults/${{ matrix.os }}/coverage/coverage.cobertura.xml'
retention-days: 3
- name: Upload C# coverage to Codecov
if: matrix.os == 'ubuntu-latest'
uses: codecov/codecov-action@v7
with:
file: sdks/csharp.tests/TestResults/${{ matrix.os }}/coverage/coverage.cobertura.xml
flags: dotnet
name: dotnet-coverage
fail_ci_if_error: false
# Build check to ensure everything compiles together
integration-build:
name: Integration Build Check
runs-on: ${{ matrix.os }}
# Intentionally parallelized for faster feedback; ci-success still gates SDK jobs.
needs: [preflight]
env:
RUSTC_WRAPPER: sccache
SCCACHE_GHA_ENABLED: ${{ github.event_name != 'pull_request' && 'true' || 'false' }}
strategy:
fail-fast: ${{ github.event_name == 'pull_request' }}
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@v7
- name: Download shared codegen artifact
uses: actions/download-artifact@v4
with:
name: codegen-generated
path: sdks
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Set up sccache
uses: mozilla-actions/sccache-action@v0.0.10
- name: Restore Rust cache
uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Install system dependencies (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y libgl1-mesa-dev libglu1-mesa-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxxf86vm-dev libasound2-dev libudev-dev
- name: Run full build script
run: |
chmod +x build.sh
./build.sh --local
- name: Verify build artifacts
run: |
# Check Rust library exists
if [[ "$RUNNER_OS" == "macOS" ]]; then
if [[ "$RUNNER_ARCH" == "ARM64" ]]; then
test -f sdks/csharp/runtimes/osx-arm64/native/libgoud_engine.dylib
else
test -f sdks/csharp/runtimes/osx-x64/native/libgoud_engine.dylib
fi
elif [[ "$RUNNER_OS" == "Linux" ]]; then
test -f sdks/csharp/runtimes/linux-x64/native/libgoud_engine.so
fi
# Check .NET package exists
test -f sdks/nuget_package_output/GoudEngine.*.nupkg
- name: Verify Python SDK can import
env:
PYTHONPATH: ${{ github.workspace }}/sdks/python
LD_LIBRARY_PATH: ${{ github.workspace }}/target/debug:${{ env.LD_LIBRARY_PATH }}
DYLD_LIBRARY_PATH: ${{ github.workspace }}/target/debug:${{ env.DYLD_LIBRARY_PATH }}
run: |
python -c "from goudengine import GoudGame, Entity, Transform2D, Sprite; print('Python SDK integration check passed')"
# TypeScript SDK — native addon build + tests
typescript-sdk-native:
name: TS SDK Native on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
needs: [preflight]
env:
RUSTC_WRAPPER: sccache
SCCACHE_GHA_ENABLED: ${{ (github.event_name != 'pull_request' || matrix.os == 'ubuntu-latest') && 'true' || 'false' }}
strategy:
fail-fast: ${{ github.event_name == 'pull_request' }}
matrix:
os: ${{ fromJSON(github.event_name == 'pull_request' && '["ubuntu-latest","macos-latest"]' || '["ubuntu-latest","macos-latest","windows-latest"]') }}
steps:
- uses: actions/checkout@v7
- name: Download shared codegen artifact
uses: actions/download-artifact@v4
with:
name: codegen-generated
path: sdks
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Set up sccache
uses: mozilla-actions/sccache-action@v0.0.10
- name: Restore Rust cache
uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: sdks/typescript/package-lock.json
- name: Install system dependencies (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y libgl1-mesa-dev libglu1-mesa-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxxf86vm-dev libasound2-dev libudev-dev libxkbcommon-x11-dev
- name: Install npm dependencies
working-directory: sdks/typescript
run: npm ci
- name: Install Playwright Chromium
working-directory: sdks/typescript
run: npx playwright install --with-deps chromium
- name: Create native typing shim (PR macOS smoke lane)
if: github.event_name == 'pull_request' && matrix.os != 'ubuntu-latest'
working-directory: sdks/typescript
run: |
cat > index.d.ts <<'EOF'
export type GameConfig = {
width?: number;
height?: number;
title?: string;
};
export class GoudGame {
constructor(config?: GameConfig);
[key: string]: any;
}
export class GoudContext {
constructor();
[key: string]: any;
}
export class Entity {
[key: string]: any;
}
export class UiManager {
constructor();
[key: string]: any;
}
EOF
- name: Build native addon
if: github.event_name != 'pull_request' || matrix.os == 'ubuntu-latest'
working-directory: sdks/typescript
run: npm run build:native
- name: Build TypeScript (Node)
working-directory: sdks/typescript
run: npm run build:ts
- name: Type-check TypeScript examples
run: |
cd examples/typescript/flappy_bird && npm install && npx tsc --noEmit
- name: Run smoke tests (Ubuntu with virtual display)
if: matrix.os == 'ubuntu-latest'
working-directory: sdks/typescript
run: xvfb-run npm run test:native
- name: Generate TypeScript coverage report
if: matrix.os == 'ubuntu-latest'
working-directory: sdks/typescript
run: xvfb-run npm run coverage:native
- name: Run smoke tests (macOS/Windows — skip GLFW window tests in headless CI)
if: matrix.os != 'ubuntu-latest'
working-directory: sdks/typescript
run: |
echo "Smoke tests require a display (GLFW window). Build verified above."
echo "Full smoke tests run on ubuntu-latest with xvfb."
- name: Upload TypeScript coverage results
if: matrix.os == 'ubuntu-latest'
uses: actions/upload-artifact@v4
with:
name: ts-coverage
path: sdks/typescript/coverage/native/cobertura-coverage.xml
if-no-files-found: error
retention-days: 3
- name: Upload native addon
if: github.event_name != 'pull_request'
uses: actions/upload-artifact@v4
with:
name: ts-native-${{ matrix.os }}
path: sdks/typescript/*.node
retention-days: 1
# TypeScript SDK — wasm build (Ubuntu only, one platform sufficient)
typescript-sdk-wasm:
name: TS SDK Wasm Build
if: github.event_name == 'pull_request' || github.event_name == 'merge_group'
runs-on: ubuntu-latest
needs: [preflight]
env:
RUSTC_WRAPPER: sccache
SCCACHE_GHA_ENABLED: ${{ github.event_name != 'pull_request' && 'true' || 'false' }}
steps:
- uses: actions/checkout@v7
- name: Download shared codegen artifact
uses: actions/download-artifact@v4
with:
name: codegen-generated
path: sdks
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- name: Set up sccache
uses: mozilla-actions/sccache-action@v0.0.10
- name: Restore Rust cache
uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: sdks/typescript/package-lock.json
- name: Install pinned wasm-pack
env:
WASM_PACK_VERSION: "0.13.1"
run: |
curl -sSfL "https://github.com/rustwasm/wasm-pack/releases/download/v${WASM_PACK_VERSION}/wasm-pack-v${WASM_PACK_VERSION}-x86_64-unknown-linux-musl.tar.gz" -o /tmp/wasm-pack.tar.gz
tar -xzf /tmp/wasm-pack.tar.gz -C /tmp
sudo install /tmp/wasm-pack-v${WASM_PACK_VERSION}-x86_64-unknown-linux-musl/wasm-pack /usr/local/bin/wasm-pack
wasm-pack --version
- name: Install npm dependencies
working-directory: sdks/typescript
run: npm ci
- name: Install Playwright Chromium
working-directory: sdks/typescript
run: npx playwright install --with-deps chromium
- name: Build wasm module
working-directory: sdks/typescript
# wasm-pack already runs wasm-opt for this bundle; a second manual pass
# broke Chromium's externref table initialization in the runtime smoke.
run: npm run build:wasm
- name: Build web TypeScript
working-directory: sdks/typescript
run: npm run build:ts:web
- name: Type-check web sources
working-directory: sdks/typescript
run: npx tsc -p tsconfig.web.json --noEmit
- name: Generate TypeScript web coverage report
working-directory: sdks/typescript
run: npm run coverage:web-runtime
- name: Verify wasm output structure
working-directory: sdks/typescript
run: |
echo "=== Wasm output ==="
ls -la wasm/
echo "=== Web dist output ==="
find dist/web/ -name "*.js" | head -20 || echo "No JS files in dist/web/"
test -f wasm/goud_engine_bg.wasm
test -f wasm/goud_engine.js
- name: Upload TypeScript web coverage results
uses: actions/upload-artifact@v4
with:
name: ts-web-coverage
path: sdks/typescript/coverage/web/cobertura-coverage.xml
if-no-files-found: error
retention-days: 3
- name: Upload wasm artifacts
if: github.event_name != 'pull_request'
uses: actions/upload-artifact@v4
with:
name: ts-wasm
path: |
sdks/typescript/wasm/*.wasm
sdks/typescript/wasm/*.js
sdks/typescript/wasm/*.d.ts
retention-days: 1
# C++ SDK tests (non-GL only, headless CI safe)
# Windows C++ CI is excluded: MSVC support is scaffolded in FindGoudEngine.cmake
# but not yet validated in CI. Add windows-latest when a Windows native-release
# artifact is reliably available on PRs.
cpp-tests:
name: C++ SDK Tests on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
needs: [preflight, native-release]
strategy:
fail-fast: ${{ github.event_name == 'pull_request' }}
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@v7
- name: Download native release artifact
uses: actions/download-artifact@v4
with:
name: native-release-${{ matrix.os }}
path: native-release
- name: Stage native library
run: |
mkdir -p target/release target/release/deps
cp native-release/* target/release/
cp native-release/* target/release/deps/
shell: bash
- name: Install system dependencies (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y cmake
- name: Configure C++ tests
run: |
cmake -B sdks/cpp/build \
-DGOUD_BUILD_TESTS=ON \
-DCMAKE_BUILD_TYPE=Release \
sdks/cpp
- name: Build C++ tests
run: cmake --build sdks/cpp/build --config Release
- name: Run non-GL C++ tests
run: sdks/cpp/build/tests/goud_cpp_tests "~[gl_required]"
# Kotlin SDK tests
kotlin-sdk-test:
name: Kotlin SDK Test
runs-on: ubuntu-latest
needs: [preflight]
steps:
- uses: actions/checkout@v7
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Set up JDK 17
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: '17'
- name: Generate Kotlin SDK
run: python codegen/gen_kotlin.py
- name: Run Kotlin SDK tests
working-directory: sdks/kotlin
run: ./gradlew test --no-daemon -x buildNative
sandbox-parity:
name: Sandbox Recovery Smoke
runs-on: ubuntu-latest
needs: [preflight]
steps:
- uses: actions/checkout@v7
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y xvfb libgl1-mesa-dev libglu1-mesa-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxxf86vm-dev libasound2-dev libudev-dev libxkbcommon-x11-dev
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: |
sdks/typescript/package-lock.json
examples/typescript/sandbox/package-lock.json
- name: Install pinned wasm-pack
env:
WASM_PACK_VERSION: "0.13.1"
run: |
cargo install wasm-pack --version "${WASM_PACK_VERSION}" --locked
wasm-pack --version
- name: Run Rust Sandbox (default smoke)
env:
GOUD_SANDBOX_SMOKE_SECONDS: "1"
run: xvfb-run -a cargo run -p sandbox
- name: Build native Python library for sandbox smoke
run: |
cargo build -p goud-engine-core
test -f target/debug/libgoud_engine.so
- name: Run Python Sandbox (default smoke)
env:
GOUD_ENGINE_LIB: ${{ github.workspace }}/target/debug/libgoud_engine.so
GOUD_SANDBOX_SMOKE_SECONDS: "1"
PYTHONPATH: ${{ github.workspace }}/sdks/python
run: xvfb-run -a python3 examples/python/sandbox.py
- name: Run native peer smoke (Rust host + Python client)
env:
GOUD_SANDBOX_SMOKE_SECONDS: "6"
run: bash scripts/sandbox-peer-smoke.sh
- name: Run C# Sandbox (2D/3D/Hybrid smoke)
env:
GOUD_SANDBOX_SMOKE_SECONDS: "1"
LD_LIBRARY_PATH: ${{ github.workspace }}/target/debug:${{ env.LD_LIBRARY_PATH }}
run: |
cd examples/csharp/sandbox
dotnet build
xvfb-run -a env DOTNET_ROLL_FORWARD=Major GOUD_SANDBOX_START_MODE=1 dotnet run --no-build
xvfb-run -a env DOTNET_ROLL_FORWARD=Major GOUD_SANDBOX_START_MODE=2 dotnet run --no-build
xvfb-run -a env DOTNET_ROLL_FORWARD=Major GOUD_SANDBOX_START_MODE=3 dotnet run --no-build
- name: Run TypeScript Sandbox (desktop + web smoke)
run: |
cd examples/typescript/sandbox
npm ci
npx playwright install --with-deps chromium
npm run build:web
npm run desktop:check
xvfb-run -a env GOUD_SANDBOX_SMOKE_SECONDS=1 npm run desktop
npm run smoke:web
node -e "import('./dist/sandbox.js').then(()=>console.log('sandbox dist import ok'))"
# Go SDK tests (needs native library for CGO linking)
go-sdk-check:
name: Go SDK Tests
runs-on: ubuntu-latest
needs: [preflight, native-release]
steps:
- uses: actions/checkout@v7
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: '1.22'
- name: Download native release artifact
uses: actions/download-artifact@v4
with:
name: native-release-ubuntu-latest
path: native-release
- name: Stage native library
run: |
mkdir -p target/release
cp native-release/* target/release/
- name: Build Go SDK (verify compilation)
working-directory: sdks/go
run: go build ./...
- name: Vet Go SDK
working-directory: sdks/go
run: go vet ./...
# Swift SDK tests (macOS only, pure-Swift value type tests)
swift-sdk-check:
name: Swift SDK Tests
runs-on: macos-latest
needs: [preflight, native-release]
steps:
- uses: actions/checkout@v7
- name: Download native release artifact
uses: actions/download-artifact@v4
with:
name: native-release-macos-latest
path: native-release
- name: Stage native library
run: |
mkdir -p target/release
cp native-release/* target/release/
- name: Run Swift tests
working-directory: sdks/swift
run: swift test
continue-on-error: true
ios-build-pipeline:
name: iOS Build Pipeline
runs-on: macos-latest
if: github.event_name != 'pull_request'
needs: [preflight]
timeout-minutes: 35
steps:
- uses: actions/checkout@v7
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Restore Rust cache
uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Build iOS static libraries
run: ./platform/ios/build-ios.sh
- name: Build iOS template for simulator
run: |
xcodebuild \
-project platform/ios/template/MobileTemplate.xcodeproj \
-scheme MobileTemplate \
-configuration Debug \
-sdk iphonesimulator \
-destination 'generic/platform=iOS Simulator' \
CODE_SIGNING_ALLOWED=NO \
build
- name: Build iOS Flappy Bird example for simulator
env:
GOUD_ENGINE_IOS_LIB_DIR: ${{ github.workspace }}/platform/ios/build/simulator
working-directory: examples/ios/flappy_bird
run: |
# Resolve SPM dependencies and build for iOS Simulator
xcodebuild \
-scheme FlappyBird \
-configuration Debug \
-sdk iphonesimulator \
-destination 'generic/platform=iOS Simulator' \
-derivedDataPath .build/derivedData \
CODE_SIGNING_ALLOWED=NO \
build 2>&1 || {
echo "xcodebuild failed, trying swift build as fallback..."
swift build \
--sdk "$(xcrun --sdk iphonesimulator --show-sdk-path)" \
--triple arm64-apple-ios-simulator \
-Xlinker -L"${GOUD_ENGINE_IOS_LIB_DIR}"
}
- name: Shutdown iOS Simulator
if: always()
run: xcrun simctl shutdown booted || true
android-build-pipeline:
name: Android Build Pipeline
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
needs: [preflight]
timeout-minutes: 25
steps:
- uses: actions/checkout@v7
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Restore Rust cache
uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Set up JDK 17
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: '17'
- name: Set up Android SDK
uses: android-actions/setup-android@v4
- name: Install Android build tooling
run: sdkmanager "platforms;android-34" "build-tools;34.0.0" "ndk;27.2.12479018"
- name: Build Android shared libraries
env:
ANDROID_NDK_HOME: ${{ env.ANDROID_SDK_ROOT }}/ndk/27.2.12479018
ANDROID_NDK_ROOT: ${{ env.ANDROID_SDK_ROOT }}/ndk/27.2.12479018
run: ./platform/android/build-android.sh
- name: Build Android template
working-directory: platform/android/template
run: ./gradlew assembleDebug --no-daemon
- name: Copy native libraries to Flappy Bird example
run: |
mkdir -p examples/android/flappy_bird/app/src/main/jniLibs
cp -r platform/android/template/app/src/main/jniLibs/* \
examples/android/flappy_bird/app/src/main/jniLibs/
- name: Build Android Flappy Bird example
working-directory: examples/android/flappy_bird
env:
GOUD_REPO_ROOT: ${{ github.workspace }}
run: ./gradlew assembleDebug --no-daemon
- name: Enable KVM group permissions
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' \
| sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Smoke test on Android emulator
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 30
arch: x86_64
force-avd-creation: false
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio
disable-animations: true
script: |
adb install examples/android/flappy_bird/app/build/outputs/apk/debug/app-debug.apk
adb shell am start -n com.goudengine.flappybird/.MainActivity
sleep 5
adb exec-out screencap -p > android-smoke-test.png
# Verify the app was installed and launched (may crash due to no GPU in CI)
adb shell pm list packages | grep -q "com.goudengine.flappybird"
- name: Upload Android smoke test screenshot
if: failure()
uses: actions/upload-artifact@v4
with:
name: android-smoke-screenshot
path: android-smoke-test.png
retention-days: 1
# C SDK tests (CMake-based, needs native library)
c-sdk-check:
name: C SDK Tests on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
needs: [preflight, native-release]
strategy:
fail-fast: ${{ github.event_name == 'pull_request' }}
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@v7
- name: Download native release artifact
uses: actions/download-artifact@v4
with:
name: native-release-${{ matrix.os }}
path: native-release
- name: Stage native library
run: |
mkdir -p target/release
cp native-release/* target/release/
shell: bash
- name: Stage generated C header
run: |
cp codegen/generated/goud_engine.h sdks/c/include/goud_engine.h
shell: bash
- name: Install system dependencies (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y cmake
- name: Configure C tests
run: cmake -B sdks/c/tests/build -S sdks/c/tests -DCMAKE_BUILD_TYPE=Release
- name: Build C tests
run: cmake --build sdks/c/tests/build --config Release
- name: Run C tests
run: ctest --test-dir sdks/c/tests/build --output-on-failure
continue-on-error: true
# Lua SDK tests (pure-Lua constant validation, no native library needed)
lua-sdk-check:
name: Lua SDK Tests
runs-on: ubuntu-latest
needs: [preflight]
steps:
- uses: actions/checkout@v7
- name: Install Lua
run: |
sudo apt-get update
sudo apt-get install -y lua5.4
- name: Run Lua tests
working-directory: sdks/lua/luarocks
run: lua5.4 test_constants.lua
clean-room-regeneration:
name: Clean Room Regeneration
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
needs: [preflight]
steps:
- uses: actions/checkout@v7
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libgl1-mesa-dev libglu1-mesa-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxxf86vm-dev libasound2-dev libudev-dev
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: |
sdks/typescript/package-lock.json
- name: Install mdBook
run: |
mkdir -p "$HOME/.cargo/bin"
tag=$(curl -sI https://github.com/rust-lang/mdBook/releases/latest | grep -i '^location:' | sed 's|.*/tag/||;s/\r//')
curl -sSL "https://github.com/rust-lang/mdBook/releases/download/${tag}/mdbook-${tag}-x86_64-unknown-linux-gnu.tar.gz" \
| tar -xz -C "$HOME/.cargo/bin"
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Install pdoc
run: pip install pdoc
- name: Install DocFX
run: |
dotnet tool install -g docfx
echo "$HOME/.dotnet/tools" >> "$GITHUB_PATH"
- name: Verify clean-room regeneration
run: bash scripts/clean-room-regenerate.sh --docs
# Final status check
ci-success:
name: CI Success
if: always()
needs: [preflight, rust-check, cargo-deny, codegen-drift-check, native-release, dotnet-check, python-sdk-check, integration-build, typescript-sdk-native, typescript-sdk-wasm, cpp-tests, kotlin-sdk-test, go-sdk-check, swift-sdk-check, ios-build-pipeline, android-build-pipeline, c-sdk-check, lua-sdk-check, sandbox-parity, clean-room-regeneration]
runs-on: ubuntu-latest
steps:
- name: Check all jobs
run: |
check_job() {
local name="$1"
local result="$2"
local allow_skipped="$3"
if [[ "$result" == "success" ]]; then
echo "$name: success"
return 0
fi
if [[ "$allow_skipped" == "true" && ( "$result" == "skipped" || "$result" == "cancelled" ) ]]; then
echo "$name: $result (allowed)"
return 0
fi
echo "$name: unexpected result '$result'"
return 1
}
EVENT="${{ github.event_name }}"
ALLOW_FASTLANE_SKIPPED="false"
ALLOW_RUST_SKIPPED="false"
ALLOW_PUSH_SKIPPED="false"
ALLOW_HEAVY_SKIPPED="false"
if [[ "$EVENT" == "pull_request" ]]; then
ALLOW_FASTLANE_SKIPPED="true"
ALLOW_RUST_SKIPPED="true"
ALLOW_HEAVY_SKIPPED="true"
fi
if [[ "$EVENT" == "push" ]]; then
ALLOW_RUST_SKIPPED="true"
ALLOW_PUSH_SKIPPED="true"
fi
FAIL=0
check_job "preflight" "${{ needs.preflight.result }}" "false" || FAIL=1
check_job "rust-check" "${{ needs.rust-check.result }}" "$ALLOW_RUST_SKIPPED" || FAIL=1
check_job "cargo-deny" "${{ needs.cargo-deny.result }}" "false" || FAIL=1
check_job "codegen-drift-check" "${{ needs.codegen-drift-check.result }}" "false" || FAIL=1
check_job "native-release" "${{ needs.native-release.result }}" "$ALLOW_FASTLANE_SKIPPED" || FAIL=1
check_job "dotnet-check" "${{ needs.dotnet-check.result }}" "$ALLOW_FASTLANE_SKIPPED" || FAIL=1
check_job "python-sdk-check" "${{ needs.python-sdk-check.result }}" "$ALLOW_FASTLANE_SKIPPED" || FAIL=1
check_job "integration-build" "${{ needs.integration-build.result }}" "$ALLOW_FASTLANE_SKIPPED" || FAIL=1
check_job "typescript-sdk-native" "${{ needs.typescript-sdk-native.result }}" "$ALLOW_FASTLANE_SKIPPED" || FAIL=1
check_job "typescript-sdk-wasm" "${{ needs.typescript-sdk-wasm.result }}" "$ALLOW_PUSH_SKIPPED" || FAIL=1
check_job "cpp-tests" "${{ needs.cpp-tests.result }}" "$ALLOW_FASTLANE_SKIPPED" || FAIL=1
check_job "kotlin-sdk-test" "${{ needs.kotlin-sdk-test.result }}" "false" || FAIL=1
check_job "go-sdk-check" "${{ needs.go-sdk-check.result }}" "$ALLOW_FASTLANE_SKIPPED" || FAIL=1
check_job "swift-sdk-check" "${{ needs.swift-sdk-check.result }}" "$ALLOW_FASTLANE_SKIPPED" || FAIL=1
check_job "ios-build-pipeline" "${{ needs.ios-build-pipeline.result }}" "$ALLOW_HEAVY_SKIPPED" || FAIL=1
check_job "android-build-pipeline" "${{ needs.android-build-pipeline.result }}" "$ALLOW_HEAVY_SKIPPED" || FAIL=1
check_job "c-sdk-check" "${{ needs.c-sdk-check.result }}" "$ALLOW_FASTLANE_SKIPPED" || FAIL=1
check_job "lua-sdk-check" "${{ needs.lua-sdk-check.result }}" "false" || FAIL=1
check_job "sandbox-parity" "${{ needs.sandbox-parity.result }}" "false" || FAIL=1
check_job "clean-room-regeneration" "${{ needs.clean-room-regeneration.result }}" "$ALLOW_HEAVY_SKIPPED" || FAIL=1
if [[ "$FAIL" -ne 0 ]]; then
echo "One or more jobs failed"
exit 1
fi
echo "All checks passed!"