Skip to content

Merge branch 'mediar-ai:main' into test-cli-ci #76

Merge branch 'mediar-ai:main' into test-cli-ci

Merge branch 'mediar-ai:main' into test-cli-ci #76

Workflow file for this run

# 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\*