Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 135 additions & 6 deletions .github/workflows/build-and-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ name: Build and Release EasyBot-MCDR

on:
push:
branches:
- main
tags:
- 'v*'
workflow_dispatch:
# 允许手动触发工作流
inputs:
version:
description: '手动指定版本号(可选)'
Expand Down Expand Up @@ -37,9 +36,125 @@ jobs:
- name: 安装MCDReforged
run: pip install mcdreforged>=2.14

- name: 安装测试依赖
run: pip install pytest pytest-asyncio>=1.0.0 -q

- name: 运行插件测试
id: plugin_test
run: |
pytest tests/test_plugin.py -v --tb=short 2>&1 | tee /tmp/test-output.txt
echo "TEST_EXIT_CODE=$?" >> $GITHUB_ENV
continue-on-error: true

- name: 生成测试报告
if: always()
run: |
# 获取版本号
PLUGIN_VERSION=$(grep -o '"version": "[^"]*"' mcdreforged.plugin.json | sed 's/"version": "\([^"]*\)"/\1/')
PLUGIN_VERSION=${PLUGIN_VERSION:-"未知"}
PYTHON_VERSION=$(python --version | awk '{print $2}')
RUN_TIME=$(date -u '+%Y-%m-%d %H:%M:%S UTC')

# 统计结果
TOTAL=$(grep -c -E "PASSED|FAILED|ERROR" /tmp/test-output.txt || true)
PASSED=$(grep -c "PASSED" /tmp/test-output.txt || true)
FAILED=$(grep -c "FAILED" /tmp/test-output.txt || true)

# 确保变量是数字(默认为0)
TOTAL=${TOTAL:-0}
PASSED=${PASSED:-0}
FAILED=${FAILED:-0}

# 计算通过率
if [ "$TOTAL" -gt "0" ]; then
PASS_RATE=$(echo "scale=1; $PASSED * 100 / $TOTAL" | bc)
else
PASS_RATE="0.0"
fi

echo "TEST_PASSED=$PASSED" >> $GITHUB_ENV
echo "TEST_FAILED=$FAILED" >> $GITHUB_ENV
echo "TEST_TOTAL=$TOTAL" >> $GITHUB_ENV
echo "TEST_PASS_RATE=$PASS_RATE" >> $GITHUB_ENV

if [ "$FAILED" -gt "0" ] 2>/dev/null; then
echo "TEST_STATUS=❌ $FAILED 项失败" >> $GITHUB_ENV
else
echo "TEST_STATUS=✅ 全部通过" >> $GITHUB_ENV
fi

# 生成 Step Summary 报告
echo "## EasyBot-MCDR 测试报告" >> $GITHUB_STEP_SUMMARY
echo "插件版本: $PLUGIN_VERSION" >> $GITHUB_STEP_SUMMARY
echo "Python: $PYTHON_VERSION" >> $GITHUB_STEP_SUMMARY
echo "运行平台: linux" >> $GITHUB_STEP_SUMMARY
echo "测试时间: $RUN_TIME" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY

echo "### 概览" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| 指标 | 结果 |" >> $GITHUB_STEP_SUMMARY
echo "|------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 总计 | $TOTAL |" >> $GITHUB_STEP_SUMMARY
echo "| 通过 | $PASSED |" >> $GITHUB_STEP_SUMMARY
echo "| 失败 | $FAILED |" >> $GITHUB_STEP_SUMMARY
echo "| 通过率 | ${PASS_RATE}% |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY

echo "### 测试详情" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| # | 测试项 | 结果 | 耗时 |" >> $GITHUB_STEP_SUMMARY
echo "|---|--------|------|------|" >> $GITHUB_STEP_SUMMARY

# 解析测试输出,生成详细表格
TEST_NUM=0
while IFS= read -r line; do
if echo "$line" | grep -qE "(PASSED|FAILED|ERROR)"; then
TEST_NUM=$((TEST_NUM + 1))
# 提取测试名称和结果
TEST_NAME=$(echo "$line" | sed 's/.*:://' | sed 's/ PASSED.*//' | sed 's/ FAILED.*//' | sed 's/ ERROR.*//')
TEST_TIME=$(echo "$line" | grep -oP '[\d.]+s$' || echo "0.000s")

