name: MCP Self-Learning Server CI/CD
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
env:
NODE_VERSION: '18'
jobs:
test:
name: Test & Lint
runs-on: ubuntu-latest
steps:
- name: π₯ Checkout code
uses: actions/checkout@v4
- name: π§ Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: π¦ Install dependencies
run: npm ci
- name: π§Ή Run linting
run: npm run lint || echo "Linting not configured"
- name: π§ͺ Run unit tests
run: npm run test:unit
- name: π Run integration tests
run: npm run test:integration
- name: π Generate coverage report
run: npm run test:coverage || echo "Coverage not configured"
- name: π₯ Run health check
run: |
npm link
timeout 10s mcp-learn health || echo "Health check completed"
- name: β‘ Test CLI commands
run: |
mcp-learn --version
mcp-learn --help
echo "CLI tests passed"
- name: π Setup Python (for Python client tests)
uses: actions/setup-python@v4
with:
python-version: '3.9'
- name: π Install Python dependencies
run: |
python -m pip install --upgrade pip
pip install aiohttp websockets
- name: π§ͺ Test Python client
run: |
# Start server in background
nohup npm start &
sleep 5
# Test Python client (basic import test)
python -c "
import sys
sys.path.insert(0, './lib')
try:
from self_learning_client import SelfLearningClient
print('β
Python client imports successfully')
except ImportError as e:
print(f'β Python client import failed: {e}')
sys.exit(1)
"
security:
name: Security Audit
runs-on: ubuntu-latest
needs: test
steps:
- name: π₯ Checkout code
uses: actions/checkout@v4
- name: π§ Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: π¦ Install dependencies
run: npm ci
- name: π Run security audit
run: npm audit --audit-level moderate
- name: π Scan for secrets
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: main
head: HEAD
build:
name: Build & Package
runs-on: ubuntu-latest
needs: [test, security]
if: github.ref == 'refs/heads/main'
steps:
- name: π₯ Checkout code
uses: actions/checkout@v4
- name: π§ Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
registry-url: 'https://npm.pkg.github.com'
- name: π¦ Install dependencies
run: npm ci
- name: π Create package info
run: |
echo "π¦ Package: $(npm list --depth=0 | head -1)"
echo "π Version: $(node -p require('./package.json').version)"
echo "π Dependencies: $(npm list --production --parseable | wc -l)"
- name: π¨ Build package
run: |
npm pack
echo "π¦ Package created: $(ls *.tgz)"
- name: π€ Upload package artifact
uses: actions/upload-artifact@v3
with:
name: npm-package
path: "*.tgz"
publish:
name: Publish Package
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main' && contains(github.event.head_commit.message, 'release:')
steps:
- name: π₯ Checkout code
uses: actions/checkout@v4
- name: π§ Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
registry-url: 'https://npm.pkg.github.com'
- name: π¦ Install dependencies
run: npm ci
- name: π Publish to GitHub Packages
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
docker:
name: Docker Build
runs-on: ubuntu-latest
needs: [test, security]
if: github.ref == 'refs/heads/main'
steps:
- name: π₯ Checkout code
uses: actions/checkout@v4
- name: π³ Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: π Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: π Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: π¨ Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
integration:
name: Integration Test
runs-on: ubuntu-latest
needs: test
steps:
- name: π₯ Checkout code
uses: actions/checkout@v4
- name: π§ Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: π¦ Install dependencies
run: npm ci
- name: π§ Install globally
run: npm link
- name: π Start server
run: |
nohup mcp-learn api &
sleep 3
- name: π§ͺ Run integration tests
run: |
# Test health endpoint
curl -f http://localhost:8765/health || exit 1
# Test status endpoint
curl -f http://localhost:8765/status || exit 1
# Test analysis endpoint
curl -f -X POST http://localhost:8765/analyze \
-H "Content-Type: application/json" \
-d '{"interaction":{"type":"test","input":"ci-test","output":"success","success":true}}' || exit 1
# Test insights endpoint
curl -f http://localhost:8765/insights || exit 1
- name: π§ͺ Test CLI commands
run: |
mcp-learn health || echo "Health check completed"
mcp-learn status || echo "Status check completed"
- name: π§ͺ Run custom integration test
run: |
chmod +x test-simple-integration.sh
./test-simple-integration.sh
notify:
name: Notify
runs-on: ubuntu-latest
needs: [test, security, build]
if: always()
steps:
- name: π Report Status
run: |
if [[ "${{ needs.test.result }}" == "success" ]]; then
echo "β
Tests passed"
else
echo "β Tests failed"
fi
if [[ "${{ needs.security.result }}" == "success" ]]; then
echo "β
Security audit passed"
else
echo "β οΈ Security issues detected"
fi
if [[ "${{ needs.build.result }}" == "success" ]]; then
echo "β
Build successful"
else
echo "β Build failed"
fi