Skip to content

fix: Protect Docker image from auto-cleanup and add auto-build #10

fix: Protect Docker image from auto-cleanup and add auto-build

fix: Protect Docker image from auto-cleanup and add auto-build #10

Workflow file for this run

name: Test Suite
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
env:
NODE_VERSION: '20'
POLARS_MAX_THREADS: '4'
DUCKDB_MEMORY_LIMIT: '2GB'
jobs:
# ============================================================
# UNIT TESTS
# Fast feedback on code changes without Docker
# ============================================================
unit-tests:
runs-on: ubuntu-latest
name: Unit Tests
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build TypeScript
run: npm run build
- name: Run unit tests
run: npm run test:unit
- name: Check TypeScript compilation
run: npx tsc --noEmit
# ============================================================
# CORE E2E TESTS
# Docker-based integration tests for core functionality
# ============================================================
e2e-tests-core:
runs-on: ubuntu-latest
name: E2E Tests - Core
needs: unit-tests
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Install dependencies
run: npm ci
- name: Build TypeScript
run: npm run build
- name: Build Docker image
run: npm run docker:build
- name: Run core E2E tests
run: NODE_OPTIONS='--experimental-vm-modules' npx jest tests/e2e/MCPServer.test.ts tests/e2e/DockerSandbox.test.ts --testTimeout=120000
timeout-minutes: 15
- name: Cleanup Docker containers
if: always()
run: |
docker ps -a --filter "label=mcp-session" -q | xargs -r docker rm -f || true
docker system prune -f
# ============================================================
# ANALYTICS E2E TESTS
# Tests for analytics functionality (Polars, DuckDB, Pandas)
# ============================================================
e2e-tests-analytics:
runs-on: ubuntu-latest
name: E2E Tests - Analytics
needs: unit-tests
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Install dependencies
run: npm ci
- name: Build TypeScript
run: npm run build
- name: Build Docker image with analytics libraries
run: npm run docker:build
- name: Run analytics E2E tests
run: NODE_OPTIONS='--experimental-vm-modules' npx jest tests/e2e/Analytics.test.ts --testTimeout=180000
timeout-minutes: 20
env:
POLARS_MAX_THREADS: ${{ env.POLARS_MAX_THREADS }}
DUCKDB_MEMORY_LIMIT: ${{ env.DUCKDB_MEMORY_LIMIT }}
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: analytics-test-results
path: |
test-results/
coverage/
- name: Cleanup Docker containers
if: always()
run: |
docker ps -a --filter "label=mcp-session" -q | xargs -r docker rm -f || true
docker system prune -f
# ============================================================
# SECURITY TESTS
# Isolation, resource limits, and security scenarios
# ============================================================
security-tests:
runs-on: ubuntu-latest
name: Security Tests
needs: e2e-tests-core
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Install dependencies
run: npm ci
- name: Build TypeScript
run: npm run build
- name: Build Docker image
run: npm run docker:build
- name: Run security tests
run: |
NODE_OPTIONS='--experimental-vm-modules' npx jest tests/e2e --testNamePattern="Security|Isolation|Network|User|Memory" --testTimeout=120000
timeout-minutes: 10
- name: Test path traversal prevention
run: |
echo "Testing path traversal protection..."
# This would run specific security test cases
- name: Test resource limits
run: |
echo "Testing resource limit enforcement..."
# Verify memory and CPU limits
- name: Cleanup
if: always()
run: |
docker ps -a --filter "label=mcp-session" -q | xargs -r docker rm -f || true
# ============================================================
# PERFORMANCE TESTS
# Benchmarks and performance regression detection
# ============================================================
performance-tests:
runs-on: ubuntu-latest
name: Performance Tests
needs: [e2e-tests-core, e2e-tests-analytics]
if: github.event_name == 'pull_request' || github.ref == 'refs/heads/main'
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Install dependencies
run: npm ci
- name: Build TypeScript
run: npm run build
- name: Build Docker image
run: npm run docker:build
- name: Run performance benchmarks
run: |
NODE_OPTIONS='--experimental-vm-modules' npx jest tests/e2e/Analytics.test.ts --testNamePattern="Performance" --testTimeout=300000
timeout-minutes: 10
- name: Upload performance metrics
if: always()
uses: actions/upload-artifact@v4
with:
name: performance-metrics
path: |
performance-results/
- name: Cleanup
if: always()
run: |
docker ps -a --filter "label=mcp-session" -q | xargs -r docker rm -f || true
# ============================================================
# COVERAGE REPORT
# Combined coverage from all test suites
# ============================================================
coverage:
runs-on: ubuntu-latest
name: Coverage Report
needs: [unit-tests, e2e-tests-core, e2e-tests-analytics]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Install dependencies
run: npm ci
- name: Build TypeScript
run: npm run build
- name: Build Docker image
run: npm run docker:build
- name: Run all tests with coverage
run: npm test -- --coverage
timeout-minutes: 20
- name: Generate coverage report
run: |
echo "## Coverage Summary" > coverage-summary.md
cat coverage/lcov-report/index.html | grep -o '>[0-9]\+%' | head -4 >> coverage-summary.md
- name: Upload coverage report
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: |
coverage/
coverage-summary.md
- name: Check coverage thresholds
run: |
# Extract coverage percentages and check against thresholds
STATEMENTS=$(cat coverage/coverage-summary.json | grep -o '"statements":{"total":[0-9]*,"covered":[0-9]*,"skipped":[0-9]*,"pct":[0-9.]*' | grep -o '"pct":[0-9.]*' | cut -d':' -f2)
BRANCHES=$(cat coverage/coverage-summary.json | grep -o '"branches":{"total":[0-9]*,"covered":[0-9]*,"skipped":[0-9]*,"pct":[0-9.]*' | grep -o '"pct":[0-9.]*' | cut -d':' -f2)
FUNCTIONS=$(cat coverage/coverage-summary.json | grep -o '"functions":{"total":[0-9]*,"covered":[0-9]*,"skipped":[0-9]*,"pct":[0-9.]*' | grep -o '"pct":[0-9.]*' | cut -d':' -f2)
LINES=$(cat coverage/coverage-summary.json | grep -o '"lines":{"total":[0-9]*,"covered":[0-9]*,"skipped":[0-9]*,"pct":[0-9.]*' | grep -o '"pct":[0-9.]*' | cut -d':' -f2)
echo "Statements: ${STATEMENTS}%"
echo "Branches: ${BRANCHES}%"
echo "Functions: ${FUNCTIONS}%"
echo "Lines: ${LINES}%"
# Fail if below thresholds (70%)
if (( $(echo "$STATEMENTS < 70" | bc -l) )); then echo "Statements coverage below 70%"; exit 1; fi
if (( $(echo "$BRANCHES < 70" | bc -l) )); then echo "Branches coverage below 70%"; exit 1; fi
if (( $(echo "$FUNCTIONS < 70" | bc -l) )); then echo "Functions coverage below 70%"; exit 1; fi
if (( $(echo "$LINES < 70" | bc -l) )); then echo "Lines coverage below 70%"; exit 1; fi
- name: Cleanup
if: always()
run: |
docker ps -a --filter "label=mcp-session" -q | xargs -r docker rm -f || true
# ============================================================
# DOCUMENTATION CHECK
# Verify ADRs and specifications are up to date
# ============================================================
documentation-check:
runs-on: ubuntu-latest
name: Documentation Check
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Check ADR files exist
run: |
test -f docs/ADR-001-analytics-architecture.md || (echo "ADR-001 missing"; exit 1)
test -f docs/ADR-002-context-management.md || (echo "ADR-002 missing"; exit 1)
test -f docs/ADR-003-caching-optimization.md || (echo "ADR-003 missing"; exit 1)
test -f docs/MCP-SPECIFICATION.md || (echo "MCP-SPECIFICATION missing"; exit 1)
echo "All documentation files present"
- name: Verify README is up to date
run: |
grep -q "Analytics" README.md || echo "Note: README may need analytics section update"
- name: Check test documentation
run: |
test -f tests/ANALYTICS_TEST_CASES.md || (echo "Analytics test cases missing"; exit 1)
echo "Test documentation complete"