if echo "$line" | grep -q "PASSED"; then
TEST_RESULT="✅ 通过"
elif echo "$line" | grep -q "FAILED"; then
TEST_RESULT="❌ 失败"
else
TEST_RESULT="⚠️ 错误"
fi

echo "| $TEST_NUM | $TEST_NAME | $TEST_RESULT | $TEST_TIME |" >> $GITHUB_STEP_SUMMARY
fi
done < /tmp/test-output.txt

- name: 使用MCDReforged打包插件
run: mcdreforged pack

- name: 代码质量检查
id: quality_check
run: |
pip install ruff pip-audit -q
echo "## 代码质量检查" >> $GITHUB_STEP_SUMMARY

# Ruff 检查
if ruff check . 2>&1 | tee /tmp/ruff-result.txt; then
echo "RUFF_STATUS=✅ 通过" >> $GITHUB_ENV
else
echo "RUFF_STATUS=❌ 发现问题" >> $GITHUB_ENV
fi

# 依赖安全检查
if pip-audit -r requirements.txt 2>&1 | tee /tmp/audit-result.txt; then
echo "AUDIT_STATUS=✅ 通过" >> $GITHUB_ENV
else
echo "AUDIT_STATUS=❌ 发现问题" >> $GITHUB_ENV
fi

echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
echo "| Ruff 代码检查 | ${{ env.RUFF_STATUS }} |" >> $GITHUB_STEP_SUMMARY
echo "| 依赖安全 | ${{ env.AUDIT_STATUS }} |" >> $GITHUB_STEP_SUMMARY

- name: 获取版本号
id: get_version
run: |
Expand Down Expand Up @@ -67,19 +182,33 @@ jobs:
${{ env.MCDR_PATH }}

- name: 发布到GitHub Release
if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/v') || github.event_name == 'push' && github.ref == 'refs/heads/main'
if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/v')
uses: softprops/action-gh-release@v2
with:
# 如果是标签推送,使用标签作为版本号
tag_name: ${{ startsWith(github.ref, 'refs/tags/v') && github.ref || format('v{0}', env.VERSION) }}
name: EasyBot-MCDR ${{ env.VERSION || 'Development Build' }}
body: |
## EasyBot-MCDR ${{ env.VERSION || 'Development Build' }}

### 版本信息
- 插件版本: ${{ env.VERSION || 'Development Build' }}
- MCDReforged: >= 2.14


### 测试结果
| 指标 | 结果 |
|------|------|
| 测试状态 | ${{ env.TEST_STATUS }} |
| 总计 | ${{ env.TEST_TOTAL }} |
| 通过 | ✅ ${{ env.TEST_PASSED }} |
| 失败 | ❌ ${{ env.TEST_FAILED }} |

### 代码质量
| 检查项 | 状态 |
|--------|------|
| Ruff 代码检查 | ${{ env.RUFF_STATUS }} |
| 依赖安全 | ${{ env.AUDIT_STATUS }} |

### 更新内容
draft: false
prerelease: contains('${{ env.VERSION }}', 'beta') || contains('${{ env.VERSION }}', 'alpha')
Expand Down
197 changes: 197 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

permissions:
contents: read

jobs:
test:
name: 集成测试
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip

- name: 安装依赖
run: |
pip install -r requirements.txt
pip install mcdreforged>=2.14
pip install pytest pytest-asyncio>=1.0.0

- name: 运行测试
run: pytest -v --tb=short 2>&1 | tee test-output.txt
continue-on-error: true

- name: 生成测试报告
if: always()
run: |
echo "## 🧪 测试报告" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY

# 统计结果
TOTAL=$(grep -c -E "PASSED|FAILED|ERROR" test-output.txt || true)
PASSED=$(grep -c "PASSED" test-output.txt || true)
FAILED=$(grep -c "FAILED" test-output.txt || true)

# 确保变量是数字(默认为0)
TOTAL=${TOTAL:-0}
PASSED=${PASSED:-0}
FAILED=${FAILED:-0}

