Merge pull request #140 from 1985312383/main #35
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # =================================================================== | |
| # CI/CD 流程配置 - 代码质量检查、测试、构建、发布 | |
| # =================================================================== | |
| # 这个workflow在代码文件变更时触发,运行完整的CI/CD流程 | |
| # 排除docs目录和markdown文件的变更 | |
| name: CI/CD Pipeline | |
| on: | |
| push: | |
| branches: [ main, develop ] | |
| paths: | |
| - 'torch_rechub/**' | |
| - 'tutorials/**' | |
| - 'examples/**' | |
| - 'config/**' | |
| - 'tests/**' | |
| - 'pyproject.toml' | |
| - '.github/workflows/ci.yml' | |
| pull_request: | |
| branches: [ main, develop ] | |
| paths: | |
| - 'torch_rechub/**' | |
| - 'tutorials/**' | |
| - 'examples/**' | |
| - 'config/**' | |
| - 'tests/**' | |
| - 'pyproject.toml' | |
| - '.github/workflows/ci.yml' | |
| release: | |
| types: [published] | |
| # 环境变量 | |
| env: | |
| PYTHON_VERSION: '3.9' | |
| TORCH_INDEX_URL: 'https://download.pytorch.org/whl/cpu' | |
| jobs: | |
| # =================================================================== | |
| # 代码质量检查 | |
| # =================================================================== | |
| lint: | |
| name: Code Quality Checks | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Cache pip packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-pip-lint-${{ hashFiles('pyproject.toml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pip-lint- | |
| ${{ runner.os }}-pip- | |
| - name: Install Dependencies | |
| run: | | |
| pip install --upgrade pip | |
| # 安装特定版本的格式化工具以确保一致性(与 pyproject.toml 保持一致) | |
| pip install yapf==0.43.0 isort==5.13.2 flake8>=3.8.0 mypy>=0.800 toml>=0.10.2 | |
| - name: Format & Lint | |
| run: | | |
| # 步骤1: isort | |
| isort --profile black torch_rechub/ examples/ tests/ | |
| # 步骤2: yapf | |
| yapf_style="{based_on_style: google, column_limit: 248, join_multiple_lines: false, split_all_comma_separated_values: true, split_before_logical_operator: true, dedent_closing_brackets: true, align_closing_bracket_with_visual_indent: true, indent_width: 4}" | |
| yapf --in-place --recursive --style="$yapf_style" torch_rechub/ examples/ tests/ | |
| # 步骤3: 检查工作区是否干净,确认所有格式化都已提交 | |
| git diff --exit-code | |
| # 步骤4: 运行flake8进行最终的代码质量检查 | |
| flake8 --max-line-length=248 --extend-ignore=E203,W503,E501,E722,E402,F821,F523,E711,E741,F401,E265,C901,E301,E305,W293,E261,W291,W292,E111,E117,F841,E302 --max-complexity=30 torch_rechub/ examples/ tests/ | |
| - name: Type checking (MyPy) - Optional | |
| continue-on-error: true | |
| run: | | |
| mypy torch_rechub/ --ignore-missing-imports | |
| # =================================================================== | |
| # 完整测试 (Python 3.9) - 运行所有测试和覆盖率报告 | |
| # =================================================================== | |
| test: | |
| name: Full Test Suite (Python 3.9) | |
| runs-on: ${{ matrix.os }} | |
| needs: lint | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, windows-latest, macos-latest] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Set up Python 3.9 | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.9' | |
| - name: Cache pip packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cache/pip | |
| ~/.cache/torch | |
| key: ${{ runner.os }}-py3.9-${{ hashFiles('pyproject.toml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-py3.9- | |
| ${{ runner.os }}- | |
| - name: Install system dependencies (Ubuntu) | |
| if: matrix.os == 'ubuntu-latest' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y build-essential | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| # Install CPU-only PyTorch for faster CI | |
| pip install torch --index-url ${{ env.TORCH_INDEX_URL }} | |
| # Install the package with dev and onnx dependencies | |
| pip install -e ".[dev,onnx]" || pip install -r requirements-dev.txt && pip install -e . | |
| - name: Run tests | |
| run: | | |
| pytest -c config/pytest.ini tests/ -v | |
| - name: Run tests with coverage (Ubuntu only) | |
| if: matrix.os == 'ubuntu-latest' | |
| run: | | |
| pytest -c config/pytest.ini tests/ -v --cov=torch_rechub --cov-report=xml --cov-report=term | |
| - name: Upload coverage to Codecov | |
| if: matrix.os == 'ubuntu-latest' | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| files: ./coverage.xml | |
| flags: unittests | |
| name: codecov-umbrella | |
| # =================================================================== | |
| # 依赖兼容性验证 (Python 3.10+) - 仅验证依赖安装成功 | |
| # =================================================================== | |
| compatibility: | |
| name: Dependency Check (Python ${{ matrix.python-version }}) | |
| runs-on: ubuntu-latest | |
| needs: lint | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ['3.10', '3.11', '3.12', '3.13'] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| # Install CPU-only PyTorch for faster CI | |
| pip install torch --index-url ${{ env.TORCH_INDEX_URL }} | |
| # Verify package installation with all optional dependencies | |
| pip install -e ".[dev,onnx]" | |
| - name: Verify imports | |
| run: | | |
| python -c "import torch_rechub; print(f'torch-rechub {torch_rechub.__version__ if hasattr(torch_rechub, \"__version__\") else \"installed\"} on Python ${{ matrix.python-version }}')" | |
| python -c "import onnx; import onnxruntime; print('ONNX dependencies OK')" | |
| # =================================================================== | |
| # 安全检查 | |
| # =================================================================== | |
| security: | |
| name: Security Scan | |
| runs-on: ubuntu-latest | |
| needs: lint | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Install bandit | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install bandit | |
| - name: Run security scan | |
| run: | | |
| bandit -r torch_rechub/ -s B101,B311,B614 -x tests,docs,examples -f json -o bandit-report.json || true | |
| bandit -r torch_rechub/ -s B101,B311,B614 -x tests,docs,examples -f txt | |
| - name: Upload security scan results | |
| uses: actions/upload-artifact@v5 | |
| if: always() | |
| with: | |
| name: bandit-security-report | |
| path: bandit-report.json | |
| # =================================================================== | |
| # 构建检查 | |
| # =================================================================== | |
| build: | |
| name: Build Package | |
| runs-on: ubuntu-latest | |
| needs: [test, compatibility, security] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Install build dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install build twine wheel setuptools | |
| - name: Build package | |
| run: | | |
| python -m build | |
| - name: Check package | |
| run: | | |
| twine check dist/* | |
| - name: Upload build artifacts | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: dist-packages | |
| path: dist/ | |
| # =================================================================== | |
| # 自动发布到PyPI (使用 uv) | |
| # 功能:从 GitHub Release 自动同步版本号、更新 CHANGELOG、发布到 PyPI | |
| # =================================================================== | |
| publish: | |
| name: Publish to PyPI | |
| runs-on: ubuntu-latest | |
| needs: build | |
| if: github.event_name == 'release' && github.event.action == 'published' | |
| environment: pypi | |
| permissions: | |
| id-token: write # Required for trusted publishing | |
| contents: write # Required for pushing changes back to repo | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| with: | |
| ref: main | |
| fetch-depth: 0 | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Get version from tag | |
| id: get_version | |
| run: | | |
| # 从 tag 提取版本号 (去掉 v 前缀) | |
| VERSION=${GITHUB_REF#refs/tags/v} | |
| echo "VERSION=$VERSION" >> $GITHUB_OUTPUT | |
| echo "📦 Version: $VERSION" | |
| - name: Update version in pyproject.toml | |
| run: | | |
| # 更新 pyproject.toml 中的版本号 | |
| sed -i "s/^version = \".*\"/version = \"${{ steps.get_version.outputs.VERSION }}\"/" pyproject.toml | |
| echo "✅ Updated pyproject.toml version to ${{ steps.get_version.outputs.VERSION }}" | |
| grep "^version" pyproject.toml | |
| - name: Update CHANGELOG.md | |
| env: | |
| RELEASE_BODY: ${{ github.event.release.body }} | |
| RELEASE_NAME: ${{ github.event.release.name }} | |
| run: | | |
| VERSION="${{ steps.get_version.outputs.VERSION }}" | |
| DATE=$(date +%Y-%m-%d) | |
| # 创建新的 changelog 条目 | |
| NEW_ENTRY="## [${VERSION}] - ${DATE} | |
| ${RELEASE_BODY} | |
| --- | |
| " | |
| # 在第一个 --- 分隔符之后插入新版本记录 | |
| awk -v entry="$NEW_ENTRY" ' | |
| !found && /^---$/ { print; print ""; print entry; found=1; next } | |
| { print } | |
| ' CHANGELOG.md > CHANGELOG.tmp && mv CHANGELOG.tmp CHANGELOG.md | |
| echo "✅ Updated CHANGELOG.md with version $VERSION" | |
| - name: Commit and push changes | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add pyproject.toml CHANGELOG.md | |
| # 检查是否有变更 | |
| if git diff --staged --quiet; then | |
| echo "No changes to commit" | |
| else | |
| git commit -m "chore(release): v${{ steps.get_version.outputs.VERSION }} [skip ci]" | |
| git push origin main | |
| echo "✅ Pushed version changes to main branch" | |
| fi | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| with: | |
| version: "latest" | |
| - name: Set up Python | |
| run: uv python install ${{ env.PYTHON_VERSION }} | |
| - name: Build package with uv | |
| run: | | |
| uv build | |
| echo "✅ Package built successfully" | |
| ls -la dist/ | |
| - name: Publish to PyPI | |
| env: | |
| UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }} | |
| run: | | |
| uv publish | |
| echo "🚀 Published to PyPI successfully!" |