Skip to content

Commit ed3fa15

Browse files
committed
feat: 添加完整的测试套件和 CI/CD 工作流
- 添加 pytest 测试套件(单元测试 + 集成测试) - 添加 GitHub Actions CI/CD 工作流 - CI: 多平台多版本测试 - 代码质量检查(ruff + basedpyright) - 安全扫描(pip-audit, bandit, safety) - 自动发布到 PyPI - 更新 pyproject.toml 配置 - 添加开发依赖 - 配置 pytest、ruff、basedpyright - 配置覆盖率报告 - 添加开发文档 - DEVELOPMENT.md: 开发指南 - RELEASE.md: 发布指南 - 添加测试运行脚本 run_tests.py - 更新 README 添加开发和 CI/CD 说明 - 更新 .gitignore 添加测试和覆盖率文件排除
1 parent ea54832 commit ed3fa15

12 files changed

Lines changed: 923 additions & 7 deletions

File tree

.github/workflows/ci.yml

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main, master ]
6+
pull_request:
7+
branches: [ main, master ]
8+
9+
jobs:
10+
test:
11+
name: Test Python ${{ matrix.python-version }} on ${{ matrix.os }}
12+
runs-on: ${{ matrix.os }}
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
os: [ubuntu-latest, windows-latest, macos-latest]
17+
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
18+
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v4
22+
23+
- name: Set up Python ${{ matrix.python-version }}
24+
uses: actions/setup-python@v5
25+
with:
26+
python-version: ${{ matrix.python-version }}
27+
28+
- name: Install uv
29+
uses: astral-sh/setup-uv@v3
30+
with:
31+
version: "latest"
32+
33+
- name: Install dependencies
34+
run: |
35+
uv venv
36+
uv pip install -e .
37+
uv pip install pytest pytest-asyncio pytest-cov reportlab
38+
39+
- name: Run tests with coverage
40+
run: |
41+
uv run pytest tests/ -v --cov=mcp_documents_reader --cov-report=xml --cov-report=term-missing
42+
43+
- name: Upload coverage to Codecov
44+
uses: codecov/codecov-action@v4
45+
with:
46+
file: ./coverage.xml
47+
flags: unittests
48+
env_vars: OS,PYTHON
49+
name: codecov-umbrella
50+
fail_ci_if_error: false
51+
52+
lint:
53+
name: Code Quality Checks
54+
runs-on: ubuntu-latest
55+
56+
steps:
57+
- name: Checkout code
58+
uses: actions/checkout@v4
59+
60+
- name: Set up Python
61+
uses: actions/setup-python@v5
62+
with:
63+
python-version: "3.12"
64+
65+
- name: Install uv
66+
uses: astral-sh/setup-uv@v3
67+
with:
68+
version: "latest"
69+
70+
- name: Install linting tools
71+
run: |
72+
uv venv
73+
uv pip install ruff basedpyright
74+
75+
- name: Run ruff linter
76+
run: |
77+
uv run ruff check .
78+
79+
- name: Run ruff formatter
80+
run: |
81+
uv run ruff format --check .
82+
83+
- name: Run type checker
84+
run: |
85+
uv run basedpyright .

