probe-code 0.6.0

AI-friendly, fully local, semantic code search tool for large codebases
Documentation
name: Integration Tests

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  integration-test:
    name: Test npm installation on ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node-version: [20]
      fail-fast: false

    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Setup Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v4
      with:
        node-version: ${{ matrix.node-version }}

    - name: Install Rust toolchain
      uses: dtolnay/rust-toolchain@stable
      with:
        components: rustfmt, clippy

    - name: Setup Rust cache
      uses: actions/cache@v4
      timeout-minutes: 5
      with:
        path: |
          ~/.cargo/bin/
          ~/.cargo/registry/index/
          ~/.cargo/registry/cache/
          ~/.cargo/git/db/
          target/
        key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-${{ hashFiles('rust-toolchain', 'rust-toolchain.toml') || 'stable' }}
        restore-keys: |
          ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-
          ${{ runner.os }}-cargo-

    - name: Build Rust binary
      run: cargo build --release

    - name: Prepare npm package with local binary
      shell: bash
      run: |
        # Create bin directory in npm package
        mkdir -p npm/bin
        
        # Copy the built binary to npm package bin directory
        if [[ "${{ runner.os }}" == "Windows" ]]; then
          cp target/release/probe.exe npm/bin/probe.exe
        else
          cp target/release/probe npm/bin/probe
          chmod +x npm/bin/probe
        fi
        
        # Install npm package dependencies
        cd npm && npm install

    - name: Install Probe locally
      run: cd npm && npm install -g .

    - name: Verify Probe installation
      run: probe --version

    - name: Test search functionality
      shell: bash
      run: |
        echo "Current directory: $(pwd)"
        echo "Probe version:"
        if [[ "${{ runner.os }}" == "Windows" ]]; then
          echo "Checking npm global installation:"
          npm list -g @buger/probe
          echo "Checking probe binary permissions:"
          ls -la "$(which probe)" || echo "probe command not found in PATH"
          ls -la "$(npm root -g)/@buger/probe/bin/" || echo "npm package bin directory not found"
          probe --version
        else
          npm --version
          probe --version
        fi
        echo "Running search command..."
        if [[ "${{ runner.os }}" == "Windows" ]]; then
          # Try direct binary execution if npm wrapper fails
          "$(npm root -g)/@buger/probe/bin/probe.exe" search "semantic code search" README.md --format json > search_results.json || \
          probe search "semantic code search" README.md --format json > search_results.json
        else
          probe search "semantic code search" README.md --format json > search_results.json
        fi
        echo "Search command completed, checking file size:"
        if [[ "${{ runner.os }}" == "Windows" ]]; then
          powershell -Command "Get-ChildItem search_results.json | Select-Object Name,Length"
          echo "File contents (first 10 lines):"
          powershell -Command "Get-Content search_results.json | Select-Object -First 10"
        else
          ls -la search_results.json
          echo "File contents (first 10 lines):"
          head -10 search_results.json
        fi

    - name: Verify search results (Unix)
      if: runner.os != 'Windows'
      run: |
        # Check that the JSON output contains expected fields
        if ! grep -q '"file"' search_results.json; then
          echo "Error: JSON output missing 'file' field"
          cat search_results.json
          exit 1
        fi

        if ! grep -q '"code"' search_results.json; then
          echo "Error: JSON output missing 'code' field"
          cat search_results.json
          exit 1
        fi

        if ! grep -q 'README.md' search_results.json; then
          echo "Error: Search results don't contain README.md"
          cat search_results.json
          exit 1
        fi

        if ! grep -q 'semantic code search' search_results.json; then
          echo "Error: Search results don't contain the search term"
          cat search_results.json
          exit 1
        fi

        echo "✅ Search results validation passed"

    - name: Verify search results (Windows)
      if: runner.os == 'Windows'
      run: |
        # Check that the JSON output contains expected fields
        if (-not (Test-Path search_results.json)) {
          Write-Host "Error: search_results.json file not found"
          exit 1
        }
        
        $content = Get-Content search_results.json -Raw
        if (-not $content) {
          Write-Host "Error: search_results.json file is empty"
          exit 1
        }
        
        # Extract JSON part by finding the first '{' character (skip debug output)
        $jsonStart = $content.IndexOf('{')
        if ($jsonStart -eq -1) {
          Write-Host "Error: No JSON found in output"
          Get-Content search_results.json
          exit 1
        }
        $jsonContent = $content.Substring($jsonStart)

        if (-not ($jsonContent -match '"file"')) {
          Write-Host "Error: JSON output missing 'file' field"
          Get-Content search_results.json
          exit 1
        }

        if (-not ($jsonContent -match '"code"')) {
          Write-Host "Error: JSON output missing 'code' field"
          Get-Content search_results.json
          exit 1
        }

        if (-not ($jsonContent -match 'README.md')) {
          Write-Host "Error: Search results don't contain README.md"
          Get-Content search_results.json
          exit 1
        }

        if (-not ($jsonContent -match 'semantic code search')) {
          Write-Host "Error: Search results don't contain the search term"
          Get-Content search_results.json
          exit 1
        }

        Write-Host "✅ Search results validation passed"

    - name: Test extract functionality
      shell: bash
      run: |
        echo "Running extract command..."
        if [[ "${{ runner.os }}" == "Windows" ]]; then
          # Try direct binary execution if npm wrapper fails
          "$(npm root -g)/@buger/probe/bin/probe.exe" extract README.md:1 --format json > extract_results.json || \
          probe extract README.md:1 --format json > extract_results.json
        else
          probe extract README.md:1 --format json > extract_results.json
        fi

    - name: Verify extract results (Unix)
      if: runner.os != 'Windows'
      run: |
        # Check that the extract output contains expected fields
        if ! grep -q '"file"' extract_results.json; then
          echo "Error: Extract JSON output missing 'file' field"
          cat extract_results.json
          exit 1
        fi

        if ! grep -q 'README.md' extract_results.json; then
          echo "Error: Extract results don't contain README.md"
          cat extract_results.json
          exit 1
        fi

        echo "✅ Extract results validation passed"

    - name: Verify extract results (Windows)
      if: runner.os == 'Windows'
      run: |
        # Check that the extract output contains expected fields
        if (-not (Test-Path extract_results.json)) {
          Write-Host "Error: extract_results.json file not found"
          exit 1
        }
        
        $content = Get-Content extract_results.json -Raw
        if (-not $content) {
          Write-Host "Error: extract_results.json file is empty"
          exit 1
        }
        
        # Extract JSON part by finding the first '{' character (skip debug output)
        $jsonStart = $content.IndexOf('{')
        if ($jsonStart -eq -1) {
          Write-Host "Error: No JSON found in output"
          Get-Content extract_results.json
          exit 1
        }
        $jsonContent = $content.Substring($jsonStart)

        if (-not ($jsonContent -match '"file"')) {
          Write-Host "Error: Extract JSON output missing 'file' field"
          Get-Content extract_results.json
          exit 1
        }

        if (-not ($jsonContent -match 'README.md')) {
          Write-Host "Error: Extract results don't contain README.md"
          Get-Content extract_results.json
          exit 1
        }

        Write-Host "✅ Extract results validation passed"

    - name: Upload test artifacts on failure
      if: failure()
      uses: actions/upload-artifact@v4
      with:
        name: test-results-${{ matrix.os }}-node${{ matrix.node-version }}
        path: |
          search_results.json
          extract_results.json
        retention-days: 7