Skip to content

Commit 6bc580d

Browse files
Merge remote-tracking branch 'origin/main' into feature/mcp-multi-client-testing
2 parents 3835568 + 4c7b6b1 commit 6bc580d

52 files changed

Lines changed: 5913 additions & 1860 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/code-quality.yml

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
name: Code Quality
2+
3+
on:
4+
push:
5+
branches: [ main, develop, feature/* ]
6+
pull_request:
7+
branches: [ main, develop ]
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
pre-commit:
15+
name: Pre-commit hooks
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Set up Python
21+
uses: actions/setup-python@v4
22+
with:
23+
python-version: '3.11'
24+
25+
- name: Install dependencies
26+
run: |
27+
python -m pip install --upgrade pip
28+
pip install pre-commit
29+
30+
- name: Run pre-commit
31+
run: pre-commit run --all-files
32+
33+
lint-and-format:
34+
name: Linting and Formatting
35+
runs-on: ubuntu-latest
36+
strategy:
37+
matrix:
38+
python-version: ['3.10', '3.11', '3.12']
39+
40+
steps:
41+
- uses: actions/checkout@v4
42+
43+
- name: Set up Python ${{ matrix.python-version }}
44+
uses: actions/setup-python@v4
45+
with:
46+
python-version: ${{ matrix.python-version }}
47+
48+
- name: Install dependencies
49+
run: |
50+
python -m pip install --upgrade pip
51+
pip install -e . || echo "Package install failed, installing dev deps directly"
52+
pip install black ruff isort
53+
54+
- name: Check code formatting with Black
55+
run: black --check --diff .
56+
57+
- name: Lint with Ruff
58+
run: ruff check .
59+
60+
- name: Check import sorting with isort
61+
run: isort --check-only --diff .
62+
63+
type-check:
64+
name: Type Checking
65+
runs-on: ubuntu-latest
66+
steps:
67+
- uses: actions/checkout@v4
68+
69+
- name: Set up Python
70+
uses: actions/setup-python@v4
71+
with:
72+
python-version: '3.11'
73+
74+
- name: Install dependencies
75+
run: |
76+
python -m pip install --upgrade pip
77+
pip install -e . || echo "Package install failed, installing deps directly"
78+
pip install mypy types-requests
79+
80+
- name: Type check with MyPy
81+
run: mypy src/
82+
83+
security:
84+
name: Security Analysis
85+
runs-on: ubuntu-latest
86+
steps:
87+
- uses: actions/checkout@v4
88+
89+
- name: Set up Python
90+
uses: actions/setup-python@v4
91+
with:
92+
python-version: '3.11'
93+
94+
- name: Install dependencies
95+
run: |
96+
python -m pip install --upgrade pip
97+
pip install bandit[toml] safety
98+
99+
- name: Run Bandit security linter
100+
run: bandit -r src/ -f json -o bandit-report.json || true
101+
102+
- name: Upload Bandit report
103+
uses: actions/upload-artifact@v4
104+
if: always()
105+
with:
106+
name: bandit-report
107+
path: bandit-report.json
108+
109+
- name: Check dependencies for security vulnerabilities
110+
run: safety check --json --output safety-report.json || true
111+
112+
- name: Upload Safety report
113+
uses: actions/upload-artifact@v4
114+
if: always()
115+
with:
116+
name: safety-report
117+
path: safety-report.json
118+
119+
complexity:
120+
name: Code Complexity Analysis
121+
runs-on: ubuntu-latest
122+
steps:
123+
- uses: actions/checkout@v4
124+
125+
- name: Set up Python
126+
uses: actions/setup-python@v4
127+
with:
128+
python-version: '3.11'
129+
130+
- name: Install dependencies
131+
run: |
132+
python -m pip install --upgrade pip
133+
pip install radon xenon
134+
135+
- name: Run complexity analysis
136+
run: |
137+
echo "## Cyclomatic Complexity" >> complexity-report.md
138+
radon cc src/ -s >> complexity-report.md
139+
echo "" >> complexity-report.md
140+
echo "## Maintainability Index" >> complexity-report.md
141+
radon mi src/ -s >> complexity-report.md
142+
echo "" >> complexity-report.md
143+
echo "## Raw Metrics" >> complexity-report.md
144+
radon raw src/ -s >> complexity-report.md
145+
146+
- name: Check complexity thresholds
147+
run: xenon --max-absolute B --max-modules B --max-average A src/
148+
149+
- name: Upload complexity report
150+
uses: actions/upload-artifact@v4
151+
if: always()
152+
with:
153+
name: complexity-report
154+
path: complexity-report.md
155+
156+
test-coverage:
157+
name: Test Coverage
158+
runs-on: ubuntu-latest
159+
steps:
160+
- uses: actions/checkout@v4
161+
162+
- name: Set up Python
163+
uses: actions/setup-python@v4
164+
with:
165+
python-version: '3.11'
166+
167+
- name: Install dependencies
168+
run: |
169+
python -m pip install --upgrade pip
170+
pip install -e . || echo "Package install failed, installing deps directly"
171+
pip install pytest pytest-cov pytest-asyncio pytest-mock coverage
172+
173+
- name: Run tests with coverage
174+
run: |
175+
pytest --cov=src/mujoco_mcp --cov-report=xml --cov-report=html --cov-report=term-missing
176+
177+
- name: Upload coverage to Codecov
178+
uses: codecov/codecov-action@v3
179+
with:
180+
file: ./coverage.xml
181+
flags: unittests
182+
name: codecov-umbrella
183+
184+
- name: Upload coverage report
185+
uses: actions/upload-artifact@v4
186+
if: always()
187+
with:
188+
name: coverage-report
189+
path: htmlcov/
190+
191+
quality-gate:
192+
name: Quality Gate
193+
runs-on: ubuntu-latest
194+
needs: [pre-commit, lint-and-format, type-check, security, complexity, test-coverage]
195+
if: always()
196+
steps:
197+
- name: Check all jobs status
198+
run: |
199+
if [[ "${{ needs.pre-commit.result }}" == "failure" || \
200+
"${{ needs.lint-and-format.result }}" == "failure" || \
201+
"${{ needs.type-check.result }}" == "failure" || \
202+
"${{ needs.security.result }}" == "failure" || \
203+
"${{ needs.complexity.result }}" == "failure" || \
204+
"${{ needs.test-coverage.result }}" == "failure" ]]; then
205+
echo "❌ Quality gate failed - some checks did not pass"
206+
exit 1
207+
else
208+
echo "✅ Quality gate passed - all checks successful"
209+
fi

.github/workflows/performance.yml

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -42,30 +42,14 @@ jobs:
4242
run: |
4343
python -c "
4444
import json
45-
import os
45+
with open('performance_benchmark_report.json') as f:
46+
results = json.load(f)
4647
47-
if os.path.exists('performance_benchmark_report.json'):
48-
with open('performance_benchmark_report.json') as f:
49-
results = json.load(f)
50-
51-
# Check overall success rate
52-
summary = results.get('summary', {})
53-
success_rate = summary.get('success_rate', 0.0)
54-
total_time = summary.get('total_execution_time', 0.0)
55-
56-
print(f'📊 Benchmark Results:')
57-
print(f' Success Rate: {success_rate:.1%}')
58-
print(f' Total Time: {total_time:.2f}s')
59-
60-
# Performance thresholds
61-
if success_rate < 0.8: # 80% success rate
62-
print(f'❌ Performance regression: success rate {success_rate:.1%} < 80%')
63-
exit(1)
64-
elif total_time > 60.0: # 60 seconds max
65-
print(f'❌ Performance regression: total time {total_time:.2f}s > 60s')
66-
exit(1)
67-
else:
68-
print(f'✅ Performance targets met')
48+
# Check if performance targets are met
49+
startup_time = results.get('startup_time', {}).get('mean', 0)
50+
if startup_time > 5.0:
51+
print(f'❌ Performance regression: startup time {startup_time:.2f}s > 5.0s')
52+
exit(1)
6953
else:
70-
print('⚠️ No benchmark results found - skipping regression check')
54+
print(f'✅ Performance OK: startup time {startup_time:.2f}s')
7155
"

.pre-commit-config.yaml

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Pre-commit hooks for code quality enforcement
2+
repos:
3+
# Pre-commit hooks
4+
- repo: https://github.com/pre-commit/pre-commit-hooks
5+
rev: v4.5.0
6+
hooks:
7+
- id: trailing-whitespace
8+
- id: end-of-file-fixer
9+
- id: check-yaml
10+
- id: check-toml
11+
- id: check-json
12+
- id: check-merge-conflict
13+
- id: check-added-large-files
14+
- id: debug-statements
15+
- id: check-executables-have-shebangs
16+
- id: check-shebang-scripts-are-executable
17+
18+
# Black formatter
19+
- repo: https://github.com/psf/black
20+
rev: 23.12.1
21+
hooks:
22+
- id: black
23+
language_version: python3
24+
args: [--line-length=100]
25+
26+
# Ruff linter and formatter
27+
- repo: https://github.com/astral-sh/ruff-pre-commit
28+
rev: v0.1.9
29+
hooks:
30+
- id: ruff
31+
args: [--fix, --exit-non-zero-on-fix]
32+
- id: ruff-format
33+
34+
# MyPy type checking
35+
- repo: https://github.com/pre-commit/mirrors-mypy
36+
rev: v1.8.0
37+
hooks:
38+
- id: mypy
39+
additional_dependencies: [types-requests]
40+
args: [--strict, --ignore-missing-imports]
41+
42+
# Security checks with bandit
43+
- repo: https://github.com/PyCQA/bandit
44+
rev: 1.7.5
45+
hooks:
46+
- id: bandit
47+
args: [-c, pyproject.toml]
48+
49+
# Import sorting with isort
50+
- repo: https://github.com/pycqa/isort
51+
rev: 5.13.2
52+
hooks:
53+
- id: isort
54+
args: [--profile, black, --line-length, "100"]
55+
56+
# Check for common Python mistakes
57+
- repo: https://github.com/PyCQA/flake8
58+
rev: 6.1.0
59+
hooks:
60+
- id: flake8
61+
additional_dependencies: [flake8-docstrings, flake8-typing-imports]
62+
args: [--max-line-length=100, --extend-ignore=E203,W503]
63+
64+
# Security vulnerabilities in dependencies
65+
- repo: https://github.com/Lucas-C/pre-commit-hooks-safety
66+
rev: v1.3.2
67+
hooks:
68+
- id: python-safety-dependencies-check
69+
70+
# Spell checking
71+
- repo: https://github.com/codespell-project/codespell
72+
rev: v2.2.6
73+
hooks:
74+
- id: codespell
75+
args: [--write-changes]
76+
exclude: ^(\.git/.*|.*\.lock|.*\.log)$
77+
78+
# Configuration
79+
ci:
80+
autofix_commit_msg: |
81+
[pre-commit.ci] auto fixes from pre-commit.com hooks
82+
83+
for more information, see https://pre-commit.ci
84+
autofix_prs: true
85+
autoupdate_branch: ''
86+
autoupdate_commit_msg: '[pre-commit.ci] pre-commit autoupdate'
87+
autoupdate_schedule: weekly
88+
skip: []
89+
submodules: false

0 commit comments

Comments
 (0)