Merge branch 'mediar-ai:main' into test-cli-ci #77
This file contains 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
# testing locally with act cli | |
# act -W .github/workflows/ci.yml --container-architecture linux/amd64 -env ACTIONS_RUNTIME_URL=http://host.docker.internal:8080/ --env ACTIONS_RUNTIME_TOKEN=foo --env ACTIONS_CACHE_URL=http://host.docker.internal:8080/ --artifact-server-path out -j build-ubuntu -P ubuntu-latest=-self-hosted --env-file .env --secret-file .secrets | |
name: Rust CI | |
on: | |
push: | |
pull_request: | |
jobs: | |
test-ubuntu: | |
runs-on: ubuntu-latest | |
env: | |
RUSTFLAGS: "-C link-arg=-Wl,--allow-multiple-definition" | |
steps: | |
- uses: actions/checkout@v3 | |
- uses: actions/cache@v3 | |
with: | |
path: | | |
~/.cargo/bin/ | |
~/.cargo/registry/index/ | |
~/.cargo/registry/cache/ | |
~/.cargo/git/db/ | |
target/ | |
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} | |
- uses: actions-rs/toolchain@v1 | |
with: | |
profile: minimal | |
toolchain: stable | |
override: true | |
- name: Install dependencies | |
run: | | |
sudo apt-get update | |
sudo apt-get install -y tesseract-ocr libtesseract-dev libavformat-dev libavfilter-dev libavdevice-dev ffmpeg libasound2-dev libgtk-3-dev libsoup-3.0-dev libjavascriptcoregtk-4.1-dev libwebkit2gtk-4.1-dev | |
sudo apt-get install -y libxcb-randr0-dev libxcb-xtest0-dev libxcb-xinerama0-dev libxcb-shape0-dev libxcb-xkb-dev | |
- name: Copy test image | |
run: | | |
mkdir -p target/debug/deps | |
cp screenpipe-vision/tests/testing_OCR.png target/debug/deps/ | |
- name: Run tests | |
run: cargo test | |
test-windows: | |
runs-on: windows-latest | |
steps: | |
- uses: actions/checkout@v3 | |
- uses: actions/cache@v3 | |
with: | |
path: | | |
~\AppData\Local\cargo\ | |
target\ | |
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} | |
- uses: actions-rs/toolchain@v1 | |
with: | |
profile: minimal | |
toolchain: stable | |
- name: setup Bun | |
uses: oven-sh/setup-bun@v1 | |
- name: Run pre_build.js on | |
shell: bash | |
run: bun ./scripts/pre_build.js | |
working-directory: ./screenpipe-app-tauri | |
- name: Copy test image | |
shell: bash | |
run: | | |
mkdir -p target/debug/deps || true | |
cp screenpipe-vision/tests/testing_OCR.png target/debug/deps/ | |
- name: Run specific Windows OCR test | |
run: cargo test test_process_ocr_task_windows | |
test-macos: | |
runs-on: macos-latest | |
steps: | |
- uses: actions/checkout@v3 | |
- uses: actions/cache@v3 | |
with: | |
path: | | |
~\AppData\Local\cargo\ | |
target\ | |
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} | |
- uses: actions-rs/toolchain@v1 | |
with: | |
profile: minimal | |
toolchain: stable | |
- name: setup Bun | |
uses: oven-sh/setup-bun@v1 | |
- name: Run pre_build.js on | |
shell: bash | |
env: | |
SKIP_SCREENPIPE_SETUP: true # avoid trying to copy screenpipe binaries, not yet built (next step) | |
run: bun ./scripts/pre_build.js | |
working-directory: ./screenpipe-app-tauri | |
- name: Copy test image | |
shell: bash | |
run: | | |
mkdir -p target/debug/deps || true | |
cp screenpipe-vision/tests/testing_OCR.png target/debug/deps/ | |
- name: Run specific Apple OCR test | |
shell: bash | |
env: | |
DYLD_LIBRARY_PATH: /Users/runner/work/screenpipe/screenpipe/screenpipe-vision/lib | |
run: cargo test test_apple_native_ocr | |
build-cli: | |
strategy: | |
matrix: | |
os: [ubuntu-latest, windows-latest] | |
runs-on: ${{ matrix.os }} | |
steps: | |
- uses: actions/checkout@v3 | |
- uses: actions/cache@v3 | |
with: | |
path: | | |
~/.cargo/bin/ | |
~/.cargo/registry/index/ | |
~/.cargo/registry/cache/ | |
~/.cargo/git/db/ | |
target/ | |
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} | |
- uses: actions-rs/toolchain@v1 | |
with: | |
profile: minimal | |
toolchain: stable | |
- name: Install dependencies (Ubuntu) | |
if: matrix.os == 'ubuntu-latest' | |
run: | | |
sudo apt-get update | |
sudo apt-get install -y libasound2-dev libgtk-3-dev libsoup-3.0-dev libjavascriptcoregtk-4.1-dev libwebkit2gtk-4.1-dev ffmpeg | |
sudo apt-get install -y libavutil-dev libavformat-dev libavfilter-dev libavdevice-dev | |
sudo apt-get install -y pkg-config xvfb pulseaudio xdotool x11-xserver-utils sox | |
sudo apt-get install -y libx11-dev libxcb1-dev | |
sudo apt-get install -y scrot | |
sudo apt-get install -y libxcb-randr0-dev libxcb-xtest0-dev libxcb-xinerama0-dev libxcb-shape0-dev libxcb-xkb-dev | |
sudo apt-get install -y xterm openbox alsa-utils | |
- name: Build CLI | |
run: cargo build --release --bin screenpipe | |
env: | |
CARGO_NET_GIT_FETCH_WITH_CLI: true | |
RUSTFLAGS: "-C target-cpu=native" | |
- uses: actions/upload-artifact@v3 | |
with: | |
name: screenpipe-${{ matrix.os }} | |
path: target/release/screenpipe* | |
test-cli-ubuntu: | |
needs: build-cli | |
runs-on: ubuntu-latest | |
timeout-minutes: 360 | |
steps: | |
- uses: actions/checkout@v3 | |
- uses: actions/download-artifact@v3 | |
with: | |
name: screenpipe-ubuntu-latest | |
path: . | |
- name: Install dependencies (Ubuntu) | |
timeout-minutes: 30 | |
run: | | |
sudo apt-get update | |
sudo apt-get install -y xvfb pulseaudio ffmpeg imagemagick xdotool x11-xserver-utils xterm openbox alsa-utils sox tesseract-ocr libtesseract-dev | |
- name: Setup display and window manager (Ubuntu) | |
timeout-minutes: 30 | |
run: | | |
# Start Xvfb | |
Xvfb :99 -ac -screen 0 1024x768x24 & | |
export DISPLAY=:99 | |
echo "DISPLAY=:99" >> $GITHUB_ENV | |
sleep 5 | |
# Start window manager | |
openbox & | |
sleep 5 | |
# Start a visible application | |
xterm -e "echo 'Test Window'; while true; do date; sleep 1; done" & | |
sleep 5 | |
- name: Setup audio (Ubuntu) | |
timeout-minutes: 30 | |
run: | | |
# Setup audio | |
pulseaudio --start | |
sleep 2 | |
pactl load-module module-null-sink sink_name=virtual_speaker | |
pactl set-default-sink virtual_speaker | |
pactl load-module module-virtual-source source_name=virtual_mic master=virtual_speaker.monitor | |
pactl set-default-source virtual_mic | |
sleep 5 | |
- name: Debug information (Ubuntu) | |
timeout-minutes: 30 | |
run: | | |
echo "Window list:" | |
xwininfo -root -tree | |
echo "Display info:" | |
xdpyinfo | head -n 20 | |
echo "Audio devices:" | |
pactl list short sinks | |
pactl list short sources | |
- name: Start simulations (Ubuntu) | |
timeout-minutes: 30 | |
run: | | |
# Start screen and audio simulation | |
chmod +x ./scripts/simulate_screen_activity.sh | |
chmod +x ./scripts/simulate_audio_activity.sh | |
./scripts/simulate_screen_activity.sh & | |
./scripts/simulate_audio_activity.sh & | |
- name: Run screenpipe and health checks (Ubuntu) | |
timeout-minutes: 30 | |
run: | | |
# Run screenpipe | |
chmod +x ./screenpipe | |
mkdir -p ./test_data/logs | |
RUST_LOG=debug,screenpipe=trace RUST_BACKTRACE=1 ./screenpipe --data-dir ./test_data --fps 1 > ./test_data/logs/screenpipe.log 2>&1 & | |
CLI_PID=$! | |
echo "Screenpipe PID: $CLI_PID" | |
# Wait longer for initialization | |
sleep 60 | |
# Check if screenpipe is still running | |
if ! ps -p $CLI_PID > /dev/null; then | |
echo "Screenpipe process has died" | |
cat ./test_data/logs/screenpipe.log | |
exit 1 | |
fi | |
# Health checks | |
for i in {1..30}; do | |
response=$(curl -s http://localhost:3030/health) | |
echo "Health check $i: $response" | |
status=$(echo $response | jq -r '.status') | |
frame_status=$(echo $response | jq -r '.frame_status') | |
audio_status=$(echo $response | jq -r '.audio_status') | |
if [[ "$status" == "Healthy" && "$frame_status" == "OK" && "$audio_status" == "OK" ]]; then | |
echo "Health check passed" | |
exit 0 | |
fi | |
# Check if screenpipe is still running | |
if ! ps -p $CLI_PID > /dev/null; then | |
echo "Screenpipe process has died during health checks" | |
break | |
fi | |
sleep 10 | |
done | |
echo "Health check failed after 5 minutes" | |
echo "Screenpipe log:" | |
cat ./test_data/logs/screenpipe.log | |
echo "Xvfb log:" | |
cat /tmp/.X99-lock | |
echo "Process list:" | |
ps aux | grep -E 'Xvfb|pulseaudio|openbox|xterm|screenpipe' | |
echo "Audio devices:" | |
pactl list short sinks | |
pactl list short sources | |
echo "Network connections:" | |
netstat -tuln | grep 3030 | |
exit 1 | |
test-cli-windows: | |
needs: [build-cli, test-cli-ubuntu] | |
runs-on: windows-latest | |
timeout-minutes: 360 | |
steps: | |
- uses: actions/checkout@v3 | |
- uses: actions/download-artifact@v3 | |
with: | |
name: screenpipe-windows-latest | |
path: . | |
- name: Install dependencies | |
shell: pwsh | |
run: | | |
choco install ffmpeg pkgconfiglite rust -y | |
choco install visualstudio2022buildtools -y | |
choco install visualstudio2022-workload-vctools -y | |
git clone https://github.com/microsoft/vcpkg.git C:\vcpkg | |
C:\vcpkg\bootstrap-vcpkg.bat -disableMetrics | |
C:\vcpkg\vcpkg.exe integrate install --disable-metrics | |
C:\vcpkg\vcpkg.exe install ffmpeg | |
$env:PKG_CONFIG_PATH = "C:\vcpkg\packages\ffmpeg_x64-windows\lib\pkgconfig" | |
$env:VCPKG_ROOT = "C:\vcpkg" | |
$env:LIBCLANG_PATH = "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\Llvm\x64\bin" | |
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") | |
- name: Install Scream virtual audio driver | |
shell: powershell | |
run: | | |
Invoke-WebRequest https://github.com/duncanthrax/scream/releases/download/4.0/Scream4.0.zip -OutFile Scream4.0.zip | |
Expand-Archive -Path Scream4.0.zip -DestinationPath Scream | |
openssl req -batch -verbose -x509 -newkey rsa -keyout ScreamCertificate.pvk -out ScreamCertificate.cer -nodes -extensions v3_req | |
openssl pkcs12 -export -nodes -in ScreamCertificate.cer -inkey ScreamCertificate.pvk -out ScreamCertificate.pfx -passout pass: | |
- name: Setup MSVC Dev Cmd | |
uses: ilammy/msvc-dev-cmd@v1 | |
- name: Sign and Install Scream Driver | |
shell: powershell | |
run: | | |
signtool sign /v /fd SHA256 /f ScreamCertificate.pfx Scream\Install\driver\x64\Scream.cat | |
Import-Certificate -FilePath ScreamCertificate.cer -CertStoreLocation Cert:\LocalMachine\root | |
Import-Certificate -FilePath ScreamCertificate.cer -CertStoreLocation Cert:\LocalMachine\TrustedPublisher | |
Scream\Install\helpers\devcon-x64.exe install Scream\Install\driver\x64\Scream.inf *Scream | |
timeout-minutes: 5 | |
- name: Start Windows Audio Service | |
run: net start audiosrv | |
shell: powershell | |
- name: Setup audio device for testing | |
shell: pwsh | |
run: | | |
Write-Output "All audio devices:" | |
Get-WmiObject Win32_SoundDevice | Select-Object Name, Status, ConfigManagerErrorCode | Format-Table -AutoSize | |
Write-Output "Scream audio devices:" | |
$screamDevice = Get-WmiObject Win32_SoundDevice | Where-Object { $_.Name -like "*Scream*" } | |
if ($screamDevice) { | |
$env:TEST_AUDIO_DEVICE = $screamDevice.Name | |
Write-Output "Using Scream audio device: $($env:TEST_AUDIO_DEVICE)" | |
echo "TEST_AUDIO_DEVICE=$($env:TEST_AUDIO_DEVICE)" >> $env:GITHUB_ENV | |
} else { | |
Write-Warning "Scream audio device not found. TEST_AUDIO_DEVICE will not be set." | |
} | |
# Additional debugging information | |
Write-Output "Audio endpoints:" | |
Get-CimInstance Win32_SoundDevice | Format-Table Name, Status, ConfigManagerErrorCode | |
Write-Output "MMDevice audio endpoints:" | |
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | |
$devices = [System.Windows.Forms.SystemInformation]::SoundDevices | |
$devices | ForEach-Object { Write-Output $_ } | |
- name: Install Tesseract OCR | |
shell: pwsh | |
run: | | |
choco install tesseract -y | |
$env:Path += ";C:\Program Files\Tesseract-OCR" | |
refreshenv | |
Write-Output "Tesseract version:" | |
& "C:\Program Files\Tesseract-OCR\tesseract.exe" --version | |
- name: Setup and run CLI (Windows) | |
shell: pwsh | |
run: | | |
# Ensure Tesseract is in PATH | |
$env:Path += ";C:\Program Files\Tesseract-OCR" | |
Write-Output "Tesseract version:" | |
& "C:\Program Files\Tesseract-OCR\tesseract.exe" --version | |
$env:RUST_LOG = "trace,screenpipe=trace,screenpipe_audio=trace" | |
$env:RUST_BACKTRACE = "full" | |
New-Item -ItemType Directory -Force -Path .\test_data\logs | |
# Debug: Print the TEST_AUDIO_DEVICE value | |
Write-Output "TEST_AUDIO_DEVICE: $env:TEST_AUDIO_DEVICE" | |
# Construct the command arguments | |
$args = @("--data-dir", ".\test_data", "--fps", "1") | |
if ($env:TEST_AUDIO_DEVICE) { | |
# Append "(output)" to the device name to specify it's an output device | |
$audioDeviceWithType = "$($env:TEST_AUDIO_DEVICE) (output)" | |
# Escape the audio device name to handle spaces and special characters | |
$escapedAudioDevice = """$audioDeviceWithType""" | |
$args += "--audio-device", $escapedAudioDevice | |
} else { | |
Write-Warning "TEST_AUDIO_DEVICE is not set. Running without --audio-device parameter." | |
} | |
# Modify the audio simulation script | |
$audioSimulationScript = @" | |
Add-Type -AssemblyName System.Speech | |
`$synthesizer = New-Object System.Speech.Synthesis.SpeechSynthesizer | |
while (`$true) { | |
`$synthesizer.Speak("This is a test audio for Screenpipe.") | |
Start-Sleep -Seconds 5 | |
} | |
"@ | |
$audioSimulationScript | Out-File -FilePath .\scripts\simulate_audio_activity.ps1 -Encoding utf8 | |
# Start screen and audio simulation | |
Start-Process -FilePath powershell -ArgumentList "-File", ".\scripts\simulate_screen_activity.ps1" -NoNewWindow | |
Start-Process -FilePath powershell -ArgumentList "-File", ".\scripts\simulate_audio_activity.ps1" -NoNewWindow | |
# Start the process with the constructed arguments | |
$processArgs = $args -join ' ' | |
Write-Output "Running command: .\screenpipe.exe $processArgs" | |
$process = Start-Process -FilePath .\screenpipe.exe -ArgumentList $processArgs -NoNewWindow -PassThru -RedirectStandardOutput .\test_data\logs\screenpipe_output.log -RedirectStandardError .\test_data\logs\screenpipe_error.log | |
if ($null -eq $process) { | |
Write-Error "Failed to start screenpipe process" | |
exit 1 | |
} | |
Write-Output "Screenpipe process started with PID: $($process.Id)" | |
Start-Sleep -Seconds 60 | |
if (Get-Process -Id $process.Id -ErrorAction SilentlyContinue) { | |
Write-Output "Screenpipe process is still running" | |
} else { | |
Write-Error "Screenpipe process has terminated unexpectedly" | |
Get-Content .\test_data\logs\screenpipe_output.log | |
Get-Content .\test_data\logs\screenpipe_error.log | |
exit 1 | |
} | |
# Health checks | |
$attempts = 30 | |
$interval = 10 | |
for ($i = 0; $i -lt $attempts; $i++) { | |
Start-Sleep -Seconds $interval | |
try { | |
$response = Invoke-RestMethod -Uri http://localhost:3030/health -ErrorAction Stop | |
Write-Output "Health check $($i+1): $($response | ConvertTo-Json -Compress)" | |
if ($response.status -eq "Healthy" -and $response.frame_status -eq "OK" -and $response.audio_status -eq "OK") { | |
Write-Output "Health check passed" | |
exit 0 | |
} | |
} catch { | |
Write-Output "Error occurred while checking health: $_" | |
} | |
if (-not (Get-Process -Id $process.Id -ErrorAction SilentlyContinue)) { | |
Write-Error "Screenpipe process has terminated during health checks" | |
Get-Content .\test_data\logs\screenpipe_output.log | |
Get-Content .\test_data\logs\screenpipe_error.log | |
exit 1 | |
} | |
} | |
Write-Error "Health check failed after 5 minutes" | |
Get-Content .\test_data\logs\screenpipe_output.log | |
Get-Content .\test_data\logs\screenpipe_error.log | |
Write-Output "Process list:" | |
Get-Process | Where-Object { $_.Name -match 'screenpipe|ffmpeg' } | Format-Table -AutoSize | |
exit 1 | |
- name: Debug audio capture | |
shell: pwsh | |
run: | | |
Write-Output "Audio devices:" | |
Get-CimInstance Win32_SoundDevice | Format-Table Name, Status, ConfigManagerErrorCode | |
Write-Output "Active audio sessions:" | |
Get-Process | Where-Object {$_.Name -eq "audiodg"} | Format-Table Name, Id, CPU | |
Write-Output "Screenpipe process details:" | |
Get-Process -Name screenpipe | Format-Table Name, Id, CPU, WorkingSet, PrivateMemorySize | |
Write-Output "Recent Screenpipe log entries:" | |
Get-Content .\test_data\logs\screenpipe_output.log -Tail 50 | |
Get-Content .\test_data\logs\screenpipe_error.log -Tail 50 | |
- name: Upload logs | |
if: always() | |
uses: actions/upload-artifact@v3 | |
with: | |
name: windows-test-logs | |
path: .\test_data\logs\* |