1+ name : CI/CD
2+
3+ on :
4+ push :
5+ branches : [ main, copilot/**, claude/** ]
6+ pull_request :
7+ branches : [ main ]
8+ workflow_dispatch :
9+
10+ permissions :
11+ contents : write
12+ id-token : write
13+ pull-requests : write
14+ security-events : write
15+
16+ concurrency :
17+ group : ${{ github.workflow }}-${{ github.ref }}
18+ cancel-in-progress : true
19+
20+ jobs :
21+ test :
22+ runs-on : ubuntu-latest
23+ steps :
24+ - uses : actions/checkout@v4
25+ - name : Set up Python
26+ uses : actions/setup-python@v5
27+ with :
28+ python-version : ' 3.11'
29+ - name : Install uv
30+ uses : astral-sh/setup-uv@v3
31+ with :
32+ version : " latest"
33+ - name : Install dependencies
34+ run : uv sync --extra dev
35+ - name : Lint with ruff
36+ run : uv run ruff check .
37+ - name : Type check with pyright
38+ run : uv run pyright src/
39+ - name : Run tests with coverage
40+ run : uv run pytest --cov=mcp_devbench --cov-report=xml --cov-report=term-missing
41+ - name : Upload coverage to Codecov
42+ uses : codecov/codecov-action@v4
43+ with :
44+ file : ./coverage.xml
45+ fail_ci_if_error : false
46+ token : ${{ secrets.CODECOV_TOKEN }}
47+
48+ test-e2e :
49+ runs-on : ubuntu-latest
50+ timeout-minutes : 30
51+ steps :
52+ - uses : actions/checkout@v4
53+ - name : Set up Python
54+ uses : actions/setup-python@v5
55+ with :
56+ python-version : " 3.11"
57+ - name : Install uv
58+ uses : astral-sh/setup-uv@v3
59+ with :
60+ version : " latest"
61+ - name : Install dependencies
62+ run : uv sync --extra dev
63+ - name : Pull test images
64+ run : |
65+ docker pull alpine:latest
66+ docker pull python:3.11-slim
67+ - name : Run E2E tests
68+ run : uv run pytest tests/e2e/ -v --tb=short --maxfail=5
69+ env :
70+ MCP_LOG_LEVEL : DEBUG
71+ - name : Cleanup containers
72+ if : always()
73+ run : |
74+ docker ps -aq --filter "name=e2e-" | xargs -r docker rm -f
75+ docker ps -aq --filter "name=alias-" | xargs -r docker rm -f
76+ docker ps -aq --filter "name=persistent-" | xargs -r docker rm -f
77+ - name : Upload test results
78+ if : always()
79+ uses : actions/upload-artifact@v4
80+ with :
81+ name : e2e-test-results
82+ path : |
83+ pytest-*.xml
84+ htmlcov/
85+ retention-days : 7
86+
87+ security :
88+ runs-on : ubuntu-latest
89+ steps :
90+ - uses : actions/checkout@v4
91+ - name : Set up Python
92+ uses : actions/setup-python@v5
93+ with :
94+ python-version : ' 3.11'
95+ - name : Install uv
96+ uses : astral-sh/setup-uv@v3
97+ with :
98+ version : " latest"
99+ - name : Install dependencies
100+ run : uv sync
101+ - name : Run Trivy filesystem scan
102+ uses : aquasecurity/trivy-action@master
103+ with :
104+ scan-type : ' fs'
105+ scan-ref : ' .'
106+ severity : ' HIGH,CRITICAL'
107+ format : ' sarif'
108+ output : ' trivy-results.sarif'
109+ - name : Upload Trivy results to GitHub Security
110+ uses : github/codeql-action/upload-sarif@v3
111+ if : always()
112+ with :
113+ sarif_file : ' trivy-results.sarif'
114+ category : ' trivy-fs'
115+ - name : Build container image
116+ run : docker build -t mcp-devbench:test .
117+ - name : Run Trivy container scan
118+ uses : aquasecurity/trivy-action@master
119+ with :
120+ image-ref : ' mcp-devbench:test'
121+ format : ' sarif'
122+ output : ' trivy-container.sarif'
123+ severity : ' HIGH,CRITICAL'
124+ - name : Upload container scan results to GitHub Security
125+ uses : github/codeql-action/upload-sarif@v3
126+ if : always()
127+ with :
128+ sarif_file : ' trivy-container.sarif'
129+ category : ' trivy-container'
130+
131+ docs :
132+ needs : test
133+ runs-on : ubuntu-latest
134+ steps :
135+ - uses : actions/checkout@v4
136+ - name : Set up Python
137+ uses : actions/setup-python@v5
138+ with :
139+ python-version : ' 3.11'
140+ - name : Install uv
141+ run : pip install uv
142+ - name : Install dependencies
143+ run : uv sync --extra docs
144+ - name : Build documentation
145+ run : uv run mkdocs build
146+ - name : Deploy to GitHub Pages
147+ if : github.ref == 'refs/heads/main' && github.event_name == 'push'
148+ uses : peaceiris/actions-gh-pages@v3
149+ with :
150+ github_token : ${{ secrets.GITHUB_TOKEN }}
151+ publish_dir : ./site
152+
153+ release :
154+ needs : [test, test-e2e, security]
155+ if : github.ref == 'refs/heads/main' && github.event_name == 'push'
156+ runs-on : ubuntu-latest
157+ steps :
158+ - name : Checkout (using admin PAT)
159+ uses : actions/checkout@v4
160+ with :
161+ fetch-depth : 0
162+ token : ${{ secrets.RELEASE_PAT }}
163+ - name : Configure Git author (for release commit)
164+ run : |
165+ git config user.name "github-actions[bot]"
166+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
167+ - name : Set up Python
168+ uses : actions/setup-python@v5
169+ with :
170+ python-version : " 3.11"
171+ - name : Install uv
172+ uses : astral-sh/setup-uv@v3
173+ with :
174+ version : " latest"
175+ - name : Install project (dev)
176+ run : uv sync --extra dev
177+ - name : Install python-semantic-release (CLI)
178+ run : uv pip install --system --upgrade python-semantic-release
179+ - name : Semantic Release (publish)
180+ env :
181+ GH_TOKEN : ${{ secrets.RELEASE_PAT }}
182+ PYPI_TOKEN : ${{ secrets.PYPI_API_TOKEN }}
183+ run : |
184+ uv run -- semantic-release -v version
185+ uv run -- semantic-release -v publish
186+
0 commit comments