Skip to content

feat: Add js-debug adapter support for JavaScript/TypeScript debugging #24

feat: Add js-debug adapter support for JavaScript/TypeScript debugging

feat: Add js-debug adapter support for JavaScript/TypeScript debugging #24

Workflow file for this run

name: E2E Tests
# Flaky Test Detection:
# Tests use nick-fields/retry@v3 with max_attempts: 3 and timeout_minutes: 5
# This catches transient failures while limiting false positives
# Tests that pass on retry are considered "flaky" and should be investigated
on:
push:
branches: [master, main]
pull_request:
branches: [master, main]
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
jobs:
# Build the debugger CLI for each platform
build:
name: Build (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache Cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Build debugger CLI
run: cargo build --release
- name: Upload debugger binary
uses: actions/upload-artifact@v4
with:
name: debugger-${{ matrix.os }}
path: target/release/debugger
retention-days: 1
# LLDB tests - C/C++/Rust debugging
test-lldb:
name: LLDB Tests (${{ matrix.os }})
needs: build
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download debugger binary
uses: actions/download-artifact@v4
with:
name: debugger-${{ matrix.os }}
path: target/release/
- name: Make debugger executable
run: chmod +x target/release/debugger
- name: Install LLDB (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y lldb gcc
- name: Install build tools (macOS)
if: matrix.os == 'macos-latest'
run: brew install gcc || true
- name: Compile C test fixtures
run: |
gcc -g tests/fixtures/simple.c -o tests/fixtures/test_simple_c || true
gcc -g tests/e2e/hello_world.c -o tests/e2e/test_c || true
gcc -g -pthread tests/fixtures/threaded.c -o tests/fixtures/test_threaded_c || true
- name: Compile Rust test fixtures
run: |
rustc -g tests/fixtures/simple.rs -o tests/fixtures/test_simple_rs || true
rustc -g tests/e2e/hello_world.rs -o tests/e2e/test_rs || true
- name: Run C Hello World Test
uses: nick-fields/retry@v3
with:
timeout_minutes: 5
max_attempts: 3
command: ./target/release/debugger test tests/scenarios/hello_world_c.yml --verbose
- name: Run Rust Hello World Test
uses: nick-fields/retry@v3
with:
timeout_minutes: 5
max_attempts: 3
command: ./target/release/debugger test tests/scenarios/hello_world_rust.yml --verbose
- name: Run Complex Verification Test
uses: nick-fields/retry@v3
with:
timeout_minutes: 5
max_attempts: 3
command: ./target/release/debugger test tests/scenarios/complex_verification.yml --verbose
- name: Run Conditional Breakpoint Test
uses: nick-fields/retry@v3
with:
timeout_minutes: 5
max_attempts: 3
command: ./target/release/debugger test tests/scenarios/conditional_breakpoint_c.yml --verbose
- name: Run Hit Count Breakpoint Test
uses: nick-fields/retry@v3
with:
timeout_minutes: 5
max_attempts: 3
command: ./target/release/debugger test tests/scenarios/hitcount_breakpoint_c.yml --verbose
- name: Run Breakpoint Management Test
uses: nick-fields/retry@v3
with:
timeout_minutes: 5
max_attempts: 3
command: ./target/release/debugger test tests/scenarios/breakpoint_management_c.yml --verbose
- name: Run Stack Navigation Test
uses: nick-fields/retry@v3
with:
timeout_minutes: 5
max_attempts: 3
command: ./target/release/debugger test tests/scenarios/stack_navigation_c.yml --verbose
- name: Run Output Capture Test
uses: nick-fields/retry@v3
with:
timeout_minutes: 5
max_attempts: 3
command: ./target/release/debugger test tests/scenarios/output_capture_c.yml --verbose
- name: Run Program Restart Test
uses: nick-fields/retry@v3
with:
timeout_minutes: 5
max_attempts: 3
command: ./target/release/debugger test tests/scenarios/program_restart_c.yml --verbose
- name: Run Pause Resume Test
uses: nick-fields/retry@v3
with:
timeout_minutes: 5
max_attempts: 3
command: ./target/release/debugger test tests/scenarios/pause_resume_c.yml --verbose
- name: Run Thread List Test
uses: nick-fields/retry@v3
with:
timeout_minutes: 5
max_attempts: 3
command: ./target/release/debugger test tests/scenarios/thread_list_c.yml --verbose
- name: Cleanup daemon
if: always()
run: pkill -f "debugger daemon" || true
- name: Upload logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: lldb-logs-${{ matrix.os }}
path: ~/.local/share/debugger/logs/
# Delve tests - Go debugging
test-delve:
name: Delve Tests (${{ matrix.os }})
needs: build
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download debugger binary
uses: actions/download-artifact@v4
with:
name: debugger-${{ matrix.os }}
path: target/release/
- name: Make debugger executable
run: chmod +x target/release/debugger
- name: Install Go
uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Install Delve
run: go install github.com/go-delve/delve/cmd/dlv@latest
- name: Compile Go test fixtures
run: |
go build -gcflags='all=-N -l' -o tests/e2e/test_go tests/e2e/hello_world.go
go build -gcflags='all=-N -l' -o tests/fixtures/test_simple_go tests/fixtures/simple.go
go build -gcflags='all=-N -l' -o tests/fixtures/test_threaded_go tests/fixtures/threaded.go
- name: Run Go Hello World Test
run: ./target/release/debugger test tests/scenarios/hello_world_go.yml --verbose
continue-on-error: true
- name: Run Go Complex Test
run: ./target/release/debugger test tests/scenarios/complex_go.yml --verbose
continue-on-error: true
- name: Run Conditional Breakpoint Test
run: ./target/release/debugger test tests/scenarios/conditional_breakpoint_go.yml --verbose
continue-on-error: true
- name: Run Hit Count Breakpoint Test
run: ./target/release/debugger test tests/scenarios/hitcount_breakpoint_go.yml --verbose
continue-on-error: true
- name: Run Stack Navigation Test
run: ./target/release/debugger test tests/scenarios/stack_navigation_go.yml --verbose
continue-on-error: true
- name: Run Output Capture Test
run: ./target/release/debugger test tests/scenarios/output_capture_go.yml --verbose
continue-on-error: true
- name: Run Program Restart Test
run: ./target/release/debugger test tests/scenarios/program_restart_go.yml --verbose
continue-on-error: true
- name: Run Thread List Test
run: ./target/release/debugger test tests/scenarios/thread_list_go.yml --verbose
continue-on-error: true
- name: Cleanup daemon
if: always()
run: pkill -f "debugger daemon" || true
- name: Upload logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: delve-logs-${{ matrix.os }}
path: ~/.local/share/debugger/logs/
# debugpy tests - Python debugging
test-debugpy:
name: debugpy Tests (${{ matrix.os }})
needs: build
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download debugger binary
uses: actions/download-artifact@v4
with:
name: debugger-${{ matrix.os }}
path: target/release/
- name: Make debugger executable
run: chmod +x target/release/debugger
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install debugpy
run: pip install debugpy
- name: Run Python Hello World Test
run: ./target/release/debugger test tests/scenarios/hello_world_python.yml --verbose
continue-on-error: true
- name: Run Conditional Breakpoint Test
run: ./target/release/debugger test tests/scenarios/conditional_breakpoint_py.yml --verbose
continue-on-error: true
- name: Run Stack Navigation Test
run: ./target/release/debugger test tests/scenarios/stack_navigation_py.yml --verbose
continue-on-error: true
- name: Run Output Capture Test
run: ./target/release/debugger test tests/scenarios/output_capture_py.yml --verbose
continue-on-error: true
- name: Cleanup daemon
if: always()
run: pkill -f "debugger daemon" || true
- name: Upload logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: debugpy-logs-${{ matrix.os }}
path: ~/.local/share/debugger/logs/
# js-debug tests - JavaScript/TypeScript debugging
test-js-debug:
name: js-debug Tests (${{ matrix.os }})
needs: build
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download debugger binary
uses: actions/download-artifact@v4
with:
name: debugger-${{ matrix.os }}
path: target/release/
- name: Make debugger executable
run: chmod +x target/release/debugger
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install TypeScript and compile fixtures
run: |
npm install -g typescript
cd tests/fixtures && npm install && npx tsc
- name: Setup js-debug adapter
run: ./target/release/debugger setup js-debug || true
- name: Check js-debug installation
run: |
echo "=== Checking js-debug installation ==="
ls -la ~/.local/share/debugger/adapters/ 2>/dev/null || true
find ~/.local/share/debugger/adapters/ -name "*.js" 2>/dev/null | head -5 || true
- name: Run JavaScript Hello World Test
run: ./target/release/debugger test tests/scenarios/hello_world_js.yml --verbose
continue-on-error: true
- name: Run TypeScript Hello World Test
run: ./target/release/debugger test tests/scenarios/hello_world_ts.yml --verbose
continue-on-error: true
- name: Run JavaScript Stepping Test
run: ./target/release/debugger test tests/scenarios/stepping_js.yml --verbose
continue-on-error: true
- name: Run JavaScript Expression Eval Test
run: ./target/release/debugger test tests/scenarios/expression_eval_js.yml --verbose
continue-on-error: true
- name: Run Conditional Breakpoint Test
run: ./target/release/debugger test tests/scenarios/conditional_breakpoint_js.yml --verbose
continue-on-error: true
- name: Run Stack Navigation Test
run: ./target/release/debugger test tests/scenarios/stack_navigation_js.yml --verbose
continue-on-error: true
- name: Run Output Capture Test
run: ./target/release/debugger test tests/scenarios/output_capture_js.yml --verbose
continue-on-error: true
- name: Cleanup daemon
if: always()
run: pkill -f "debugger daemon" || true
- name: Upload logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: js-debug-logs-${{ matrix.os }}
path: ~/.local/share/debugger/logs/
# GDB tests - C/C++ debugging with GDB (native DAP or cdt-gdb-adapter bridge)
test-gdb:
name: GDB Tests
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download debugger binary
uses: actions/download-artifact@v4
with:
name: debugger-ubuntu-latest
path: target/release/
- name: Make debugger executable
run: chmod +x target/release/debugger
- name: Install GDB and build tools
run: |
sudo apt-get update
sudo apt-get install -y gdb gcc g++
- name: Check GDB version
run: gdb --version | head -1
- name: Install Node.js for cdt-gdb-adapter
uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install cdt-gdb-adapter (for GDB < 14.1)
run: npm install -g cdt-gdb-adapter || true
- name: Compile C test fixtures
run: |
gcc -g tests/fixtures/simple.c -o tests/fixtures/test_simple_c
gcc -g tests/e2e/hello_world.c -o tests/e2e/test_c
gcc -g -pthread tests/fixtures/threaded.c -o tests/fixtures/test_threaded_c
- name: Run C Hello World Test with GDB
run: ./target/release/debugger test tests/scenarios/hello_world_c.yml --adapter gdb --verbose
continue-on-error: true
- name: Run Conditional Breakpoint Test with GDB
run: ./target/release/debugger test tests/scenarios/conditional_breakpoint_c.yml --adapter gdb --verbose
continue-on-error: true
- name: Run Hit Count Breakpoint Test with GDB
run: ./target/release/debugger test tests/scenarios/hitcount_breakpoint_c.yml --adapter gdb --verbose
continue-on-error: true
- name: Run Breakpoint Management Test with GDB
run: ./target/release/debugger test tests/scenarios/breakpoint_management_c.yml --adapter gdb --verbose
continue-on-error: true
- name: Run Stack Navigation Test with GDB
run: ./target/release/debugger test tests/scenarios/stack_navigation_c.yml --adapter gdb --verbose
continue-on-error: true
- name: Run Output Capture Test with GDB
run: ./target/release/debugger test tests/scenarios/output_capture_c.yml --adapter gdb --verbose
continue-on-error: true
- name: Run Program Restart Test with GDB
run: ./target/release/debugger test tests/scenarios/program_restart_c.yml --adapter gdb --verbose
continue-on-error: true
- name: Run Pause Resume Test with GDB
run: ./target/release/debugger test tests/scenarios/pause_resume_c.yml --adapter gdb --verbose
continue-on-error: true
- name: Run Thread List Test with GDB
run: ./target/release/debugger test tests/scenarios/thread_list_c.yml --adapter gdb --verbose
continue-on-error: true
- name: Cleanup daemon
if: always()
run: pkill -f "debugger daemon" || true
- name: Upload logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: gdb-logs
path: ~/.local/share/debugger/logs/
# GDB tests on macOS - with Homebrew installation
test-gdb-macos:
name: GDB Tests (macOS)
needs: build
runs-on: macos-latest
continue-on-error: true
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download debugger binary
uses: actions/download-artifact@v4
with:
name: debugger-macos-latest
path: target/release/
- name: Make debugger executable
run: chmod +x target/release/debugger
- name: Install GDB via Homebrew
id: install-gdb
run: |
brew install gdb || echo "gdb_install_failed=true" >> $GITHUB_OUTPUT
if command -v gdb &> /dev/null; then
echo "GDB installed successfully"
gdb --version | head -1
echo "gdb_available=true" >> $GITHUB_OUTPUT
else
echo "GDB installation failed or not available"
echo "gdb_available=false" >> $GITHUB_OUTPUT
fi
- name: Install Node.js and cdt-gdb-adapter
if: steps.install-gdb.outputs.gdb_available == 'true'
uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install cdt-gdb-adapter (for GDB < 14.1)
if: steps.install-gdb.outputs.gdb_available == 'true'
run: npm install -g cdt-gdb-adapter || true
- name: Compile C test fixtures
if: steps.install-gdb.outputs.gdb_available == 'true'
run: |
gcc -g tests/fixtures/simple.c -o tests/fixtures/test_simple_c
gcc -g tests/e2e/hello_world.c -o tests/e2e/test_c
gcc -g -pthread tests/fixtures/threaded.c -o tests/fixtures/test_threaded_c
- name: Run C Hello World Test with GDB
if: steps.install-gdb.outputs.gdb_available == 'true'
run: ./target/release/debugger test tests/scenarios/hello_world_c.yml --adapter gdb --verbose
continue-on-error: true
- name: Run Conditional Breakpoint Test with GDB
if: steps.install-gdb.outputs.gdb_available == 'true'
run: ./target/release/debugger test tests/scenarios/conditional_breakpoint_c.yml --adapter gdb --verbose
continue-on-error: true
- name: Run Hit Count Breakpoint Test with GDB
if: steps.install-gdb.outputs.gdb_available == 'true'
run: ./target/release/debugger test tests/scenarios/hitcount_breakpoint_c.yml --adapter gdb --verbose
continue-on-error: true
- name: Run Breakpoint Management Test with GDB
if: steps.install-gdb.outputs.gdb_available == 'true'
run: ./target/release/debugger test tests/scenarios/breakpoint_management_c.yml --adapter gdb --verbose
continue-on-error: true
- name: Run Stack Navigation Test with GDB
if: steps.install-gdb.outputs.gdb_available == 'true'
run: ./target/release/debugger test tests/scenarios/stack_navigation_c.yml --adapter gdb --verbose
continue-on-error: true
- name: Run Output Capture Test with GDB
if: steps.install-gdb.outputs.gdb_available == 'true'
run: ./target/release/debugger test tests/scenarios/output_capture_c.yml --adapter gdb --verbose
continue-on-error: true
- name: Run Program Restart Test with GDB
if: steps.install-gdb.outputs.gdb_available == 'true'
run: ./target/release/debugger test tests/scenarios/program_restart_c.yml --adapter gdb --verbose
continue-on-error: true
- name: Run Pause Resume Test with GDB
if: steps.install-gdb.outputs.gdb_available == 'true'
run: ./target/release/debugger test tests/scenarios/pause_resume_c.yml --adapter gdb --verbose
continue-on-error: true
- name: Run Thread List Test with GDB
if: steps.install-gdb.outputs.gdb_available == 'true'
run: ./target/release/debugger test tests/scenarios/thread_list_c.yml --adapter gdb --verbose
continue-on-error: true
- name: Skip tests if GDB unavailable
if: steps.install-gdb.outputs.gdb_available != 'true'
run: echo "Skipping GDB tests - GDB not available on macOS"
- name: Cleanup daemon
if: always()
run: pkill -f "debugger daemon" || true
- name: Upload logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: gdb-macos-logs
path: ~/.local/share/debugger/logs/
# Integration tests with Rust test framework
integration-tests:
name: Integration Tests
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache Cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Install LLDB
run: |
sudo apt-get update
sudo apt-get install -y lldb gcc
- name: Install Go and Delve
run: |
sudo apt-get install -y golang-go
go install github.com/go-delve/delve/cmd/dlv@latest
- name: Install Python and debugpy
run: |
sudo apt-get install -y python3 python3-pip
pip3 install debugpy
- name: Install Node.js and js-debug
uses: actions/setup-node@v4
with:
node-version: '22'
- name: Compile test fixtures
run: |
gcc -g tests/fixtures/simple.c -o tests/fixtures/test_simple_c || true
rustc -g tests/fixtures/simple.rs -o tests/fixtures/test_simple_rs || true
go build -gcflags='all=-N -l' -o tests/fixtures/test_simple_go tests/fixtures/simple.go || true
cd tests/fixtures && npm install && npx tsc || true
- name: Run integration tests
run: cargo test --test integration -- --test-threads=1
continue-on-error: true
- name: Cleanup daemon
if: always()
run: pkill -f "debugger daemon" || true
- name: Upload logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: integration-logs
path: ~/.local/share/debugger/logs/
# Summary job
e2e-summary:
name: E2E Test Summary
needs: [test-lldb, test-delve, test-debugpy, test-js-debug, test-gdb, test-gdb-macos, integration-tests]
runs-on: ubuntu-latest
if: always()
steps:
- name: Check test results
run: |
echo "## E2E Test Results Summary"
echo ""
echo "| Test Suite | Status |"
echo "|------------|--------|"
echo "| LLDB | ${{ needs.test-lldb.result }} |"
echo "| Delve | ${{ needs.test-delve.result }} |"
echo "| debugpy | ${{ needs.test-debugpy.result }} |"
echo "| js-debug | ${{ needs.test-js-debug.result }} |"
echo "| GDB | ${{ needs.test-gdb.result }} |"
echo "| GDB (macOS) | ${{ needs.test-gdb-macos.result }} |"
echo "| Integration | ${{ needs.integration-tests.result }} |"
echo ""
echo "All test suites completed."