Skip to content

Update Python example #166

Update Python example

Update Python example #166

Workflow file for this run

name: Test, Build & Deploy Documentation
on:
push:
branches: [ "main", "dev" ]
pull_request:
branches: [ "main", "dev" ]
workflow_dispatch: # Manual trigger for testing
inputs:
run_tests:
description: "Run test jobs"
type: boolean
default: true
build_docs:
description: "Build documentation"
type: boolean
default: false
deploy_docs:
description: "Deploy docs (only works on main branch)"
type: boolean
default: false
dry_run_publish:
description: "Dry-run publish (validates but doesn't publish)"
type: boolean
default: true
permissions:
contents: write # Needed for creating tags when publish workflow is called
pages: write
id-token: write # Needed for Trusted Publishing (OIDC) - npm and PyPI
jobs:
# ============================================================================
# BUILD JOBS - Build artifacts first, then test against them
# ============================================================================
# Build Python wheels for Linux (all Python versions via cibuildwheel)
build-python-wheels-linux:
name: Build Python Wheels (Linux)
runs-on: ubuntu-latest
if: |
github.event_name == 'push' ||
github.event_name == 'pull_request' ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.run_tests == 'true')
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Python 3.12
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Setup Node.js (for Task setup)
uses: actions/setup-node@v4
with:
node-version: '24.x'
- name: Install Task
run: sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin && echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Setup SDK
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: task setup
- name: Build wheels with cibuildwheel
run: |
pip install cibuildwheel
cibuildwheel --platform linux --output-dir dist/py
- name: Upload wheel artifacts
uses: actions/upload-artifact@v4
with:
name: wheels-linux
path: dist/py/*.whl
retention-days: 7
# Build Python wheels for macOS (all Python versions via cibuildwheel)
build-python-wheels-macos:
name: Build Python Wheels (macOS)
runs-on: macos-latest
if: |
github.event_name == 'push' ||
github.event_name == 'pull_request' ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.run_tests == 'true')
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Python 3.12
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install Task
run: brew install go-task
- name: Setup Node.js (for Task setup)
uses: actions/setup-node@v4
with:
node-version: '24.x'
- name: Setup SDK
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: task setup
- name: Build wheels with cibuildwheel
run: |
pip install cibuildwheel
cibuildwheel --platform macos --output-dir dist/py
- name: Upload wheel artifacts
uses: actions/upload-artifact@v4
with:
name: wheels-darwin
path: dist/py/*.whl
retention-days: 7
# Build Node.js prebuilds for Linux
build-nodejs-linux:
name: Build Node.js Prebuilds (Linux)
runs-on: ubuntu-latest
if: |
github.event_name == 'push' ||
github.event_name == 'pull_request' ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.run_tests == 'true')
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js 24.x
uses: actions/setup-node@v4
with:
node-version: '24.x'
- name: Install Task
run: sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin && echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Setup project
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: task setup
- name: Build prebuilds
run: node scripts/prebuild.js --platform=linux
- name: Upload prebuild artifacts
uses: actions/upload-artifact@v4
with:
name: prebuilds-linux
path: prebuilds/@zoom/*.tar.gz
retention-days: 7
# Build Node.js prebuilds for macOS
build-nodejs-macos:
name: Build Node.js Prebuilds (macOS)
runs-on: macos-latest
if: |
github.event_name == 'push' ||
github.event_name == 'pull_request' ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.run_tests == 'true')
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js 24.x
uses: actions/setup-node@v4
with:
node-version: '24.x'
- name: Install Task
run: brew install go-task
- name: Setup project
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: task setup
- name: Build prebuilds
run: node scripts/prebuild.js --platform=darwin
- name: Upload prebuild artifacts
uses: actions/upload-artifact@v4
with:
name: prebuilds-darwin
path: prebuilds/@zoom/*.tar.gz
retention-days: 7
# ============================================================================
# TEST JOBS - Test against pre-built artifacts
# ============================================================================
# C++ unit tests — mock SDK replaces the binary; real headers downloaded via check-deps
test-cpp-linux:
name: Test C++ Core (Linux)
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js (for check-deps.js SDK download)
uses: actions/setup-node@v4
with:
node-version: '24.x'
- name: Install CMake
run: sudo apt-get install -y cmake
- name: Download SDK headers
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: node scripts/check-deps.js
- name: Build and run C++ tests
run: |
cmake -B build/tests -DRTMS_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Debug
cmake --build build/tests --target rtms_tests -j$(nproc)
cd build/tests && ctest --output-on-failure
test-cpp-macos:
name: Test C++ Core (macOS)
runs-on: macos-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js (for check-deps.js SDK download)
uses: actions/setup-node@v4
with:
node-version: '24.x'
- name: Download SDK headers
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: node scripts/check-deps.js
- name: Build and run C++ tests
run: |
cmake -B build/tests -DRTMS_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Debug
cmake --build build/tests --target rtms_tests -j$(sysctl -n hw.logicalcpu)
cd build/tests && ctest --output-on-failure
# Test Node.js SDK on Linux using pre-built prebuilds
test-nodejs-linux:
name: Test Node.js SDK on Linux (Node ${{ matrix.node-version }})
runs-on: ubuntu-latest
needs: [build-nodejs-linux]
strategy:
matrix:
node-version: ['22.x', '24.x'] # Test current LTS and latest LTS
fail-fast: false # Continue testing other versions if one fails
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Download prebuilds
uses: actions/download-artifact@v4
with:
name: prebuilds-linux
path: prebuilds/
- name: Install dependencies
run: npm install
- name: Extract native prebuild
# install.js skips extraction when .git exists (dev mode detection).
# --force bypasses that check so the full install flow runs in CI.
run: node scripts/install.js --force
- name: Compile TypeScript
run: npx tsc
- name: Run Node.js tests
run: npx jest tests/ts/rtms.test.ts tests/ts/rtms.wrapper.test.ts
# Test Node.js SDK on macOS using pre-built prebuilds
test-nodejs-macos:
name: Test Node.js SDK on macOS (Node 24.x)
runs-on: macos-latest
needs: [build-nodejs-macos]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js 24.x
uses: actions/setup-node@v4
with:
node-version: '24.x'
- name: Download prebuilds
uses: actions/download-artifact@v4
with:
name: prebuilds-darwin
path: prebuilds/
- name: Install dependencies
run: npm install
- name: Extract native prebuild
# Use install.js so macOS framework archives (.framework.tar.gz) are
# extracted after prebuild-install runs. --force bypasses dev-mode check.
run: node scripts/install.js --force
- name: Compile TypeScript
run: npx tsc
- name: Run Node.js tests
run: npx jest tests/ts/rtms.test.ts tests/ts/rtms.wrapper.test.ts
# Integration test: npm pack → install → load (validates end-user install flow)
test-nodejs-integration-macos:
name: Test Node.js Install Flow (macOS)
runs-on: macos-latest
needs: [build-nodejs-macos]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js 24.x
uses: actions/setup-node@v4
with:
node-version: '24.x'
- name: Download prebuilds
uses: actions/download-artifact@v4
with:
name: prebuilds-darwin
path: prebuilds/
- name: Install dependencies
run: npm install
- name: Run integration test (npm pack → install → load)
run: npx jest tests/ts/pack-install.test.js --testTimeout=120000
# Test Python SDK on Linux using pre-built wheels
test-python-linux:
name: Test Python SDK on Linux (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
needs: [build-python-wheels-linux]
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12', '3.13']
fail-fast: false # Continue testing other versions if one fails
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Download wheels
uses: actions/download-artifact@v4
with:
name: wheels-linux
path: dist/py/
- name: Install wheel for this Python version
run: |
# Convert Python version to wheel format (3.10 -> cp310)
PY_TAG="cp$(echo '${{ matrix.python-version }}' | tr -d '.')"
WHEEL=$(ls dist/py/*${PY_TAG}*manylinux*.whl 2>/dev/null | head -1)
if [ -z "$WHEEL" ]; then
echo "Error: No wheel found for Python ${{ matrix.python-version }}"
ls -la dist/py/
exit 1
fi
echo "Installing wheel: $WHEEL"
pip install "$WHEEL"
- name: Install test dependencies
run: pip install pytest python-dotenv
- name: Run Python tests
run: pytest tests/py/test_rtms.py -v
# Test Python SDK on macOS using pre-built wheels
test-python-macos:
name: Test Python SDK on macOS (Python ${{ matrix.python-version }})
runs-on: macos-latest
needs: [build-python-wheels-macos]
strategy:
matrix:
python-version: ['3.10', '3.13'] # Test minimum and latest
fail-fast: false
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Download wheels
uses: actions/download-artifact@v4
with:
name: wheels-darwin
path: dist/py/
- name: Install wheel for this Python version
run: |
# Convert Python version to wheel format (3.10 -> cp310)
PY_TAG="cp$(echo '${{ matrix.python-version }}' | tr -d '.')"
WHEEL=$(ls dist/py/*${PY_TAG}*macosx*.whl 2>/dev/null | head -1)
if [ -z "$WHEEL" ]; then
echo "Error: No wheel found for Python ${{ matrix.python-version }}"
ls -la dist/py/
exit 1
fi
echo "Installing wheel: $WHEEL"
pip install "$WHEEL"
- name: Install test dependencies
run: pip install pytest python-dotenv
- name: Run Python tests
run: pytest tests/py/test_rtms.py -v
# ============================================================================
# VERSION CHECK & PUBLISH TRIGGERS
# ============================================================================
# Check if versions have changed (only on main branch after tests pass)
check-version-change:
name: Check for Version Changes
runs-on: ubuntu-latest
needs: [test-cpp-linux, test-cpp-macos, test-nodejs-linux, test-nodejs-macos, test-nodejs-integration-macos, test-python-linux, test-python-macos]
if: |
success() &&
github.event_name == 'push' &&
github.ref == 'refs/heads/main'
outputs:
node_changed: ${{ steps.check.outputs.node_changed }}
python_changed: ${{ steps.check.outputs.python_changed }}
node_version: ${{ steps.check.outputs.node_version }}
python_version: ${{ steps.check.outputs.python_version }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Need full history for tag checking
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '24.x'
- name: Check version changes
id: check
run: |
# Get current versions from package files
NODE_VERSION=$(node -p "require('./package.json').version")
PYTHON_VERSION=$(grep '^version = ' pyproject.toml | cut -d'"' -f2)
echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT
echo "python_version=$PYTHON_VERSION" >> $GITHUB_OUTPUT
echo "Current Node.js version: $NODE_VERSION"
echo "Current Python version: $PYTHON_VERSION"
# Check if tags already exist for current versions
if git ls-remote --tags origin | grep -q "refs/tags/js-v${NODE_VERSION}$"; then
echo "node_changed=false" >> $GITHUB_OUTPUT
echo "Node.js version $NODE_VERSION already published (tag exists)"
else
echo "node_changed=true" >> $GITHUB_OUTPUT
echo "Node.js version $NODE_VERSION is NEW - will trigger publish"
fi
if git ls-remote --tags origin | grep -q "refs/tags/py-v${PYTHON_VERSION}$"; then
echo "python_changed=false" >> $GITHUB_OUTPUT
echo "Python version $PYTHON_VERSION already published (tag exists)"
else
echo "python_changed=true" >> $GITHUB_OUTPUT
echo "Python version $PYTHON_VERSION is NEW - will trigger publish"
fi
# Trigger Python publish workflow if version changed
# Note: No secrets needed - uses PyPI Trusted Publishing (OIDC)
trigger-publish-python:
name: Trigger Python Publish
needs: [check-version-change, build-python-wheels-linux, build-python-wheels-macos]
if: |
success() &&
needs.check-version-change.outputs.python_changed == 'true'
uses: ./.github/workflows/publish.yml
with:
language: python
version: ${{ needs.check-version-change.outputs.python_version }}
dry_run: false
use_existing_artifacts: true
# Trigger Node.js publish workflow if version changed
# Note: No secrets needed - uses npm Trusted Publishing (OIDC)
trigger-publish-node:
name: Trigger Node.js Publish
needs: [check-version-change, build-nodejs-linux, build-nodejs-macos]
if: |
success() &&
needs.check-version-change.outputs.node_changed == 'true'
uses: ./.github/workflows/publish.yml
with:
language: node
version: ${{ needs.check-version-change.outputs.node_version }}
dry_run: false
use_existing_artifacts: true
# ============================================================================
# DOCUMENTATION JOBS
# ============================================================================
# Build documentation (after tests pass)
build-docs:
name: Build Documentation
runs-on: ubuntu-latest
needs: [test-cpp-linux, test-cpp-macos, test-nodejs-linux, test-nodejs-macos, test-python-linux, test-python-macos]
# Only run on main/master branches and if tests pass, or via workflow_dispatch
if: |
success() &&
(
(github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')) ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.build_docs == 'true')
)
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Docker Compose
uses: docker/setup-compose-action@v1.1.0
- name: Generate all documentation via Docker
run: docker compose run --rm docs
- name: Upload documentation artifact
uses: actions/upload-artifact@v4
with:
name: documentation-site
path: ./docs
retention-days: 30
# Deploy documentation site to GitHub Pages
deploy-docs:
name: Deploy Documentation to GitHub Pages
runs-on: ubuntu-latest
needs: [build-docs]
# Only deploy from main/master branch
if: |
success() &&
(
(github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')) ||
(github.event_name == 'workflow_dispatch' &&
github.event.inputs.deploy_docs == 'true' &&
(github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'))
)
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Download documentation site artifact
uses: actions/download-artifact@v4
with:
name: documentation-site
path: ./docs
- name: Setup GitHub Pages
uses: actions/configure-pages@v5
- name: Upload site to GitHub Pages
uses: actions/upload-pages-artifact@v3
with:
path: './docs'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4