name: CI on: push: branches: [main] pull_request: branches: [main] workflow_dispatch: jobs: version-sync: name: Version Sync Check runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version-file: .node-version - name: Check version sync run: node scripts/check-version-sync.js rust: name: Rust runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Rust toolchain uses: dtolnay/rust-toolchain@stable with: components: rustfmt, clippy - name: Cache Rust build artifacts uses: Swatinem/rust-cache@v2 with: workspaces: cli - name: Format check run: cargo fmt --manifest-path cli/Cargo.toml -- --check - name: Clippy check run: cargo clippy --manifest-path cli/Cargo.toml -- -D warnings - name: Run Rust tests run: cargo test --profile ci --manifest-path cli/Cargo.toml dashboard: name: Dashboard runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version-file: .node-version - name: Install pnpm uses: pnpm/action-setup@v4 - name: Install dependencies run: pnpm install --filter dashboard working-directory: packages/dashboard - name: Build dashboard run: pnpm build working-directory: packages/dashboard sandbox-package: name: Sandbox Package runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup pnpm uses: pnpm/action-setup@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version-file: .node-version cache: pnpm - name: Install dependencies run: pnpm install --frozen-lockfile - name: Test sandbox package run: pnpm --filter @agent-browser/sandbox test rust-cross: name: Rust (${{ matrix.os }} - ${{ matrix.target }}) if: github.event_name != 'pull_request' runs-on: ${{ matrix.os }} strategy: matrix: include: - os: macos-latest target: aarch64-apple-darwin - os: macos-latest target: x86_64-apple-darwin - os: windows-latest target: x86_64-pc-windows-msvc steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Rust toolchain uses: dtolnay/rust-toolchain@stable with: targets: ${{ matrix.target }} - name: Cache Rust build artifacts uses: Swatinem/rust-cache@v2 with: workspaces: cli - name: Run Rust tests run: cargo test --profile ci --manifest-path cli/Cargo.toml --target ${{ matrix.target }} native-e2e: name: Native E2E Tests if: github.event_name != 'pull_request' runs-on: ubuntu-latest needs: rust steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Rust toolchain uses: dtolnay/rust-toolchain@stable - name: Cache Rust build artifacts uses: Swatinem/rust-cache@v2 with: workspaces: cli - name: Install Chrome run: | cargo run --manifest-path cli/Cargo.toml -- install --with-deps - name: Install ffmpeg run: sudo apt-get update && sudo apt-get install -y ffmpeg - name: Run e2e tests run: cargo test --profile ci --manifest-path cli/Cargo.toml e2e -- --ignored --test-threads=1 windows-integration: name: Windows Integration Test if: github.event_name != 'pull_request' runs-on: windows-latest needs: rust-cross steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Rust toolchain uses: dtolnay/rust-toolchain@stable with: targets: x86_64-pc-windows-msvc - name: Cache Rust build artifacts uses: Swatinem/rust-cache@v2 with: workspaces: cli - name: Build Rust CLI run: cargo build --release --manifest-path cli/Cargo.toml --target x86_64-pc-windows-msvc - name: Copy CLI binary to bin directory run: | Copy-Item cli/target/x86_64-pc-windows-msvc/release/agent-browser.exe bin/agent-browser-win32-x64.exe - name: Test agent-browser install command run: | $env:PATH = "$pwd\bin;$env:PATH" for ($i = 1; $i -le 3; $i++) { bin/agent-browser-win32-x64.exe install if ($LASTEXITCODE -eq 0) { exit 0 } Write-Host "Attempt $i failed, retrying in 10 seconds..." Start-Sleep -Seconds 10 } exit 1 shell: pwsh timeout-minutes: 10 - name: Test daemon lifecycle (open, snapshot, close) run: | $env:PATH = "$pwd\bin;$env:PATH" Write-Host "--- Opening page ---" bin/agent-browser-win32-x64.exe open https://example.com if ($LASTEXITCODE -ne 0) { Write-Error "open failed"; exit 1 } Write-Host "--- Taking snapshot ---" $snapshot = bin/agent-browser-win32-x64.exe snapshot if ($LASTEXITCODE -ne 0) { Write-Error "snapshot failed"; exit 1 } Write-Host $snapshot Write-Host "--- Closing browser ---" bin/agent-browser-win32-x64.exe close if ($LASTEXITCODE -ne 0) { Write-Error "close failed"; exit 1 } Write-Host "--- Windows daemon lifecycle test passed ---" shell: pwsh timeout-minutes: 5 global-install: name: Global Install (${{ matrix.os }}) if: github.event_name != 'pull_request' runs-on: ${{ matrix.os }} needs: rust-cross strategy: matrix: include: - os: ubuntu-latest target: x86_64-unknown-linux-gnu binary: agent-browser-linux-x64 - os: macos-latest target: aarch64-apple-darwin binary: agent-browser-darwin-arm64 - os: windows-latest target: x86_64-pc-windows-msvc binary: agent-browser-win32-x64.exe steps: - name: Checkout repository uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version-file: .node-version - name: Setup Rust toolchain uses: dtolnay/rust-toolchain@stable with: targets: ${{ matrix.target }} - name: Cache Rust build artifacts uses: Swatinem/rust-cache@v2 with: workspaces: cli - name: Build Rust CLI run: cargo build --release --manifest-path cli/Cargo.toml --target ${{ matrix.target }} - name: Copy CLI binary to bin directory (Unix) if: runner.os != 'Windows' run: cp cli/target/${{ matrix.target }}/release/agent-browser bin/${{ matrix.binary }} - name: Copy CLI binary to bin directory (Windows) if: runner.os == 'Windows' run: Copy-Item cli/target/${{ matrix.target }}/release/agent-browser.exe bin/${{ matrix.binary }} - name: Test npm global install run: | npm pack npm install -g agent-browser-*.tgz agent-browser --version shell: bash - name: Verify symlink points to native binary (Unix) if: runner.os != 'Windows' run: | SYMLINK=$(npm prefix -g)/bin/agent-browser TARGET=$(readlink "$SYMLINK") echo "Symlink: $SYMLINK" echo "Target: $TARGET" if [[ "$TARGET" != *"${{ matrix.binary }}"* ]]; then echo "ERROR: Symlink should point to native binary, not JS wrapper" exit 1 fi echo "Symlink correctly points to native binary" shell: bash - name: Verify shim points to native binary (Windows) if: runner.os == 'Windows' run: | $shimPath = "$(npm prefix -g)\agent-browser.cmd" $content = Get-Content $shimPath -Raw echo "Shim path: $shimPath" echo "Shim content:" echo $content if ($content -notmatch "agent-browser-win32-x64\.exe") { echo "ERROR: Shim should point to native .exe, not JS wrapper" exit 1 } echo "Shim correctly points to native binary" shell: pwsh