ci: 添加 PR 自动检测 CI 流程

This commit is contained in:
zhulinsen
2026-01-13 20:34:57 +08:00
parent 34606e36b3
commit 4a41162013
5 changed files with 157 additions and 1 deletions

69
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,69 @@
# CI 流程 - Pull Request 自动检测
# 当有 PR 提交或推送到 main 分支时自动运行
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
# ==================== 核心检查(必须通过)====================
check:
name: ✅ 代码检查
runs-on: ubuntu-latest
steps:
- name: 📥 检出代码
uses: actions/checkout@v4
- name: 🐍 设置 Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
- name: 📦 安装依赖
run: |
pip install --upgrade pip
pip install -r requirements.txt
pip install flake8
- name: 🐍 语法检查
run: |
python -m py_compile main.py config.py analyzer.py notification.py
python -m py_compile storage.py scheduler.py search_service.py
python -m py_compile market_analyzer.py stock_analyzer.py
python -m py_compile data_provider/*.py
echo "✅ Python 语法检查通过"
- name: 🔎 静态分析 (严重错误)
run: |
# 只检查严重错误:语法错误、未定义变量等
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
- name: ✅ 模块导入测试
run: |
python -c "from config import get_config; print('✅ config')"
python -c "from storage import DatabaseManager; print('✅ storage')"
python -c "from notification import NotificationService; print('✅ notification')"
python -c "from data_provider import DataFetcherManager; print('✅ data_provider')"
python -c "from analyzer import GeminiAnalyzer; print('✅ analyzer')"
echo "✅ 所有模块导入成功"
# ==================== Docker 构建测试 ====================
docker:
name: 🐳 Docker 构建
runs-on: ubuntu-latest
needs: [check]
steps:
- name: 📥 检出代码
uses: actions/checkout@v4
- name: 🐳 构建镜像
run: |
docker build -t stock-analysis:test .
docker run --rm stock-analysis:test python -c "print('✅ Docker OK')"

View File

@@ -72,6 +72,36 @@ docs: 更新 README 部署说明
- 重要逻辑添加注释
- 新功能需要更新相关文档
### CI 自动检查
提交 PR 后CI 会自动运行以下检查:
| 检查项 | 说明 | 必须通过 |
|--------|------|:--------:|
| 🐍 语法检查 | Python 语法正确性 | ✅ |
| 📦 依赖安装 | Python 3.10/3.11/3.12 多版本测试 | ✅ |
| 🐳 Docker 构建 | Docker 镜像能正常构建 | ✅ |
| 🔍 代码规范 | Black/Flake8/isort 格式检查 | ⚠️ 警告 |
| 🔒 安全检查 | Bandit/Safety 漏洞扫描 | ⚠️ 警告 |
| 🧪 单元测试 | pytest 测试(如有) | ✅ |
**本地运行检查:**
```bash
# 安装检查工具
pip install black flake8 isort bandit
# 代码格式化
black .
isort .
# 静态检查
flake8 .
# 安全扫描
bandit -r . -x ./test_*.py
```
## 📋 优先贡献方向
查看 [Roadmap](README.md#-roadmap) 了解当前需要的功能:

View File

@@ -1,6 +1,7 @@
# 📈 A股智能分析系统
[![GitHub stars](https://img.shields.io/github/stars/ZhuLinsen/daily_stock_analysis?style=social)](https://github.com/ZhuLinsen/daily_stock_analysis/stargazers)
[![CI](https://github.com/ZhuLinsen/daily_stock_analysis/actions/workflows/ci.yml/badge.svg)](https://github.com/ZhuLinsen/daily_stock_analysis/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![GitHub Actions](https://img.shields.io/badge/GitHub%20Actions-Ready-2088FF?logo=github-actions&logoColor=white)](https://github.com/features/actions)
@@ -68,7 +69,7 @@
| `TELEGRAM_CHAT_ID` | Telegram Chat ID | 可选 |
| `EMAIL_SENDER` | 发件人邮箱(如 `xxx@qq.com` | 可选 |
| `EMAIL_PASSWORD` | 邮箱授权码(非登录密码) | 可选 |
| `EMAIL_RECEIVERS` | 收件人邮箱(留空则发给自己) | 可选 |
| `EMAIL_RECEIVERS` | 收件人邮箱(多个用逗号分隔,留空则发给自己) | 可选 |
| `CUSTOM_WEBHOOK_URLS` | 自定义 Webhook多个用逗号分隔 | 可选 |
> *注:至少配置一个渠道,配置多个则同时推送到所有渠道

28
pyproject.toml Normal file
View File

@@ -0,0 +1,28 @@
[tool.black]
line-length = 120
target-version = ['py310', 'py311', 'py312']
include = '\.pyi?$'
exclude = '''
/(
\.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| venv
| _build
| buck-out
| build
| dist
| __pycache__
)/
'''
[tool.isort]
profile = "black"
line_length = 120
skip = [".git", "__pycache__", ".env", "venv", ".venv"]
[tool.bandit]
exclude_dirs = ["tests", "test_*.py"]
skips = ["B101"] # assert 语句在测试中是允许的

28
setup.cfg Normal file
View File

@@ -0,0 +1,28 @@
[flake8]
max-line-length = 120
exclude =
.git,
__pycache__,
.env,
venv,
.venv,
build,
dist,
*.egg-info
# E501: 行太长(有些地方确实需要长行)
# W503: 运算符在换行前(与 black 冲突)
# E203: 切片前的空格(与 black 冲突)
# E402: 模块级导入不在文件顶部(有时需要先设置环境变量)
ignore = E501,W503,E203,E402
[tool:pytest]
testpaths = .
python_files = test_*.py
python_functions = test_*
addopts = -v --tb=short
[isort]
profile = black
line_length = 120
skip = .git,__pycache__,.env,venv,.venv
known_first_party = config,storage,analyzer,notification,scheduler,search_service,market_analyzer,stock_analyzer,data_provider