Skip to content

fix(mcp): swap TextContent block order — text summary last for single… #104

fix(mcp): swap TextContent block order — text summary last for single…

fix(mcp): swap TextContent block order — text summary last for single… #104

name: QA - MCP EU AI Act
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
workflow_dispatch:
jobs:
test:
name: Tests & Coverage
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12']
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest pytest-cov pytest-asyncio
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Run tests with coverage
run: |
pytest tests/ -v \
--cov=. \
--cov-report=term-missing \
--cov-report=xml \
--cov-report=html \
--cov-fail-under=80
- name: Upload coverage to Codecov
if: matrix.python-version == '3.11'
uses: codecov/codecov-action@v5
with:
file: ./coverage.xml
flags: unittests
name: codecov-mcp-eu-ai-act
fail_ci_if_error: false
- name: Archive coverage HTML report
if: matrix.python-version == '3.11'
uses: actions/upload-artifact@v7
with:
name: coverage-report
path: htmlcov/
retention-days: 30
quality-gates:
name: Quality Gates
runs-on: ubuntu-latest
needs: test
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Python 3.11
uses: actions/setup-python@v6
with:
python-version: '3.11'
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest pytest-cov pytest-asyncio
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Check test files exist
run: |
if [ ! -d "tests" ]; then
echo "❌ No tests/ directory found"
exit 1
fi
TEST_COUNT=$(find tests -name "test_*.py" | wc -l)
if [ $TEST_COUNT -eq 0 ]; then
echo "❌ No test files found"
exit 1
fi
echo "✅ Found $TEST_COUNT test files"
- name: Verify pytest configuration
run: |
if [ ! -f "pytest.ini" ] && [ ! -f "pyproject.toml" ] && [ ! -f "setup.cfg" ]; then
echo "⚠️ No pytest configuration found (pytest.ini, pyproject.toml, or setup.cfg)"
echo "Continuing anyway..."
else
echo "✅ Pytest configuration found"
fi
- name: Check for security test markers
run: |
SECURITY_TESTS=$(grep -r "@pytest.mark.security" tests/ | wc -l || echo "0")
if [ $SECURITY_TESTS -eq 0 ]; then
echo "⚠️ No security tests found (no @pytest.mark.security markers)"
echo "Consider adding security tests"
else
echo "✅ Found $SECURITY_TESTS security test markers"
fi
- name: Check for code smells (TODO/FIXME/HACK)
run: |
SMELLS=$(grep -r "TODO\|FIXME\|HACK" --include="*.py" --exclude-dir=tests . | wc -l || echo "0")
if [ $SMELLS -gt 0 ]; then
echo "⚠️ Found $SMELLS code smells (TODO/FIXME/HACK)"
grep -r "TODO\|FIXME\|HACK" --include="*.py" --exclude-dir=tests . || true
echo "This is a warning, not blocking the build"
else
echo "✅ No code smells found"
fi
- name: Run coverage check
run: |
coverage run -m pytest tests/
coverage report --fail-under=80
coverage json
COVERAGE=$(python -c "import json; print(json.load(open('coverage.json'))['totals']['percent_covered'])")
echo "📊 Coverage: ${COVERAGE}%"
echo "coverage=${COVERAGE}" >> $GITHUB_OUTPUT
id: coverage
- name: Generate coverage badge
if: github.ref == 'refs/heads/main'
run: |
COVERAGE=${{ steps.coverage.outputs.coverage }}
COLOR="red"
if (( $(echo "$COVERAGE >= 80" | bc -l) )); then
COLOR="brightgreen"
elif (( $(echo "$COVERAGE >= 70" | bc -l) )); then
COLOR="green"
elif (( $(echo "$COVERAGE >= 50" | bc -l) )); then
COLOR="yellow"
fi
echo "Coverage: ${COVERAGE}% (${COLOR})"
# Badge will be created by shields.io: https://img.shields.io/badge/coverage-${COVERAGE}%25-${COLOR}
integration-test:
name: Integration Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Python 3.11
uses: actions/setup-python@v6
with:
python-version: '3.11'
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Run integration tests
run: |
if [ -d "tests" ]; then
pytest tests/ -v -m "integration" --tb=short || echo "No integration tests found"
fi
- name: Test MCP server standalone
run: |
timeout 10s python3 server.py || echo "✅ Server ran successfully (timeout expected)"
security-scan:
name: Security Scan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Python 3.11
uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Install security tools
run: |
python -m pip install --upgrade pip
pip install bandit
- name: Install pip-audit
run: pip install pip-audit
- name: Run Bandit (security linter)
run: |
bandit -r . -f json -o bandit-report.json || true
bandit -r . -ll || true
- name: Check dependencies for vulnerabilities (pip-audit)
run: |
if [ -f requirements.txt ]; then
pip-audit -r requirements.txt --format=json -o pip-audit-report.json || echo "⚠️ Vulnerabilities found, check pip-audit-report.json"
pip-audit -r requirements.txt || true
else
echo "No requirements.txt found, skipping pip-audit"
fi
- name: Upload security reports
uses: actions/upload-artifact@v7
with:
name: security-reports
path: |
bandit-report.json
pip-audit-report.json
retention-days: 30
build-status:
name: Build Status Summary
runs-on: ubuntu-latest
needs: [test, quality-gates, integration-test, security-scan]
if: always()
steps:
- name: Check build status
run: |
echo "==================================="
echo " MCP EU AI Act - Build Summary"
echo "==================================="
echo ""
echo "✅ Tests: ${{ needs.test.result }}"
echo "✅ Quality Gates: ${{ needs.quality-gates.result }}"
echo "✅ Integration: ${{ needs.integration-test.result }}"
echo "✅ Security: ${{ needs.security-scan.result }}"
echo ""
if [ "${{ needs.test.result }}" != "success" ] || [ "${{ needs.quality-gates.result }}" != "success" ]; then
echo "❌ Build FAILED"
exit 1
else
echo "✅ Build PASSED"
fi