echo "| 指标 | 结果 |" >> $GITHUB_STEP_SUMMARY
echo "|------|------|" >> $GITHUB_STEP_SUMMARY
echo "| 总计 | $TOTAL |" >> $GITHUB_STEP_SUMMARY
echo "| 通过 | ✅ $PASSED |" >> $GITHUB_STEP_SUMMARY
echo "| 失败 | ❌ $FAILED |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY

# 测试详情表格
echo "### 详细结果" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| 测试项 | 结果 |" >> $GITHUB_STEP_SUMMARY
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
grep -E "(PASSED|FAILED|ERROR)" test-output.txt | sed 's/.*:://' | sed 's/ PASSED/ ✅ |/' | sed 's/ FAILED/ ❌ |/' | sed 's/ ERROR/ ⚠️ |/' >> $GITHUB_STEP_SUMMARY || true
echo "" >> $GITHUB_STEP_SUMMARY

# 如果有失败,显示详细信息
if [ "$FAILED" -gt "0" ] 2>/dev/null; then
echo "### ❌ 失败详情" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
grep -A 20 "FAILED" test-output.txt | head -50 >> $GITHUB_STEP_SUMMARY || true
echo '```' >> $GITHUB_STEP_SUMMARY
fi

# 设置输出变量供后续步骤使用
echo "TEST_PASSED=$PASSED" >> $GITHUB_ENV
echo "TEST_FAILED=$FAILED" >> $GITHUB_ENV
echo "TEST_TOTAL=$TOTAL" >> $GITHUB_ENV

# 如果有失败则返回错误
if [ "$FAILED" -gt "0" ] 2>/dev/null; then
exit 1
fi
lint:
name: 代码检查
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: 安装 ruff
run: pip install ruff

- name: Ruff 代码检查
run: |
if ruff check . --output-file ruff-report.txt 2>&1 | tee ruff-output.txt; then
echo "## ✅ Ruff 代码检查通过" >> $GITHUB_STEP_SUMMARY
else
echo "## ❌ Ruff 代码检查发现问题" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
cat ruff-output.txt >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
fi

type-check:
name: 类型检查
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip

- name: 安装依赖
run: |
pip install -r requirements.txt
pip install mcdreforged>=2.14

- name: 安装 pyright
run: pip install pyright

- name: Pyright 类型检查
run: |
if pyright 2>&1 | tee pyright-output.txt; then
echo "## ✅ Pyright 类型检查通过" >> $GITHUB_STEP_SUMMARY
else
echo "## ⚠️ Pyright 类型检查发现问题(非阻断)" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
tail -20 pyright-output.txt >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
fi
continue-on-error: true

security:
name: 安全扫描
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: 安装 pip-audit
run: pip install pip-audit

- name: 审计依赖安全
run: |
if pip-audit -r requirements.txt 2>&1 | tee audit-output.txt; then
echo "## ✅ 依赖安全检查通过" >> $GITHUB_STEP_SUMMARY
else
echo "## ❌ 依赖安全检查发现问题" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
cat audit-output.txt >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
fi

import-check:
name: 导入检查
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip

- name: 安装依赖
run: |
pip install -r requirements.txt
pip install mcdreforged>=2.14

- name: 检查模块导入
run: |
python -c "
import importlib, sys, pathlib

errors = []
for f in pathlib.Path('easybot_mcdr').rglob('*.py'):
mod = f.with_suffix('').as_posix().replace('/', '.')
try:
importlib.import_module(mod)
except Exception as e:
# 跳过 MCDR 运行时错误,只关注导入/语法问题
if isinstance(e, (SyntaxError, ImportError, ModuleNotFoundError)):
errors.append((mod, str(e)))

if errors:
for m, e in errors:
print(f'失败: {m} -> {e}', file=sys.stderr)
sys.exit(1)
print('所有模块均可导入(或仅有预期的 MCDR 运行时依赖)')
"
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ __pycache__/
*.pyd
*.pyi
__temp
.idea
.idea
.pytest_cache/
*.egg-info/
Loading
Loading