Merge pull request #8 from niksacdev/add-claude-github-actions-175539… #13
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: 🧪 Test Suite | |
| on: | |
| push: | |
| branches: [main, develop] | |
| pull_request: | |
| branches: [main, develop] | |
| workflow_dispatch: # Allow manual triggers | |
| env: | |
| PYTHON_VERSION: "3.10" | |
| jobs: | |
| test: | |
| name: Run Tests & Coverage | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: 📥 Checkout code | |
| uses: actions/checkout@v4 | |
| - name: 🐍 Set up Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: 📦 Install UV | |
| run: | | |
| curl -LsSf https://astral.sh/uv/install.sh | sh | |
| echo "$HOME/.cargo/bin" >> $GITHUB_PATH | |
| - name: 🔄 Install dependencies | |
| run: | | |
| uv sync | |
| - name: 🧪 Run agent registry tests (core functionality) | |
| run: | | |
| echo "Running core agent registry tests..." | |
| uv run pytest tests/test_agent_registry.py -v --cov=loan_processing.agents.providers.openai.agentregistry --cov-report=term-missing | |
| - name: 🧪 Run comprehensive test suite | |
| run: | | |
| echo "Running all available tests..." | |
| uv run python run_tests.py | |
| - name: 📊 Check test coverage on core components | |
| run: | | |
| echo "Checking coverage on core agent registry component..." | |
| uv run python -c " | |
| import sys | |
| import re | |
| import subprocess | |
| # Run coverage on the core agent registry | |
| result = subprocess.run([ | |
| 'uv', 'run', 'pytest', | |
| 'tests/test_agent_registry.py', | |
| '--cov=loan_processing.agents.providers.openai.agentregistry', | |
| '--cov=loan_processing.agents.shared', | |
| '--cov-report=term-missing' | |
| ], capture_output=True, text=True) | |
| # Extract coverage percentage | |
| output = result.stdout | |
| print('Coverage Output:') | |
| print(output) | |
| coverage_match = re.search(r'TOTAL.*?(\d+)%', output) | |
| if coverage_match: | |
| coverage = int(coverage_match.group(1)) | |
| print(f'Coverage: {coverage}%') | |
| if coverage < 90: | |
| print(f'❌ Coverage {coverage}% is below required 90%') | |
| sys.exit(1) | |
| else: | |
| print(f'✅ Coverage {coverage}% meets requirement') | |
| else: | |
| print('⚠️ Could not determine exact coverage percentage') | |
| # Check if tests passed anyway | |
| if result.returncode == 0: | |
| print('✅ Tests passed, proceeding...') | |
| else: | |
| print('❌ Tests failed') | |
| sys.exit(1) | |
| " | |
| - name: 🎯 Test Results Summary | |
| if: always() | |
| run: | | |
| echo "## 🧪 Test Results" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if [ ${{ job.status }} == 'success' ]; then | |
| echo "✅ **All tests passed with ≥90% coverage on core components!**" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "The code is ready for merge." >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "❌ **Tests failed or coverage below 90%**" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "Please fix failing tests before merging." >> $GITHUB_STEP_SUMMARY | |
| fi | |
| lint: | |
| name: Code Quality | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: 📥 Checkout code | |
| uses: actions/checkout@v4 | |
| - name: 🐍 Set up Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: 📦 Install UV | |
| run: | | |
| curl -LsSf https://astral.sh/uv/install.sh | sh | |
| echo "$HOME/.cargo/bin" >> $GITHUB_PATH | |
| - name: 🔄 Install dependencies | |
| run: | | |
| uv sync | |
| - name: 🔍 Run type checking (mypy) | |
| run: | | |
| uv run mypy loan_processing/ --ignore-missing-imports | |
| continue-on-error: true # Don't fail on type issues for now | |
| - name: 🧹 Run linting (ruff) | |
| run: | | |
| uv run ruff check . | |
| - name: 🎨 Check code formatting (ruff format) | |
| run: | | |
| uv run ruff format --check . | |
| security: | |
| name: Security Scan | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: 📥 Checkout code | |
| uses: actions/checkout@v4 | |
| - name: 🐍 Set up Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: 📦 Install UV | |
| run: | | |
| curl -LsSf https://astral.sh/uv/install.sh | sh | |
| echo "$HOME/.cargo/bin" >> $GITHUB_PATH | |
| - name: 🔄 Install dependencies | |
| run: | | |
| uv sync | |
| - name: 🔒 Run security audit | |
| run: | | |
| uv run pip-audit --desc --local | |
| continue-on-error: true # Don't fail build on security warnings, just report | |
| - name: 🛡️ Upload security results | |
| if: always() | |
| run: | | |
| echo "Security scan completed. Review any warnings manually." | |
| validate-architecture: | |
| name: Architecture Validation | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: 📥 Checkout code | |
| uses: actions/checkout@v4 | |
| - name: 🏗️ Validate domain boundaries | |
| run: | | |
| echo "🔍 Checking for SDK imports in domain layers..." | |
| # Check that shared models and tools don't import SDK-specific code | |
| sdk_imports=$(grep -r "from openai\|import openai\|from anthropic\|import anthropic" loan_processing/agents/shared/ loan_processing/tools/services/ || true) | |
| if [ -n "$sdk_imports" ]; then | |
| echo "❌ Found SDK imports in domain layers:" | |
| echo "$sdk_imports" | |
| echo "" | |
| echo "Domain models and services must remain provider-agnostic." | |
| echo "Move SDK-specific code to providers/ directories." | |
| exit 1 | |
| else | |
| echo "✅ Domain boundaries are clean - no SDK imports found" | |
| fi | |
| - name: 📁 Validate file organization | |
| run: | | |
| echo "🔍 Checking project structure..." | |
| required_dirs=( | |
| "loan_processing/agents/shared/models" | |
| "loan_processing/agents/providers/openai" | |
| "loan_processing/tools/services" | |
| "loan_processing/tools/mcp_servers" | |
| "tests" | |
| ) | |
| for dir in "${required_dirs[@]}"; do | |
| if [ ! -d "$dir" ]; then | |
| echo "❌ Required directory missing: $dir" | |
| exit 1 | |
| else | |
| echo "✅ Found: $dir" | |
| fi | |
| done | |
| - name: 🧪 Validate test structure | |
| run: | | |
| echo "🔍 Checking test organization..." | |
| # Verify main test file exists and is working | |
| if [ -f "tests/test_agent_registry.py" ]; then | |
| echo "✅ Core test file found: tests/test_agent_registry.py" | |
| # Run a quick validation | |
| uv run python -c " | |
| import sys | |
| sys.path.append('.') | |
| try: | |
| from tests.test_agent_registry import TestAgentRegistryCreation | |
| print('✅ Core test class imports successfully') | |
| except ImportError as e: | |
| print(f'❌ Test import failed: {e}') | |
| sys.exit(1) | |
| " | |
| else | |
| echo "❌ Core test file missing: tests/test_agent_registry.py" | |
| exit 1 | |
| fi |