Skip to content

Commit f86c9a7

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

File tree

15 files changed

+1253
-18
lines changed

15 files changed

+1253
-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

.flake8

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[flake8]
2+
max-line-length = 88
3+
extend-ignore = E203,W503
4+
exclude =
5+
.git,
6+
__pycache__,
7+
build,
8+
dist,
9+
*.egg-info,
10+
venv,
11+
.venv

.github/workflows/ci.yml

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
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@v5
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
47+
48+
actionlint:
49+
runs-on: ubuntu-latest
50+
steps:
51+
- uses: actions/checkout@v4
52+
53+
- name: Install actionlint
54+
run: |
55+
# Download and install actionlint
56+
bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
57+
echo "${PWD}" >> "$GITHUB_PATH"
58+
59+
- name: Run actionlint
60+
run: actionlint
61+
62+
test:
63+
name: Run Tests
64+
runs-on: ubuntu-latest
65+
needs: [lint, actionlint]
66+
strategy:
67+
matrix:
68+
python-version: ['3.10', '3.11', '3.12']
69+
70+
steps:
71+
- name: Checkout code
72+
uses: actions/checkout@v4
73+
74+
- name: Set up Python ${{ matrix.python-version }}
75+
uses: actions/setup-python@v5
76+
with:
77+
python-version: ${{ matrix.python-version }}
78+
79+
- name: Create virtual environment
80+
run: python -m venv venv
81+
82+
- name: Install dependencies
83+
run: |
84+
source venv/bin/activate
85+
pip install --upgrade pip
86+
pip install -e ".[test]"
87+
88+
- name: Run unit tests
89+
run: |
90+
source venv/bin/activate
91+
pytest -m unit -v
92+
93+
- name: Run client tests
94+
run: |
95+
source venv/bin/activate
96+
pytest tests/test_client_no_server.py -v
97+
98+
- name: Run integration tests
99+
run: |
100+
source venv/bin/activate
101+
pytest -m integration -v
102+
103+
docker:
104+
name: Build and Push Docker Image
105+
runs-on: ubuntu-latest
106+
needs: [lint, actionlint, test]
107+
if: github.event_name == 'push' && github.ref == 'refs/heads/master' || github.event_name == 'release'
108+
permissions:
109+
contents: read
110+
packages: write
111+
steps:
112+
- name: Checkout code
113+
uses: actions/checkout@v4
114+
115+
- name: Install Podman
116+
run: |
117+
sudo apt update
118+
sudo apt install -y podman
119+
120+
- name: Log in to GitHub Container Registry
121+
run: |
122+
echo "${{ secrets.GITHUB_TOKEN }}" | podman login ghcr.io -u ${{ github.repository_owner }} --password-stdin
123+
124+
- name: Get short SHA
125+
id: slug
126+
run: echo "SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7)" >> "$GITHUB_OUTPUT"
127+
128+
- name: Build and push container image
129+
run: |
130+
# Build the image
131+
podman build -t "ghcr.io/${{ github.repository }}/vtk-mcp:latest" \
132+
-t "ghcr.io/${{ github.repository }}/vtk-mcp:${{ github.sha }}" \
133+
-t "ghcr.io/${{ github.repository }}/vtk-mcp:${{ steps.slug.outputs.SHORT_SHA }}" \
134+
.
135+
136+
# Push all tags
137+
podman push "ghcr.io/${{ github.repository }}/vtk-mcp:latest"
138+
podman push "ghcr.io/${{ github.repository }}/vtk-mcp:${{ github.sha }}"
139+
podman push "ghcr.io/${{ github.repository }}/vtk-mcp:${{ steps.slug.outputs.SHORT_SHA }}"
140+
141+
security:
142+
name: Security Scan
143+
runs-on: ubuntu-latest
144+
needs: docker
145+
if: github.event_name == 'push' && github.ref == 'refs/heads/master' || github.event_name == 'release'
146+
permissions:
147+
contents: read
148+
packages: read
149+
security-events: write
150+
151+
steps:
152+
- name: Run Trivy vulnerability scanner
153+
uses: aquasecurity/trivy-action@master
154+
with:
155+
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
156+
format: 'sarif'
157+
output: 'trivy-results.sarif'
158+
159+
- name: Upload Trivy scan results to GitHub Security tab
160+
uses: github/codeql-action/upload-sarif@v3
161+
if: always()
162+
with:
163+
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)