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
0 commit comments