name: Build and Deploy MCP Server
on:
push:
branches: [ main, develop ]
tags: [ 'v*' ]
pull_request:
branches: [ main ]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements-http.txt
pip install pytest pytest-asyncio
- name: Run tests
run: |
# Add your tests here
python -m pytest tests/ -v || echo "No tests found, skipping"
- name: Lint code
run: |
pip install flake8
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
build:
needs: test
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
outputs:
image-tag: ${{ steps.meta.outputs.tags }}
image-digest: ${{ steps.build.outputs.digest }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image
id: build
uses: docker/build-push-action@v5
with:
context: .
file: ./docker/Dockerfile.prod
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
image: ${{ steps.meta.outputs.tags }}
deploy-staging:
if: github.ref == 'refs/heads/develop'
needs: build
runs-on: ubuntu-latest
environment: staging
steps:
- name: Deploy to staging
run: |
echo "🚀 Deploying to staging environment"
echo "Image: ${{ needs.build.outputs.image-tag }}"
# Add staging deployment logic here
deploy-production:
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')
needs: build
runs-on: ubuntu-latest
environment: production
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Deploy to Proxmox
env:
PROXMOX_HOST: ${{ secrets.PROXMOX_HOST }}
PROXMOX_USER: ${{ secrets.PROXMOX_USER }}
PROXMOX_SSH_KEY: ${{ secrets.PROXMOX_SSH_KEY }}
IMAGE_TAG: ${{ needs.build.outputs.image-tag }}
run: |
# Setup SSH key
mkdir -p ~/.ssh
echo "$PROXMOX_SSH_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H $PROXMOX_HOST >> ~/.ssh/known_hosts
# Deploy using the deployment script
chmod +x deploy/deploy-production.sh
./deploy/deploy-production.sh
- name: Verify deployment
env:
PROXMOX_HOST: ${{ secrets.PROXMOX_HOST }}
run: |
# Wait for deployment to be ready
sleep 30
# Test health endpoint
curl -f http://$PROXMOX_HOST/health || exit 1
# Test MCP endpoint
curl -f http://$PROXMOX_HOST/api/mcp || exit 1
echo "✅ Deployment verified successfully"
security-scan:
needs: build
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ needs.build.outputs.image-tag }}
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
if: always()
with:
sarif_file: 'trivy-results.sarif'