Skip to content

Commit b9d92b2

Browse files
committed
add ci and dockerfile
1 parent c60bf77 commit b9d92b2

File tree

14 files changed

+1236
-18
lines changed

14 files changed

+1236
-18
lines changed

.dockerignore

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
build/
8+
develop-eggs/
9+
dist/
10+
downloads/
11+
eggs/
12+
.eggs/
13+
lib/
14+
lib64/
15+
parts/
16+
sdist/
17+
var/
18+
wheels/
19+
*.egg-info/
20+
.installed.cfg
21+
*.egg
22+
23+
# Virtual environments
24+
venv/
25+
env/
26+
ENV/
27+
28+
# Testing
29+
.pytest_cache/
30+
.coverage
31+
htmlcov/
32+
.tox/
33+
34+
# IDE
35+
.vscode/
36+
.idea/
37+
*.swp
38+
*.swo
39+
*~
40+
41+
# Git
42+
.git/
43+
.gitignore
44+
45+
# Documentation
46+
docs/
47+
48+
# CI/CD
49+
.github/
50+
.flake8
51+
52+
# Local development
53+
.env
54+
*.log
55+
temp/
56+
tmp/
57+
58+
# OS
59+
.DS_Store
60+
Thumbs.db

.github/workflows/ci.yml

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
name: CI/CD Pipeline
2+
3+
on:
4+
push:
5+
branches: [ master, release ]
6+
pull_request:
7+
branches: [ master ]
8+
release:
9+
types: [ published ]
10+
11+
env:
12+
REGISTRY: ghcr.io
13+
IMAGE_NAME: ${{ github.repository }}
14+
15+
jobs:
16+
lint:
17+
name: Code Style & Linting
18+
runs-on: ubuntu-latest
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v4
22+
23+
- name: Set up Python
24+
uses: actions/setup-python@v4
25+
with:
26+
python-version: '3.12'
27+
28+
- name: Create virtual environment
29+
run: python -m venv venv
30+
31+
- name: Install dependencies
32+
run: |
33+
source venv/bin/activate
34+
pip install --upgrade pip
35+
pip install black flake8
36+
pip install -e .
37+
38+
- name: Run Black
39+
run: |
40+
source venv/bin/activate
41+
black --check --diff src/ tests/
42+
43+
- name: Run Flake8
44+
run: |
45+
source venv/bin/activate
46+
flake8 src/ tests/
47+
48+
test:
49+
name: Run Tests
50+
runs-on: ubuntu-latest
51+
needs: lint
52+
strategy:
53+
matrix:
54+
python-version: ['3.10', '3.11', '3.12']
55+
56+
steps:
57+
- name: Checkout code
58+
uses: actions/checkout@v4
59+
60+
- name: Set up Python ${{ matrix.python-version }}
61+
uses: actions/setup-python@v4
62+
with:
63+
python-version: ${{ matrix.python-version }}
64+
65+
- name: Create virtual environment
66+
run: python -m venv venv
67+
68+
- name: Install dependencies
69+
run: |
70+
source venv/bin/activate
71+
pip install --upgrade pip
72+
pip install -e ".[test]"
73+
74+
- name: Run unit tests
75+
run: |
76+
source venv/bin/activate
77+
pytest -m unit -v
78+
79+
- name: Run client tests
80+
run: |
81+
source venv/bin/activate
82+
pytest tests/test_client_no_server.py -v
83+
84+
- name: Run integration tests
85+
run: |
86+
source venv/bin/activate
87+
pytest -m integration -v
88+
89+
docker:
90+
name: Build and Push Docker Image
91+
runs-on: ubuntu-latest
92+
needs: [lint, test]
93+
if: github.event_name == 'push' && github.ref == 'refs/heads/master' || github.event_name == 'release'
94+
permissions:
95+
contents: read
96+
packages: write
97+
98+
steps:
99+
- name: Checkout code
100+
uses: actions/checkout@v4
101+
102+
- name: Set up Docker Buildx
103+
uses: docker/setup-buildx-action@v3
104+
105+
- name: Log in to Container Registry
106+
uses: docker/login-action@v3
107+
with:
108+
registry: ${{ env.REGISTRY }}
109+
username: ${{ github.actor }}
110+
password: ${{ secrets.GITHUB_TOKEN }}
111+
112+
- name: Extract metadata
113+
id: meta
114+
uses: docker/metadata-action@v5
115+
with:
116+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
117+
tags: |
118+
type=ref,event=branch
119+
type=ref,event=pr
120+
type=semver,pattern={{version}}
121+
type=semver,pattern={{major}}.{{minor}}
122+
type=semver,pattern={{major}}
123+
type=raw,value=latest,enable={{is_default_branch}}
124+
125+
- name: Build and push Docker image
126+
uses: docker/build-push-action@v5
127+
with:
128+
context: .
129+
push: true
130+
tags: ${{ steps.meta.outputs.tags }}
131+
labels: ${{ steps.meta.outputs.labels }}
132+
cache-from: type=gha
133+
cache-to: type=gha,mode=max
134+
135+
security:
136+
name: Security Scan
137+
runs-on: ubuntu-latest
138+
needs: docker
139+
if: github.event_name == 'push' && github.ref == 'refs/heads/master' || github.event_name == 'release'
140+
permissions:
141+
contents: read
142+
packages: read
143+
security-events: write
144+
145+
steps:
146+
- name: Run Trivy vulnerability scanner
147+
uses: aquasecurity/trivy-action@master
148+
with:
149+
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
150+
format: 'sarif'
151+
output: 'trivy-results.sarif'
152+
153+
- name: Upload Trivy scan results to GitHub Security tab
154+
uses: github/codeql-action/upload-sarif@v2
155+
if: always()
156+
with:
157+
sarif_file: 'trivy-results.sarif'

