nexus-mcp/.github/workflows/nexus-mcp-ci.yml
nathan cc00efc4c1 fix(ci): resolve test collection and async failures
- 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"
2026-04-13 13:22:00 -04:00

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 }}"