.github/workflows/release.yml

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
name: Release and Publish
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
workflow_dispatch:
8+
inputs:
9+
publish_pypi:
10+
description: 'Publish to PyPI'
11+
required: true
12+
type: boolean
13+
default: false
14+
15+
jobs:
16+
validate:
17+
name: Validate Release
18+
runs-on: ubuntu-latest
19+
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@v4
23+
24+
- name: Set up Python
25+
uses: actions/setup-python@v5
26+
with:
27+
python-version: "3.12"
28+
29+
- name: Install uv
30+
uses: astral-sh/setup-uv@v3
31+
with:
32+
version: "latest"
33+
34+
- name: Install dependencies
35+
run: |
36+
uv venv
37+
uv pip install -e .
38+
uv pip install pytest pytest-asyncio pytest-cov reportlab
39+
40+
- name: Run tests
41+
run: |
42+
uv run pytest tests/ -v --cov=mcp_documents_reader --cov-report=xml
43+
44+
- name: Run linting
45+
run: |
46+
uv run ruff check .
47+
uv run ruff format --check .
48+
uv run basedpyright .
49+
50+
build:
51+
name: Build Distribution
52+
runs-on: ubuntu-latest
53+
needs: validate
54+
55+
steps:
56+
- name: Checkout code
57+
uses: actions/checkout@v4
58+
59+
- name: Set up Python
60+
uses: actions/setup-python@v5
61+
with:
62+
python-version: "3.12"
63+
64+
- name: Install uv
65+
uses: astral-sh/setup-uv@v3
66+
with:
67+
version: "latest"
68+
69+
- name: Install build dependencies
70+
run: |
71+
uv venv
72+
uv pip install build
73+
74+
- name: Build source and wheel distribution
75+
run: |
76+
uv run python -m build
77+
78+
- name: Upload artifacts
79+
uses: actions/upload-artifact@v4
80+
with:
81+
name: dist
82+
path: dist/
83+
84+
publish-pypi:
85+
name: Publish to PyPI
86+
runs-on: ubuntu-latest
87+
needs: [validate, build]
88+
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.publish_pypi)
89+
environment:
90+
name: pypi
91+
url: https://pypi.org/p/mcp-documents-reader
92+
permissions:
93+
id-token: write
94+
95+
steps:
96+
- name: Download artifacts
97+
uses: actions/download-artifact@v4
98+
with:
99+
name: dist
100+
path: dist/
101+
102+
- name: Publish to PyPI
103+
uses: pypa/gh-action-pypi-publish@release/v1
104+
with:
105+
verbose: true
106+
print-hash: true
107+
108+
create-release:
109+
name: Create GitHub Release
110+
runs-on: ubuntu-latest
111+
needs: [validate, build]
112+
if: github.event_name == 'push'
113+
permissions:
114+
contents: write
115+
116+
steps:
117+
- name: Checkout code
118+
uses: actions/checkout@v4
119+
120+
- name: Download artifacts
121+
uses: actions/download-artifact@v4
122+
with:
123+
name: dist
124+
path: dist/
125+
126+
- name: Get tag name
127+
id: tag
128+
run: echo "TAG_NAME=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
129+
130+
- name: Generate release notes
131+
id: release_notes
132+
run: |
133+
echo "CHANGELOG<<EOF" >> $GITHUB_OUTPUT
134+
if [ -f "CHANGELOG.md" ]; then
135+
awk -v ver="${{ steps.tag.outputs.TAG_NAME }}" '/^## \[/ { if (p) { exit }; if ($2 == ver) { p=1; next } } p && NF' CHANGELOG.md >> $GITHUB_OUTPUT
136+
else
137+
echo "No changelog available for this release." >> $GITHUB_OUTPUT
138+
fi
139+
echo "EOF" >> $GITHUB_OUTPUT
140+
141+
- name: Create GitHub Release
142+
uses: softprops/action-gh-release@v2
143+
with:
144+
name: Release ${{ steps.tag.outputs.TAG_NAME }}
145+
body: |
146+
## Changes
147+
148+
${{ steps.release_notes.outputs.CHANGELOG }}
149+
150+
## Installation
151+
152+
```bash
153+
pip install mcp-documents-reader==${{ steps.tag.outputs.TAG_NAME }}
154+
```
155+
156+
Or using uv:
157+
158+
```bash
159+
uv pip install mcp-documents-reader==${{ steps.tag.outputs.TAG_NAME }}
160+
```
161+
files: dist/*
162+
draft: false
163+
prerelease: false
164+
generate_release_notes: true
165+
env:
166+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/security.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Security Scan
2+
3+
on:
4+
push:
5+
branches: [ main, master ]
6+
pull_request:
7+
branches: [ main, master ]
8+
schedule:
9+
- cron: '0 0 * * 0' # Weekly security scan
10+
11+
jobs:
12+
security:
13+
name: Security Scan
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
20+
- name: Set up Python
21+
uses: actions/setup-python@v5
22+
with:
23+
python-version: "3.12"
24+
25+
- name: Install uv
26+
uses: astral-sh/setup-uv@v3
27+
with:
28+
version: "latest"
29+
30+
- name: Install dependencies
31+
run: |
32+
uv venv
33+
uv pip install -e .
34+
uv pip install pip-audit bandit safety
35+
36+
- name: Run pip-audit
37+
run: |
38+
uv run pip-audit || true
39+
40+
- name: Run bandit
41+
run: |
42+
uv run bandit -r . -ll || true
43+
44+
- name: Run safety check
45+
run: |
46+
uv run safety check || true

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,17 @@ pids
147147
# Coverage directory used by tools like istanbul
148148
coverage/
149149
.nyc_output/
150+
htmlcov/
151+
.coverage
152+
.coverage.*
153+
coverage.xml
154+
*.coverage
155+
156+
# pytest
157+
.pytest_cache/
158+
.coverage
159+
htmlcov/
160+
coverage.xml
150161

151162
# Dependency directories
152163
node_modules/

0 commit comments

Comments
 (0)