Dockerfile

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
LABEL org.opencontainers.image.title="VTK MCP Server"
2+
LABEL org.opencontainers.image.description="Model Context Protocol server for VTK class documentation"
3+
LABEL org.opencontainers.image.source="https://github.com/kitware/vtk-mcp"
4+
LABEL org.opencontainers.image.licenses="MIT"
5+
LABEL org.opencontainers.image.documentation="https://github.com/kitware/vtk-mcp/blob/main/README.md"
6+
7+
FROM python:3.12-slim
8+
9+
WORKDIR /app
10+
11+
ENV PIP_DISABLE_PIP_VERSION_CHECK=1 \
12+
PIP_NO_CACHE_DIR=1 \
13+
PYTHONDONTWRITEBYTECODE=1 \
14+
PYTHONUNBUFFERED=1
15+
16+
# Install system dependencies for VTK
17+
RUN apt update && apt install -y \
18+
libgl1-mesa-glx \
19+
libglib2.0-0 \
20+
libgomp1 \
21+
libsm6 \
22+
libxext6 \
23+
libxrender-dev
24+
25+
COPY . .
26+
RUN pip install --upgrade pip && \
27+
pip install --verbose .
28+
29+
# Create non-root user for security
30+
#RUN useradd --create-home --shell /bin/bash --uid 1000 vtk-user && \
31+
# chown -R vtk-user:vtk-user /app
32+
#USER vtk-user
33+
34+
EXPOSE 8000
35+
36+
CMD ["vtk-mcp-server", "--transport", "http", "--host", "0.0.0.0", "--port", "8000"]

README.md

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ vtk-mcp-server --transport http --host localhost --port 8000
2828
### Client
2929

3030
```bash
31-
# Get detailed C++ class information
31+
# Get detailed C++ class information
3232
vtk-mcp-client info-cpp vtkActor
3333
vtk-mcp-client info-cpp vtkPolyData
3434

@@ -54,6 +54,46 @@ The server provides three MCP tools:
5454
- `get_vtk_class_info_python(class_name)` - Get Python API documentation using help() function
5555
- `search_vtk_classes(search_term)` - Search for VTK classes containing a term
5656

57+
## Docker
58+
59+
### Using Pre-built Image
60+
61+
```bash
62+
# Run with Docker/Podman
63+
docker run -p 8000:8000 ghcr.io/kitware/vtk-mcp:latest
64+
65+
# Or with Podman
66+
podman run -p 8000:8000 ghcr.io/kitware/vtk-mcp:latest
67+
68+
# Access server at http://localhost:8000/mcp/
69+
```
70+
71+
### Building Locally
72+
73+
```bash
74+
# Build image
75+
docker build -t vtk-mcp-server .
76+
77+
# Or with Podman
78+
podman build -t vtk-mcp-server .
79+
80+
# Run container
81+
docker run -p 8000:8000 vtk-mcp-server
82+
```
83+
84+
### Docker Compose
85+
86+
```bash
87+
# Start services
88+
docker-compose up -d
89+
90+
# View logs
91+
docker-compose logs -f
92+
93+
# Stop services
94+
docker-compose down
95+
```
96+
5797
## Development
5898

5999
```bash
@@ -72,3 +112,44 @@ flake8 src/ --max-line-length=88
72112
vtk-mcp-server --transport http &
73113
vtk-mcp-client info-cpp vtkActor
74114
```
115+
116+
## Testing
117+
118+
Install test dependencies:
119+
120+
```bash
121+
pip install -e ".[test]"
122+
```
123+
124+
Run tests:
125+
126+
```bash
127+
# Run all tests
128+
pytest
129+
130+
# Run specific test types using markers
131+
pytest -m unit # Unit tests only
132+
pytest -m integration # Integration tests only
133+
pytest -m http # HTTP transport tests
134+
pytest -m stdio # Stdio transport tests
135+
136+
# Run specific test files
137+
pytest tests/test_server_functions.py # Server unit tests
138+
pytest tests/test_client_no_server.py # Client error handling
139+
pytest tests/test_http_integration.py # HTTP integration
140+
pytest tests/test_stdio_integration.py # Stdio integration
141+
142+
# Useful pytest options
143+
pytest -v # Verbose output
144+
pytest -x # Stop on first failure
145+
pytest --tb=short # Short traceback format
146+
pytest -k "test_name" # Run tests matching pattern
147+
```
148+
149+
### Test Structure
150+
151+
- `tests/test_server_functions.py` - Unit tests for MCP tool functions (no server required)
152+
- `tests/test_client_no_server.py` - Client error handling when server unavailable
153+
- `tests/test_http_integration.py` - Full integration tests with HTTP transport
154+
- `tests/test_stdio_integration.py` - Full integration tests with stdio transport
155+
- `tests/conftest.py` - Shared test fixtures and configuration

0 commit comments

Comments
 (0)