- Add conftest.py to inject lib/ onto sys.path, fixing ModuleNotFoundError on identity test collection - Add pytest-asyncio to CI install step and pyproject.toml test extras; set asyncio_mode=auto to resolve 31 async test failures flagged in session tech debt backlog - All 35 tests now pass; 8 skipped (live API, expected) Ref: Session Snapshot 2026-04-13 — "Pytest validation incomplete"
239 lines
6.5 KiB
YAML
239 lines
6.5 KiB
YAML
name: Nexus MCP - CI/CD Pipeline
|
|
|
|
on:
|
|
push:
|
|
branches: [ main, develop, rebuild-* ]
|
|
pull_request:
|
|
branches: [ main, develop ]
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
test:
|
|
name: Test Suite
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix:
|
|
python-version: ["3.11", "3.12", "3.13"]
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Python ${{ matrix.python-version }}
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: ${{ matrix.python-version }}
|
|
|
|
- name: Cache pip dependencies
|
|
uses: actions/cache@v3
|
|
with:
|
|
path: ~/.cache/pip
|
|
key: ${{ runner.os }}-pip-${{ hashFiles('nexus-mcp/pyproject.toml') }}
|
|
restore-keys: |
|
|
${{ runner.os }}-pip-
|
|
|
|
- name: Install dependencies
|
|
working-directory: nexus-mcp
|
|
run: |
|
|
python -m pip install --upgrade pip
|
|
pip install -e .
|
|
pip install pytest pytest-cov pytest-asyncio black ruff
|
|
|
|
- name: Lint with ruff
|
|
working-directory: nexus-mcp
|
|
run: |
|
|
ruff check src/ lib/ tests/ --ignore E501,F401
|
|
continue-on-error: true
|
|
|
|
- name: Format check with black
|
|
working-directory: nexus-mcp
|
|
run: |
|
|
black --check --diff src/ lib/ tests/
|
|
continue-on-error: true
|
|
|
|
- name: Run unit tests
|
|
working-directory: nexus-mcp
|
|
run: |
|
|
pytest tests/workday_tests/test_mismatch_scans.py -v --tb=short
|
|
|
|
- name: Run integration tests
|
|
working-directory: nexus-mcp
|
|
run: |
|
|
pytest tests/integration_test_audit_shard.py -v --tb=short
|
|
|
|
- name: Run all tests with coverage
|
|
working-directory: nexus-mcp
|
|
run: |
|
|
pytest tests/ -v --cov=src --cov=lib --cov-report=term --cov-report=xml
|
|
|
|
- name: Upload coverage reports
|
|
uses: codecov/codecov-action@v3
|
|
with:
|
|
file: nexus-mcp/coverage.xml
|
|
flags: unittests
|
|
name: codecov-${{ matrix.python-version }}
|
|
if: matrix.python-version == '3.13'
|
|
|
|
validate-server:
|
|
name: Validate MCP Server
|
|
runs-on: ubuntu-latest
|
|
needs: test
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.13"
|
|
|
|
- name: Install dependencies
|
|
working-directory: nexus-mcp
|
|
run: |
|
|
python -m pip install --upgrade pip
|
|
pip install -e .
|
|
|
|
- name: Validate server imports
|
|
working-directory: nexus-mcp
|
|
run: |
|
|
python -c "
|
|
import sys, os
|
|
sys.path.insert(0, 'lib')
|
|
sys.path.insert(0, 'src')
|
|
from dotenv import load_dotenv
|
|
load_dotenv()
|
|
from mcp.server.fastmcp import FastMCP
|
|
from shards import identity, workday, itsm, assets, logistics, audit
|
|
print('✅ All imports successful')
|
|
"
|
|
|
|
- name: Test server initialization
|
|
working-directory: nexus-mcp
|
|
run: |
|
|
python test_client.py > /tmp/test_output.txt
|
|
grep -q "All audit tools executed successfully" /tmp/test_output.txt
|
|
echo "✅ Server initialization validated"
|
|
|
|
- name: Verify tool registration
|
|
working-directory: nexus-mcp
|
|
run: |
|
|
python list_tools.py > /tmp/tools.txt
|
|
grep -q "48 tools available" /tmp/tools.txt
|
|
echo "✅ Tool registration validated"
|
|
|
|
security-scan:
|
|
name: Security & Dependency Check
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.13"
|
|
|
|
- name: Install safety
|
|
run: pip install safety
|
|
|
|
- name: Check dependencies for vulnerabilities
|
|
working-directory: nexus-mcp
|
|
run: |
|
|
pip install -e .
|
|
safety check --json || echo "⚠️ Security vulnerabilities found"
|
|
continue-on-error: true
|
|
|
|
- name: Scan for secrets
|
|
uses: trufflesecurity/trufflehog@main
|
|
with:
|
|
path: ./
|
|
base: ${{ github.event.repository.default_branch }}
|
|
head: HEAD
|
|
|
|
version-check:
|
|
name: Version & Changelog Check
|
|
runs-on: ubuntu-latest
|
|
if: github.event_name == 'pull_request'
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Check version bump
|
|
run: |
|
|
CURRENT_VERSION=$(grep -Po 'version = "\K[^"]*' nexus-mcp/pyproject.toml)
|
|
echo "Current version: $CURRENT_VERSION"
|
|
|
|
# Get main branch version
|
|
git fetch origin main
|
|
MAIN_VERSION=$(git show origin/main:nexus-mcp/pyproject.toml | grep -Po 'version = "\K[^"]*')
|
|
echo "Main branch version: $MAIN_VERSION"
|
|
|
|
if [ "$CURRENT_VERSION" == "$MAIN_VERSION" ]; then
|
|
echo "⚠️ Version not bumped in pyproject.toml"
|
|
echo "Please update version before merging to main"
|
|
exit 1
|
|
fi
|
|
|
|
echo "✅ Version bumped: $MAIN_VERSION → $CURRENT_VERSION"
|
|
|
|
- name: Check for CHANGELOG updates
|
|
run: |
|
|
if ! git diff origin/main...HEAD --name-only | grep -q "CHANGELOG.md\|nexus-mcp/README.md"; then
|
|
echo "⚠️ No CHANGELOG or README updates detected"
|
|
echo "Consider documenting your changes"
|
|
else
|
|
echo "✅ Documentation updated"
|
|
fi
|
|
|
|
build:
|
|
name: Build Distribution
|
|
runs-on: ubuntu-latest
|
|
needs: [test, validate-server]
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.13"
|
|
|
|
- name: Install build tools
|
|
run: pip install build twine
|
|
|
|
- name: Build package
|
|
working-directory: nexus-mcp
|
|
run: python -m build
|
|
|
|
- name: Check distribution
|
|
working-directory: nexus-mcp
|
|
run: twine check dist/*
|
|
|
|
- name: Upload artifacts
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: nexus-mcp-dist-${{ github.sha }}
|
|
path: nexus-mcp/dist/
|
|
retention-days: 30
|
|
|
|
notify:
|
|
name: Notify Status
|
|
runs-on: ubuntu-latest
|
|
needs: [test, validate-server, security-scan, build]
|
|
if: always()
|
|
|
|
steps:
|
|
- name: Report status
|
|
run: |
|
|
echo "Pipeline completed"
|
|
echo "Tests: ${{ needs.test.result }}"
|
|
echo "Validation: ${{ needs.validate-server.result }}"
|
|
echo "Security: ${{ needs.security-scan.result }}"
|
|
echo "Build: ${{ needs.build.result }}"
|