chore: english docs for demos #70
Workflow file for this run
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: From Scratch | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened] | |
| paths: | |
| - ".github/workflows/from_scratch.yml" | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: from-scratch-${{ github.head_ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| from_scratch: | |
| name: From Scratch - ${{ matrix.platform_name }} - Python ${{ matrix.python-version }} | |
| runs-on: ${{ matrix.runs-on }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - runs-on: macos-15-intel | |
| platform_name: "macOS x64" | |
| arch: "x64" | |
| python-version: "3.10" | |
| - runs-on: macos-latest | |
| platform_name: "macOS ARM64" | |
| arch: "arm64" | |
| python-version: "3.10" | |
| - runs-on: ubuntu-24.04 | |
| platform_name: "Linux x64" | |
| arch: "x64" | |
| python-version: "3.10" | |
| - runs-on: ubuntu-24.04-arm | |
| platform_name: "Linux ARM64" | |
| arch: "arm64" | |
| python-version: "3.10" | |
| - runs-on: windows-2025 | |
| platform_name: "Windows x64" | |
| arch: "x64" | |
| python-version: "3.10" | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| # This step is not necessary for the build, but it is useful for debugging. | |
| - name: Install tools and dependencies (macOS) | |
| if: runner.os == 'macOS' | |
| shell: bash | |
| run: | | |
| brew install tree | |
| - name: Install tools and dependencies (Linux) | |
| if: runner.os == 'Linux' | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Installing Linux build dependencies" | |
| echo "================================================" | |
| sudo apt-get update | |
| # Install C++ build essentials and libc++ development packages | |
| # TEN Framework uses clang and statically links libc++ on Linux | |
| # Both Linux runners use Ubuntu 24.04 which ships LLVM 18 | |
| sudo apt-get install -y \ | |
| clang \ | |
| libc++-18-dev \ | |
| libc++abi-18-dev \ | |
| tree | |
| # On ARM64, create symlinks for libc++ static libraries | |
| # (x64 runners already have them in the standard location) | |
| if [ "${{ matrix.arch }}" == "arm64" ]; then | |
| if [ -f "/usr/lib/llvm-18/lib/libc++.a" ]; then | |
| echo "" | |
| echo "Creating symlinks for libc++ static libraries on ARM64..." | |
| sudo ln -sf /usr/lib/llvm-18/lib/libc++.a /usr/lib/aarch64-linux-gnu/libc++.a | |
| sudo ln -sf /usr/lib/llvm-18/lib/libc++abi.a /usr/lib/aarch64-linux-gnu/libc++abi.a | |
| echo "✓ Symlinks created successfully" | |
| fi | |
| fi | |
| echo "" | |
| echo "✓ Linux build dependencies installed successfully" | |
| - name: Setup Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Setup Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: "stable" | |
| cache: false | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "22" | |
| - name: Verify Node.js and npm installation | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Verifying Node.js and npm installation" | |
| echo "================================================" | |
| echo "Node.js version:" | |
| node --version | |
| echo "" | |
| echo "npm location and version:" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| # On Windows, check for npm, npm.cmd, and npm.exe | |
| if command -v npm &> /dev/null; then | |
| echo "npm found: $(which npm)" | |
| npm --version | |
| elif command -v npm.cmd &> /dev/null; then | |
| echo "npm.cmd found: $(which npm.cmd)" | |
| npm.cmd --version | |
| elif command -v npm.exe &> /dev/null; then | |
| echo "npm.exe found: $(which npm.exe)" | |
| npm.exe --version | |
| else | |
| echo "❌ ERROR: npm not found in PATH" | |
| echo "PATH contents:" | |
| echo "$PATH" | tr ':' '\n' | |
| exit 1 | |
| fi | |
| else | |
| which npm | |
| npm --version | |
| fi | |
| echo "" | |
| echo "✓ Node.js and npm verified successfully" | |
| - name: Install tools and dependencies (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| Write-Host "================================================" | |
| Write-Host "Installing Windows build dependencies" | |
| Write-Host "================================================" | |
| # Disable Windows Store Python app execution aliases that shadow real Python | |
| # These aliases intercept 'python'/'python3' commands and break scripts | |
| # that check for Python availability | |
| Remove-Item "$env:LOCALAPPDATA\Microsoft\WindowsApps\python.exe" -ErrorAction SilentlyContinue | |
| Remove-Item "$env:LOCALAPPDATA\Microsoft\WindowsApps\python3.exe" -ErrorAction SilentlyContinue | |
| # Install LLVM/Clang for C++ extension builds | |
| winget install LLVM.LLVM --disable-interactivity --accept-source-agreements --accept-package-agreements | |
| # Refresh PATH so clang is available in subsequent steps | |
| $env:PATH = [System.Environment]::GetEnvironmentVariable("PATH", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("PATH", "User") | |
| echo "C:\Program Files\LLVM\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append | |
| # Create temp working directory | |
| New-Item -ItemType Directory -Force -Path "C:\Temp" | Out-Null | |
| Write-Host "" | |
| Write-Host "✓ Windows build dependencies installed successfully" | |
| - name: Install tman using package manager | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Installing tman on ${{ matrix.platform_name }} with Python ${{ matrix.python-version }}" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "macOS" ]]; then | |
| echo "Installing tman via Homebrew..." | |
| brew install TEN-framework/ten-framework/tman | |
| elif [[ "${{ runner.os }}" == "Linux" ]]; then | |
| echo "Installing tman via apt..." | |
| sudo add-apt-repository -y ppa:ten-framework/ten-framework | |
| sudo apt update | |
| sudo apt install -y tman | |
| elif [[ "${{ runner.os }}" == "Windows" ]]; then | |
| echo "Installing tman via winget..." | |
| winget install TEN-framework.tman --disable-interactivity --accept-source-agreements --accept-package-agreements | |
| # winget modifies the system/user PATH, but GitHub Actions steps | |
| # inherit the PATH snapshot from job start. Re-read the current | |
| # Machine+User PATH and add any new entries to GITHUB_PATH so | |
| # subsequent steps can find tman. | |
| NEW_PATH=$(powershell.exe -NoProfile -Command \ | |
| "[System.Environment]::GetEnvironmentVariable('PATH','Machine') + ';' + [System.Environment]::GetEnvironmentVariable('PATH','User')") | |
| echo "$NEW_PATH" | tr ';' '\n' | while IFS= read -r p; do | |
| if [ -n "$p" ] && ! echo "$PATH" | tr ':' '\n' | grep -qxF "$p"; then | |
| echo "$p" >> $GITHUB_PATH | |
| fi | |
| done | |
| else | |
| echo "❌ ERROR: Unsupported OS: ${{ runner.os }}" | |
| exit 1 | |
| fi | |
| echo "✓ tman installation completed" | |
| - name: Verify tman installation | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Verifying tman installation" | |
| echo "================================================" | |
| # Check if tman is installed | |
| if ! command -v tman &> /dev/null; then | |
| echo "❌ ERROR: tman is not installed" | |
| exit 1 | |
| fi | |
| # Display tman version and location | |
| echo "✓ tman is installed successfully" | |
| echo " Version: $(tman --version 2>&1 || tman -v 2>&1)" | |
| echo " Location: $(which tman)" | |
| # Display Python version being used | |
| echo "" | |
| echo "Python configuration:" | |
| echo " Version: $(python3 --version)" | |
| echo " Location: $(which python3)" | |
| # Verify tman can run basic commands | |
| echo "" | |
| echo "Testing basic tman commands:" | |
| tman --help | |
| - name: Setup tgn (TEN build system) | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Installing tgn build system for C++ extensions" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| # On Windows, install to a temporary directory | |
| # Use RUNNER_TEMP which is guaranteed to exist and be writable | |
| TGN_INSTALL_DIR="${RUNNER_TEMP}/ten_gn" | |
| echo "Installing tgn to: $TGN_INSTALL_DIR" | |
| # Use the PowerShell install script with custom install directory | |
| powershell -ExecutionPolicy Bypass -Command "\$env:TGN_INSTALL_DIR='$TGN_INSTALL_DIR'; & tools/tgn/install_tgn.ps1" | |
| # Add tgn to PATH for subsequent steps | |
| echo "$TGN_INSTALL_DIR" >> $GITHUB_PATH | |
| else | |
| # Install tgn using the install script | |
| # The script automatically handles CI environment and skips interactive prompts | |
| bash tools/tgn/install_tgn.sh | |
| echo "/usr/local/ten_gn" >> $GITHUB_PATH | |
| fi | |
| echo "" | |
| echo "✓ tgn setup completed" | |
| - name: Verify tgn installation | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Verifying tgn installation" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| TGN_DIR="${RUNNER_TEMP}/ten_gn" | |
| TGN_CMD="tgn.bat" | |
| else | |
| TGN_DIR="/usr/local/ten_gn" | |
| TGN_CMD="tgn" | |
| fi | |
| # Check if tgn directory exists | |
| if [ ! -d "$TGN_DIR" ]; then | |
| echo "❌ ERROR: tgn directory not found at $TGN_DIR" | |
| exit 1 | |
| fi | |
| echo "✓ tgn directory found at $TGN_DIR" | |
| echo "Contents:" | |
| ls -la "$TGN_DIR" || echo "Cannot list directory contents" | |
| # Check if tgn command exists | |
| if [ ! -f "$TGN_DIR/$TGN_CMD" ]; then | |
| echo "❌ ERROR: $TGN_CMD not found in $TGN_DIR" | |
| exit 1 | |
| fi | |
| echo "" | |
| echo "✓ $TGN_CMD found" | |
| echo "✓ tgn verification completed" | |
| - name: Create transcriber_demo app using tman | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Creating transcriber_demo app" | |
| echo "================================================" | |
| # Set working directory based on OS | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR" | |
| # Install the app using tman | |
| tman install app transcriber_demo | |
| # Verify the app was created | |
| if [ ! -d "transcriber_demo" ]; then | |
| echo "❌ ERROR: transcriber_demo app was not created" | |
| exit 1 | |
| fi | |
| echo "✓ transcriber_demo app created successfully" | |
| - name: Verify app installation | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Verifying transcriber_demo app structure" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR/transcriber_demo" | |
| # List the app structure | |
| echo "App directory structure:" | |
| ls -la | |
| # Check for common files/directories that should exist | |
| if [ -f "manifest.json" ]; then | |
| echo "✓ manifest.json exists" | |
| else | |
| echo "❌ WARNING: manifest.json not found" | |
| fi | |
| if [ -f "property.json" ]; then | |
| echo "✓ property.json exists" | |
| else | |
| echo "⚠ WARNING: property.json not found (may be optional)" | |
| fi | |
| echo "" | |
| echo "✓ App structure verification completed" | |
| - name: Install app dependencies with tman | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Installing transcriber_demo ten packages" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR/transcriber_demo" | |
| # Install TEN package dependencies using tman | |
| tman install | |
| if [[ "${{ runner.os }}" != "Windows" ]]; then | |
| tree -I . | |
| fi | |
| if [ $? -eq 0 ]; then | |
| echo "✓ tman install completed successfully" | |
| else | |
| echo "❌ ERROR: tman install failed" | |
| exit 1 | |
| fi | |
| - name: Verify ten_runtime_python package from cloud | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Verifying ten_runtime_python package" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| PYTHON_LIB="libten_runtime_python.pyd" | |
| else | |
| WORK_DIR="/tmp" | |
| PYTHON_LIB="libten_runtime_python.so" | |
| fi | |
| cd "$WORK_DIR/transcriber_demo" | |
| # Check if the Python runtime library exists | |
| if [ -f "ten_packages/system/ten_runtime_python/lib/$PYTHON_LIB" ]; then | |
| echo "✓ $PYTHON_LIB found" | |
| else | |
| echo "❌ ERROR: $PYTHON_LIB not found" | |
| echo "Package may be incomplete or download failed" | |
| exit 1 | |
| fi | |
| - name: Install pip and npm dependencies | |
| shell: bash | |
| env: | |
| # Force UTF-8 encoding on Windows to handle Unicode characters in Python scripts | |
| PYTHONIOENCODING: utf-8 | |
| run: | | |
| echo "================================================" | |
| echo "Installing pip and npm dependencies" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| # Fix PATH to use correct Python version | |
| PYTHON_PATH=$(cygpath -u "${pythonLocation}" 2>/dev/null || echo "${pythonLocation}" | sed 's|\\|/|g' | sed 's|^\([A-Za-z]\):|/\L\1|') | |
| export PATH="${PYTHON_PATH}:${PYTHON_PATH}/Scripts:$PATH" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR/transcriber_demo" | |
| # Install Python and npm dependencies using tman | |
| tman run install_deps | |
| if [ $? -eq 0 ]; then | |
| echo "✓ Dependencies installed successfully" | |
| else | |
| echo "❌ ERROR: Failed to install dependencies" | |
| exit 1 | |
| fi | |
| - name: Build app with tman | |
| shell: bash | |
| env: | |
| # Force UTF-8 encoding on Windows to handle Unicode characters in Python scripts | |
| PYTHONIOENCODING: utf-8 | |
| run: | | |
| echo "================================================" | |
| echo "Building transcriber_demo app" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| BIN_MAIN="bin/main.exe" | |
| # Fix PATH to use correct Python version | |
| PYTHON_PATH=$(cygpath -u "${pythonLocation}" 2>/dev/null || echo "${pythonLocation}" | sed 's|\\|/|g' | sed 's|^\([A-Za-z]\):|/\L\1|') | |
| export PATH="${PYTHON_PATH}:${PYTHON_PATH}/Scripts:$PATH" | |
| else | |
| WORK_DIR="/tmp" | |
| BIN_MAIN="bin/main" | |
| fi | |
| cd "$WORK_DIR/transcriber_demo" | |
| # Build the app using tman (includes go build and tsc compilation) | |
| tman run build | |
| if [ $? -ne 0 ]; then | |
| echo "❌ ERROR: tman run build failed" | |
| exit 1 | |
| fi | |
| # Verify that bin/main was generated | |
| if [ -f "$BIN_MAIN" ]; then | |
| echo "✓ $BIN_MAIN generated successfully" | |
| ls -lh "$BIN_MAIN" | |
| else | |
| echo "❌ ERROR: $BIN_MAIN not found" | |
| echo "Contents of bin directory:" | |
| ls -la bin/ || echo "bin directory does not exist" | |
| exit 1 | |
| fi | |
| echo "" | |
| echo "✓ Build verification completed" | |
| - name: Check nodejs_addon_loader manifest | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Checking nodejs_addon_loader manifest.json" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR/transcriber_demo" | |
| if [ -f "ten_packages/addon_loader/nodejs_addon_loader/manifest.json" ]; then | |
| echo "✓ nodejs_addon_loader manifest.json exists" | |
| echo "" | |
| echo "Content of manifest.json:" | |
| cat ten_packages/addon_loader/nodejs_addon_loader/manifest.json | |
| else | |
| echo "❌ WARNING: nodejs_addon_loader manifest.json not found" | |
| echo "Listing ten_packages directory structure:" | |
| ls -la ten_packages/ || echo "ten_packages directory does not exist" | |
| if [ -d "ten_packages/addon_loader" ]; then | |
| echo "Contents of ten_packages/addon_loader:" | |
| ls -la ten_packages/addon_loader/ | |
| fi | |
| fi | |
| - name: Run app with tman | |
| shell: bash | |
| env: | |
| # Force UTF-8 encoding on Windows to handle Unicode characters in Python scripts | |
| PYTHONIOENCODING: utf-8 | |
| run: | | |
| echo "================================================" | |
| echo "Running transcriber_demo app on ${{ matrix.platform_name }} with Python ${{ matrix.python-version }}" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| # Fix PATH: Ensure the correct Python version is used by tman | |
| # Convert Windows path to Unix path for Git Bash | |
| PYTHON_PATH=$(cygpath -u "${pythonLocation}" 2>/dev/null || echo "${pythonLocation}" | sed 's|\\|/|g' | sed 's|^\([A-Za-z]\):|/\L\1|') | |
| export PATH="${PYTHON_PATH}:${PYTHON_PATH}/Scripts:$PATH" | |
| echo "Python environment after PATH fix:" | |
| echo " python3 --version: $(python3 --version 2>&1)" | |
| echo " python3 location: $(which python3 2>/dev/null)" | |
| echo "" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR/transcriber_demo" | |
| # Start the app in the background | |
| echo "Starting app with 'tman run start'..." | |
| tman run start & | |
| APP_PID=$! | |
| echo "App started with PID: $APP_PID" | |
| # Wait for the app to initialize (give it some time to start) | |
| echo "Waiting for app to initialize..." | |
| sleep 10 | |
| # Check if the process is still running (not crashed) | |
| if ps -p $APP_PID > /dev/null; then | |
| echo "✓ App is running successfully (PID: $APP_PID)" | |
| else | |
| echo "❌ ERROR: App crashed or exited unexpectedly" | |
| exit 1 | |
| fi | |
| # Let the app run for a bit to ensure stability | |
| echo "App is running, waiting for 5 more seconds..." | |
| sleep 5 | |
| # Check again to ensure it's still running | |
| if ps -p $APP_PID > /dev/null; then | |
| echo "✓ App is still running stable" | |
| else | |
| echo "❌ ERROR: App crashed during runtime" | |
| exit 1 | |
| fi | |
| # Gracefully stop the app | |
| echo "" | |
| echo "Stopping app gracefully (PID: $APP_PID)..." | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| taskkill //PID $APP_PID //T //F 2>/dev/null || true | |
| else | |
| kill -TERM -$APP_PID 2>/dev/null || kill -TERM $APP_PID || true | |
| fi | |
| # Wait for the app to shut down gracefully | |
| echo "Waiting for app to shut down..." | |
| sleep 3 | |
| # Check if the app has stopped | |
| if ps -p $APP_PID > /dev/null 2>&1; then | |
| echo "⚠ App did not stop gracefully, forcing kill..." | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| taskkill //PID $APP_PID //F 2>/dev/null || true | |
| else | |
| kill -KILL -$APP_PID 2>/dev/null || kill -KILL $APP_PID || true | |
| fi | |
| sleep 1 | |
| fi | |
| # Final check | |
| if ps -p $APP_PID > /dev/null 2>&1; then | |
| echo "❌ WARNING: App process still running" | |
| else | |
| echo "✓ App stopped successfully" | |
| fi | |
| # Extra cleanup: kill any remaining transcriber_demo processes | |
| echo "Cleaning up any remaining processes..." | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| taskkill //IM "main.exe" //F 2>/dev/null || true | |
| else | |
| pkill -f "transcriber_demo" || true | |
| pkill -f "bin/main" || true | |
| fi | |
| echo "" | |
| echo "================================================" | |
| echo "✅ All verifications completed successfully on ${{ matrix.platform_name }} with Python ${{ matrix.python-version }}" | |
| echo "================================================" | |
| - name: Install C++ extension webrtc_vad_cpp | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Installing C++ extension: webrtc_vad_cpp" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR/transcriber_demo" | |
| # Install the C++ extension from the cloud store | |
| tman install extension webrtc_vad_cpp | |
| if [ $? -eq 0 ]; then | |
| echo "✓ webrtc_vad_cpp extension installed successfully" | |
| else | |
| echo "❌ ERROR: Failed to install webrtc_vad_cpp extension" | |
| exit 1 | |
| fi | |
| - name: Build app with C++ extension | |
| shell: bash | |
| env: | |
| # Force UTF-8 encoding on Windows to handle Unicode characters in Python scripts | |
| PYTHONIOENCODING: utf-8 | |
| run: | | |
| echo "================================================" | |
| echo "Rebuilding app with C++ extension" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR/transcriber_demo" | |
| # Rebuild the app to compile the C++ extension into a dynamic library | |
| tman run build | |
| if [ $? -ne 0 ]; then | |
| echo "❌ ERROR: tman run build failed with C++ extension" | |
| exit 1 | |
| fi | |
| echo "✓ App with C++ extension built successfully" | |
| - name: Run app with VAD functionality | |
| shell: bash | |
| env: | |
| # Force UTF-8 encoding on Windows to handle Unicode characters in Python scripts | |
| PYTHONIOENCODING: utf-8 | |
| run: | | |
| echo "================================================" | |
| echo "Running transcriber_demo app with VAD functionality" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR/transcriber_demo" | |
| # Start the app with VAD support in the background | |
| echo "Starting app with 'tman run start_with_vad'..." | |
| tman run start_with_vad & | |
| APP_PID=$! | |
| echo "App started with PID: $APP_PID" | |
| # Wait for the app to initialize | |
| echo "Waiting for app to initialize..." | |
| sleep 10 | |
| # Check if the process is still running (not crashed) | |
| if ps -p $APP_PID > /dev/null; then | |
| echo "✓ App with VAD is running successfully (PID: $APP_PID)" | |
| else | |
| echo "❌ ERROR: App with VAD crashed or exited unexpectedly" | |
| exit 1 | |
| fi | |
| # Let the app run for a bit to ensure stability with C++ extension | |
| echo "App is running with VAD, waiting for 5 more seconds..." | |
| sleep 5 | |
| # Check again to ensure it's still running | |
| if ps -p $APP_PID > /dev/null; then | |
| echo "✓ App with VAD is still running stable" | |
| else | |
| echo "❌ ERROR: App with VAD crashed during runtime" | |
| exit 1 | |
| fi | |
| # Gracefully stop the app | |
| echo "" | |
| echo "Stopping app gracefully (PID: $APP_PID)..." | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| taskkill //PID $APP_PID //T //F 2>/dev/null || true | |
| else | |
| kill -TERM -$APP_PID 2>/dev/null || kill -TERM $APP_PID || true | |
| fi | |
| # Wait for the app to shut down gracefully | |
| echo "Waiting for app to shut down..." | |
| sleep 3 | |
| # Check if the app has stopped | |
| if ps -p $APP_PID > /dev/null 2>&1; then | |
| echo "⚠ App did not stop gracefully, forcing kill..." | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| taskkill //PID $APP_PID //F 2>/dev/null || true | |
| else | |
| kill -KILL -$APP_PID 2>/dev/null || kill -KILL $APP_PID || true | |
| fi | |
| sleep 1 | |
| fi | |
| # Final check | |
| if ps -p $APP_PID > /dev/null 2>&1; then | |
| echo "❌ WARNING: App process still running" | |
| else | |
| echo "✓ App with VAD stopped successfully" | |
| fi | |
| # Extra cleanup | |
| echo "Cleaning up any remaining processes..." | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| taskkill //IM "main.exe" //F 2>/dev/null || true | |
| else | |
| pkill -f "transcriber_demo" || true | |
| pkill -f "bin/main" || true | |
| fi | |
| echo "" | |
| echo "================================================" | |
| echo "✅ C++ development environment verification completed on ${{ matrix.platform_name }} with Python ${{ matrix.python-version }}" | |
| echo "================================================" | |
| # ======================================== | |
| # Extension Development Verification | |
| # ======================================== | |
| - name: Create C++ extension | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Creating C++ extension for testing" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR" | |
| # Create a C++ extension using the default template | |
| tman create extension test_ext_cpp --template default_extension_cpp | |
| if [ ! -d "test_ext_cpp" ]; then | |
| echo "❌ ERROR: test_ext_cpp extension was not created" | |
| exit 1 | |
| fi | |
| echo "✓ C++ extension created successfully" | |
| - name: Install C++ extension dependencies | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Installing C++ extension dependencies" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR/test_ext_cpp" | |
| # Install dependencies in standalone mode | |
| tman install --standalone | |
| if [ $? -eq 0 ]; then | |
| echo "✓ C++ extension dependencies installed successfully" | |
| else | |
| echo "❌ ERROR: Failed to install C++ extension dependencies" | |
| exit 1 | |
| fi | |
| - name: Build C++ extension | |
| shell: bash | |
| env: | |
| # Force UTF-8 encoding on Windows to handle Unicode characters in Python scripts | |
| PYTHONIOENCODING: utf-8 | |
| run: | | |
| echo "================================================" | |
| echo "Building C++ extension" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| TEST_BIN="bin/test_ext_cpp_test.exe" | |
| else | |
| WORK_DIR="/tmp" | |
| TEST_BIN="bin/test_ext_cpp_test" | |
| fi | |
| cd "$WORK_DIR/test_ext_cpp" | |
| # Build using tman | |
| tman run build | |
| if [ $? -ne 0 ]; then | |
| echo "❌ ERROR: C++ extension build failed" | |
| exit 1 | |
| fi | |
| # Verify that test binary was generated | |
| if [ -f "$TEST_BIN" ]; then | |
| echo "✓ C++ extension test binary generated successfully" | |
| ls -lh "$TEST_BIN" | |
| else | |
| echo "❌ ERROR: C++ extension test binary not found" | |
| echo "Contents of bin directory:" | |
| ls -la bin/ || echo "bin directory does not exist" | |
| exit 1 | |
| fi | |
| - name: Test C++ extension | |
| shell: bash | |
| env: | |
| # Force UTF-8 encoding on Windows to handle Unicode characters in Python scripts | |
| PYTHONIOENCODING: utf-8 | |
| run: | | |
| echo "================================================" | |
| echo "Testing C++ extension" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR/test_ext_cpp" | |
| # Run tests using tman | |
| tman run test | |
| if [ $? -eq 0 ]; then | |
| echo "✓ C++ extension tests passed successfully" | |
| else | |
| echo "❌ ERROR: C++ extension tests failed" | |
| exit 1 | |
| fi | |
| - name: Create Go extension | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Creating Go extension for testing" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR" | |
| # Create a Go extension using the default template | |
| tman create extension test_ext_go --template default_extension_go --template-data class_name_prefix=Test | |
| if [ ! -d "test_ext_go" ]; then | |
| echo "❌ ERROR: test_ext_go extension was not created" | |
| exit 1 | |
| fi | |
| echo "✓ Go extension created successfully" | |
| - name: Install Go extension dependencies | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Installing Go extension dependencies" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR/test_ext_go" | |
| # Install dependencies in standalone mode | |
| tman install --standalone | |
| if [ $? -eq 0 ]; then | |
| echo "✓ Go extension dependencies installed successfully" | |
| else | |
| echo "❌ ERROR: Failed to install Go extension dependencies" | |
| exit 1 | |
| fi | |
| - name: Test Go extension | |
| shell: bash | |
| env: | |
| # Force UTF-8 encoding on Windows to handle Unicode characters in Python scripts | |
| PYTHONIOENCODING: utf-8 | |
| run: | | |
| echo "================================================" | |
| echo "Testing Go extension" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR/test_ext_go" | |
| # Run tests using tman | |
| tman run test | |
| if [ $? -eq 0 ]; then | |
| echo "✓ Go extension tests passed successfully" | |
| else | |
| echo "❌ ERROR: Go extension tests failed" | |
| exit 1 | |
| fi | |
| - name: Create Python extension | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Creating Python extension for testing" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR" | |
| # Create a Python extension using the default async template | |
| tman create extension test_ext_python --template default_async_extension_python --template-data class_name_prefix=Test | |
| if [ ! -d "test_ext_python" ]; then | |
| echo "❌ ERROR: test_ext_python extension was not created" | |
| exit 1 | |
| fi | |
| echo "✓ Python extension created successfully" | |
| - name: Install Python extension dependencies | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Installing Python extension dependencies" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR/test_ext_python" | |
| # Install TEN framework dependencies in standalone mode | |
| tman install --standalone | |
| if [ $? -ne 0 ]; then | |
| echo "❌ ERROR: Failed to install TEN framework dependencies" | |
| exit 1 | |
| fi | |
| # Install Python pip dependencies (pytest, etc.) | |
| if [ -f "requirements.txt" ]; then | |
| echo "" | |
| echo "Installing Python pip dependencies from requirements.txt..." | |
| python3 -m pip install -r requirements.txt | |
| if [ $? -eq 0 ]; then | |
| echo "✓ Python pip dependencies installed successfully" | |
| else | |
| echo "❌ ERROR: Failed to install Python pip dependencies" | |
| exit 1 | |
| fi | |
| else | |
| echo "⚠ WARNING: requirements.txt not found, skipping pip install" | |
| fi | |
| echo "✓ All Python extension dependencies installed successfully" | |
| - name: Test Python extension | |
| shell: bash | |
| env: | |
| # Force UTF-8 encoding on Windows to handle Unicode characters in Python scripts | |
| PYTHONIOENCODING: utf-8 | |
| run: | | |
| echo "================================================" | |
| echo "Testing Python extension" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR/test_ext_python" | |
| # Workaround: ensure binaries downloaded by tman have execute permission | |
| # (macOS runners may lack +x on spawned test binaries) | |
| if [[ "${{ runner.os }}" != "Windows" ]]; then | |
| find . -type f \( -name "*.sh" -o -path "*/bin/*" -o -path "*/.ten/*" \) -exec chmod +x {} + 2>/dev/null || true | |
| fi | |
| # Run tests using tman | |
| tman run test -- -s | |
| if [ $? -eq 0 ]; then | |
| echo "✓ Python extension tests passed successfully" | |
| else | |
| echo "❌ ERROR: Python extension tests failed" | |
| exit 1 | |
| fi | |
| - name: Create Node.js extension | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Creating Node.js extension for testing" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR" | |
| # Create a Node.js extension using the default template | |
| tman create extension test_ext_nodejs --template default_extension_nodejs --template-data class_name_prefix=Test | |
| if [ ! -d "test_ext_nodejs" ]; then | |
| echo "❌ ERROR: test_ext_nodejs extension was not created" | |
| exit 1 | |
| fi | |
| echo "✓ Node.js extension created successfully" | |
| - name: Install Node.js extension dependencies | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Installing Node.js extension dependencies" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR/test_ext_nodejs" | |
| # Install dependencies in standalone mode | |
| tman install --standalone | |
| if [ $? -eq 0 ]; then | |
| echo "✓ Node.js extension dependencies installed successfully" | |
| else | |
| echo "❌ ERROR: Failed to install Node.js extension dependencies" | |
| exit 1 | |
| fi | |
| - name: Build Node.js extension | |
| shell: bash | |
| env: | |
| # Force UTF-8 encoding on Windows to handle Unicode characters in Python scripts | |
| PYTHONIOENCODING: utf-8 | |
| run: | | |
| echo "================================================" | |
| echo "Building Node.js extension" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR/test_ext_nodejs" | |
| # Build using tman (compiles TypeScript) | |
| tman run build | |
| if [ $? -ne 0 ]; then | |
| echo "❌ ERROR: Node.js extension build failed" | |
| exit 1 | |
| fi | |
| # Verify that build output exists | |
| if [ -f ".ten/app/ten_packages/extension/test_ext_nodejs/build/index.js" ]; then | |
| echo "✓ Node.js extension compiled successfully" | |
| ls -lh .ten/app/ten_packages/extension/test_ext_nodejs/build/index.js | |
| else | |
| echo "⚠ WARNING: Build output not found in expected location" | |
| echo "Checking build directory:" | |
| find .ten -name "index.js" -type f || echo "No index.js found" | |
| fi | |
| - name: Test Node.js extension | |
| shell: bash | |
| env: | |
| # Force UTF-8 encoding on Windows to handle Unicode characters in Python scripts | |
| PYTHONIOENCODING: utf-8 | |
| run: | | |
| echo "================================================" | |
| echo "Testing Node.js extension" | |
| echo "================================================" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| WORK_DIR="C:/Temp" | |
| else | |
| WORK_DIR="/tmp" | |
| fi | |
| cd "$WORK_DIR/test_ext_nodejs" | |
| # Run tests using tman | |
| tman run test | |
| if [ $? -eq 0 ]; then | |
| echo "✓ Node.js extension tests passed successfully" | |
| else | |
| echo "❌ ERROR: Node.js extension tests failed" | |
| exit 1 | |
| fi | |
| - name: Extension Development Summary | |
| if: always() | |
| shell: bash | |
| run: | | |
| echo "================================================" | |
| echo "Extension Development Verification Summary" | |
| echo "================================================" | |
| echo "Platform: ${{ matrix.platform_name }}" | |
| echo "Python Version: ${{ matrix.python-version }}" | |
| echo "" | |
| echo "✅ All extension development workflows verified:" | |
| echo " - C++ extension: Create → Install → Build → Test" | |
| echo " - Go extension: Create → Install → Test" | |
| echo " - Python extension: Create → Install → Test" | |
| echo " - Node.js extension: Create → Install → Build → Test" | |
| echo "" | |
| echo "================================================" |