mirror of
https://github.com/ZGCA-Forge/Elevator.git
synced 2026-02-04 05:15:19 +00:00
add ci build
This commit is contained in:
0
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
0
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
0
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
0
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
38
.github/dependabot.yml
vendored
Normal file
38
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
# Python dependencies
|
||||||
|
- package-ecosystem: "pip"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
day: "monday"
|
||||||
|
time: "06:00"
|
||||||
|
open-pull-requests-limit: 10
|
||||||
|
reviewers:
|
||||||
|
- "elevator-py-team"
|
||||||
|
assignees:
|
||||||
|
- "elevator-py-team"
|
||||||
|
labels:
|
||||||
|
- "dependencies"
|
||||||
|
- "python"
|
||||||
|
commit-message:
|
||||||
|
prefix: "deps"
|
||||||
|
include: "scope"
|
||||||
|
|
||||||
|
# GitHub Actions
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
|
day: "monday"
|
||||||
|
time: "06:00"
|
||||||
|
open-pull-requests-limit: 5
|
||||||
|
reviewers:
|
||||||
|
- "elevator-py-team"
|
||||||
|
labels:
|
||||||
|
- "dependencies"
|
||||||
|
- "github-actions"
|
||||||
|
commit-message:
|
||||||
|
prefix: "ci"
|
||||||
|
include: "scope"
|
||||||
|
|
||||||
0
.github/pull_request_template.md
vendored
Normal file
0
.github/pull_request_template.md
vendored
Normal file
220
.github/workflows/ci.yml
vendored
Normal file
220
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main, develop ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ main, develop ]
|
||||||
|
schedule:
|
||||||
|
# Run tests daily at 6 AM UTC
|
||||||
|
- cron: '0 6 * * *'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: Test Python ${{ matrix.python-version }} on ${{ matrix.os }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
|
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: ${{ matrix.python-version }}
|
||||||
|
|
||||||
|
- name: Cache pip dependencies
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: ~/.cache/pip
|
||||||
|
key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-pip-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install -e .
|
||||||
|
|
||||||
|
- name: Check dependencies
|
||||||
|
run: |
|
||||||
|
python run_all_tests.py --check-deps
|
||||||
|
|
||||||
|
- name: Run linting
|
||||||
|
run: |
|
||||||
|
black --check msgcenterpy tests
|
||||||
|
isort --check-only msgcenterpy tests
|
||||||
|
|
||||||
|
- name: Run type checking
|
||||||
|
run: |
|
||||||
|
mypy msgcenterpy
|
||||||
|
|
||||||
|
- name: Run tests with coverage
|
||||||
|
run: |
|
||||||
|
python -m pytest --cov=msgcenterpy --cov-report=xml --cov-report=term-missing
|
||||||
|
|
||||||
|
- name: Upload coverage to Codecov
|
||||||
|
if: matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest'
|
||||||
|
uses: codecov/codecov-action@v3
|
||||||
|
with:
|
||||||
|
file: ./coverage.xml
|
||||||
|
flags: unittests
|
||||||
|
name: codecov-umbrella
|
||||||
|
fail_ci_if_error: false
|
||||||
|
|
||||||
|
test-with-ros2:
|
||||||
|
name: Test with ROS2 (Ubuntu)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ros:humble
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
run: |
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y python3-pip python3-dev
|
||||||
|
|
||||||
|
- name: Install ROS2 dependencies
|
||||||
|
run: |
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y \
|
||||||
|
python3-rosidl-runtime-py \
|
||||||
|
python3-rclpy \
|
||||||
|
ros-humble-std-msgs \
|
||||||
|
ros-humble-geometry-msgs
|
||||||
|
|
||||||
|
- name: Install package
|
||||||
|
run: |
|
||||||
|
python3 -m pip install --upgrade pip
|
||||||
|
pip3 install -e .[dev,ros2]
|
||||||
|
|
||||||
|
- name: Run ROS2 tests
|
||||||
|
run: |
|
||||||
|
. /opt/ros/humble/setup.sh
|
||||||
|
python3 run_all_tests.py --type ros2
|
||||||
|
|
||||||
|
- name: Run conversion tests
|
||||||
|
run: |
|
||||||
|
. /opt/ros/humble/setup.sh
|
||||||
|
python3 run_all_tests.py --type conversion
|
||||||
|
|
||||||
|
build:
|
||||||
|
name: Build and check package
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
|
||||||
|
- name: Install build dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install build twine check-manifest
|
||||||
|
|
||||||
|
- name: Check manifest
|
||||||
|
run: check-manifest
|
||||||
|
|
||||||
|
- name: Build package
|
||||||
|
run: python -m build
|
||||||
|
|
||||||
|
- name: Check package
|
||||||
|
run: twine check dist/*
|
||||||
|
|
||||||
|
- name: Upload build artifacts
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: dist
|
||||||
|
path: dist/
|
||||||
|
|
||||||
|
security:
|
||||||
|
name: Security scan
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
|
||||||
|
- name: Install security tools
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install bandit safety
|
||||||
|
|
||||||
|
- name: Run bandit security scan
|
||||||
|
run: bandit -r msgcenterpy/ -f json -o bandit-report.json
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Run safety security scan
|
||||||
|
run: safety check --json --output safety-report.json
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Upload security reports
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: security-reports
|
||||||
|
path: |
|
||||||
|
bandit-report.json
|
||||||
|
safety-report.json
|
||||||
|
if: always()
|
||||||
|
|
||||||
|
docs:
|
||||||
|
name: Build documentation
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install -e .[docs]
|
||||||
|
|
||||||
|
# 为将来的文档构建预留
|
||||||
|
- name: Check documentation
|
||||||
|
run: |
|
||||||
|
echo "Documentation build placeholder"
|
||||||
|
# sphinx-build -b html docs docs/_build/html
|
||||||
|
|
||||||
|
performance:
|
||||||
|
name: Performance benchmarks
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install -e .
|
||||||
|
pip install pytest-benchmark
|
||||||
|
|
||||||
|
# 为将来的性能测试预留
|
||||||
|
- name: Run benchmarks
|
||||||
|
run: |
|
||||||
|
echo "Performance benchmarks placeholder"
|
||||||
|
# python -m pytest tests/benchmarks/ --benchmark-json=benchmark.json
|
||||||
|
|
||||||
269
.github/workflows/code-quality.yml
vendored
Normal file
269
.github/workflows/code-quality.yml
vendored
Normal file
@@ -0,0 +1,269 @@
|
|||||||
|
name: Code Quality
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main, develop ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ main, develop ]
|
||||||
|
schedule:
|
||||||
|
# Run weekly code quality checks
|
||||||
|
- cron: '0 2 * * 1'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
name: Linting and formatting
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
|
||||||
|
- name: Cache pip dependencies
|
||||||
|
uses: actions/cache@v3
|
||||||
|
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: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install -e .
|
||||||
|
pip install flake8 pylint
|
||||||
|
|
||||||
|
- name: Run Black formatting check
|
||||||
|
run: |
|
||||||
|
black --check --diff elevator_saga tests
|
||||||
|
|
||||||
|
- name: Run isort import sorting check
|
||||||
|
run: |
|
||||||
|
isort --check-only --diff elevator_saga tests
|
||||||
|
|
||||||
|
- name: Run flake8
|
||||||
|
run: |
|
||||||
|
flake8 elevator_saga tests --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||||
|
flake8 elevator_saga tests --count --exit-zero --max-complexity=10 --max-line-length=88 --statistics
|
||||||
|
|
||||||
|
- name: Run pylint
|
||||||
|
run: |
|
||||||
|
pylint elevator_saga --exit-zero --output-format=parseable --reports=no | tee pylint-report.txt
|
||||||
|
|
||||||
|
- name: Upload lint reports
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: lint-reports
|
||||||
|
path: |
|
||||||
|
pylint-report.txt
|
||||||
|
if: always()
|
||||||
|
|
||||||
|
type-check:
|
||||||
|
name: Type checking
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install -e .
|
||||||
|
|
||||||
|
- name: Run mypy type checking
|
||||||
|
run: |
|
||||||
|
mypy elevator_saga --html-report mypy-report --txt-report mypy-report
|
||||||
|
|
||||||
|
- name: Upload type check reports
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: type-check-reports
|
||||||
|
path: mypy-report/
|
||||||
|
if: always()
|
||||||
|
|
||||||
|
complexity:
|
||||||
|
name: Code complexity analysis
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install radon xenon
|
||||||
|
|
||||||
|
- name: Run cyclomatic complexity check
|
||||||
|
run: |
|
||||||
|
radon cc elevator_saga --min B --total-average
|
||||||
|
|
||||||
|
- name: Run maintainability index
|
||||||
|
run: |
|
||||||
|
radon mi elevator_saga --min B
|
||||||
|
|
||||||
|
- name: Run complexity with xenon
|
||||||
|
run: |
|
||||||
|
xenon --max-absolute B --max-modules B --max-average A elevator_saga
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
name: Dependency analysis
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install -e .
|
||||||
|
pip install pip-audit pipdeptree
|
||||||
|
|
||||||
|
- name: Generate dependency tree
|
||||||
|
run: |
|
||||||
|
pipdeptree --freeze > requirements-freeze.txt
|
||||||
|
pipdeptree --graph-output png > dependency-graph.png
|
||||||
|
|
||||||
|
- name: Check for known vulnerabilities
|
||||||
|
run: |
|
||||||
|
pip-audit --format=json --output=vulnerability-report.json
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Upload dependency reports
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: dependency-reports
|
||||||
|
path: |
|
||||||
|
requirements-freeze.txt
|
||||||
|
dependency-graph.png
|
||||||
|
vulnerability-report.json
|
||||||
|
if: always()
|
||||||
|
|
||||||
|
documentation:
|
||||||
|
name: Documentation quality
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install -e .
|
||||||
|
pip install pydocstyle interrogate
|
||||||
|
|
||||||
|
- name: Check docstring style
|
||||||
|
run: |
|
||||||
|
pydocstyle elevator_saga --count --explain --source
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Check docstring coverage
|
||||||
|
run: |
|
||||||
|
interrogate elevator_saga --ignore-init-method --ignore-magic --ignore-module --ignore-nested-functions --fail-under=70
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
pre-commit:
|
||||||
|
name: Pre-commit hooks
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
|
||||||
|
- name: Install pre-commit
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install pre-commit
|
||||||
|
|
||||||
|
- name: Cache pre-commit
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: ~/.cache/pre-commit
|
||||||
|
key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}
|
||||||
|
|
||||||
|
- name: Run pre-commit hooks
|
||||||
|
run: |
|
||||||
|
pre-commit run --all-files --show-diff-on-failure
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
summary:
|
||||||
|
name: Quality summary
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [lint, type-check, complexity, dependencies, documentation, pre-commit]
|
||||||
|
if: always()
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Create quality report
|
||||||
|
run: |
|
||||||
|
echo "## 📊 Code Quality Report" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Check | Status |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "|-------|--------|" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
# Format results
|
||||||
|
if [ "${{ needs.lint.result }}" = "success" ]; then
|
||||||
|
echo "| Linting | ✅ Passed |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
else
|
||||||
|
echo "| Linting | ❌ Failed |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${{ needs.type-check.result }}" = "success" ]; then
|
||||||
|
echo "| Type Check | ✅ Passed |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
else
|
||||||
|
echo "| Type Check | ❌ Failed |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${{ needs.complexity.result }}" = "success" ]; then
|
||||||
|
echo "| Complexity | ✅ Passed |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
else
|
||||||
|
echo "| Complexity | ⚠️ Warning |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${{ needs.dependencies.result }}" = "success" ]; then
|
||||||
|
echo "| Dependencies | ✅ Secure |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
else
|
||||||
|
echo "| Dependencies | ⚠️ Check needed |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${{ needs.documentation.result }}" = "success" ]; then
|
||||||
|
echo "| Documentation | ✅ Good |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
else
|
||||||
|
echo "| Documentation | ⚠️ Needs improvement |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${{ needs.pre-commit.result }}" = "success" ]; then
|
||||||
|
echo "| Pre-commit | ✅ Passed |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
else
|
||||||
|
echo "| Pre-commit | ⚠️ Some hooks failed |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "📈 **Overall Quality:** ${{ needs.lint.result == 'success' && needs.type-check.result == 'success' && 'Good' || 'Needs attention' }}" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
34
.github/workflows/dependabot.yml
vendored
Normal file
34
.github/workflows/dependabot.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
name: Dependabot Auto-merge
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, reopened]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
dependabot:
|
||||||
|
name: Auto-merge Dependabot PRs
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.actor == 'dependabot[bot]'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Dependabot metadata
|
||||||
|
id: metadata
|
||||||
|
uses: dependabot/fetch-metadata@v1
|
||||||
|
with:
|
||||||
|
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
|
||||||
|
- name: Enable auto-merge for Dependabot PRs
|
||||||
|
if: steps.metadata.outputs.update-type == 'version-update:semver-patch' || steps.metadata.outputs.update-type == 'version-update:semver-minor'
|
||||||
|
run: gh pr merge --auto --merge "$PR_URL"
|
||||||
|
env:
|
||||||
|
PR_URL: ${{ github.event.pull_request.html_url }}
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Comment on major version updates
|
||||||
|
if: steps.metadata.outputs.update-type == 'version-update:semver-major'
|
||||||
|
run: |
|
||||||
|
gh pr comment "$PR_URL" --body "🚨 **Major version update detected!** Please review this PR carefully before merging."
|
||||||
|
env:
|
||||||
|
PR_URL: ${{ github.event.pull_request.html_url }}
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
184
.github/workflows/publish.yml
vendored
Normal file
184
.github/workflows/publish.yml
vendored
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
name: Publish to PyPI
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
test_pypi:
|
||||||
|
description: 'Publish to Test PyPI instead of PyPI'
|
||||||
|
required: false
|
||||||
|
default: 'false'
|
||||||
|
type: boolean
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: Run tests before publish
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install -e .
|
||||||
|
|
||||||
|
- name: Run comprehensive tests
|
||||||
|
run: |
|
||||||
|
python -m pytest --cov=msgcenterpy --cov-fail-under=80
|
||||||
|
|
||||||
|
- name: Run linting
|
||||||
|
run: |
|
||||||
|
black --check msgcenterpy tests
|
||||||
|
isort --check-only msgcenterpy tests
|
||||||
|
mypy msgcenterpy
|
||||||
|
|
||||||
|
build:
|
||||||
|
name: Build package
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: test
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
|
||||||
|
# - name: Install build dependencies
|
||||||
|
# run: |
|
||||||
|
# python -m pip install --upgrade pip
|
||||||
|
# pip install build twine check-manifest
|
||||||
|
|
||||||
|
# - name: Verify version consistency
|
||||||
|
# run: |
|
||||||
|
# # 检查版本号一致性
|
||||||
|
# VERSION=$(python -c "import msgcenterpy; print(msgcenterpy.__version__)" 2>/dev/null || echo "unknown")
|
||||||
|
# TAG_VERSION="${GITHUB_REF#refs/tags/v}"
|
||||||
|
# if [ "$GITHUB_EVENT_NAME" = "release" ]; then
|
||||||
|
# if [ "$VERSION" != "$TAG_VERSION" ]; then
|
||||||
|
# echo "Version mismatch: package=$VERSION, tag=$TAG_VERSION"
|
||||||
|
# exit 1
|
||||||
|
# fi
|
||||||
|
# fi
|
||||||
|
|
||||||
|
# - name: Check manifest
|
||||||
|
# run: check-manifest
|
||||||
|
|
||||||
|
- name: Build package
|
||||||
|
run: |
|
||||||
|
python -m build
|
||||||
|
|
||||||
|
- name: Check package
|
||||||
|
run: |
|
||||||
|
twine check dist/*
|
||||||
|
|
||||||
|
- name: Upload build artifacts
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: dist-${{ github.run_number }}
|
||||||
|
path: dist/
|
||||||
|
retention-days: 30
|
||||||
|
|
||||||
|
publish-test:
|
||||||
|
name: Publish to Test PyPI
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
if: github.event.inputs.test_pypi == 'true' || (github.event_name == 'release' && github.event.release.prerelease)
|
||||||
|
environment:
|
||||||
|
name: test-pypi
|
||||||
|
url: https://test.pypi.org/p/msgcenterpy
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Download build artifacts
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: dist-${{ github.run_number }}
|
||||||
|
path: dist/
|
||||||
|
|
||||||
|
- name: Publish to Test PyPI
|
||||||
|
uses: pypa/gh-action-pypi-publish@release/v1
|
||||||
|
with:
|
||||||
|
repository-url: https://test.pypi.org/legacy/
|
||||||
|
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
|
||||||
|
verbose: true
|
||||||
|
|
||||||
|
publish-pypi:
|
||||||
|
name: Publish to PyPI
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
if: github.event_name == 'release' && !github.event.release.prerelease && github.event.inputs.test_pypi != 'true'
|
||||||
|
environment:
|
||||||
|
name: pypi
|
||||||
|
url: https://pypi.org/p/msgcenterpy
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Download build artifacts
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: dist-${{ github.run_number }}
|
||||||
|
path: dist/
|
||||||
|
|
||||||
|
- name: Publish to PyPI
|
||||||
|
uses: pypa/gh-action-pypi-publish@release/v1
|
||||||
|
with:
|
||||||
|
password: ${{ secrets.PYPI_API_TOKEN }}
|
||||||
|
verbose: true
|
||||||
|
|
||||||
|
create-github-release-assets:
|
||||||
|
name: Add assets to GitHub release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
if: github.event_name == 'release'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Download build artifacts
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: dist-${{ github.run_number }}
|
||||||
|
path: dist/
|
||||||
|
|
||||||
|
- name: Upload release assets
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
with:
|
||||||
|
files: dist/*
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
post-publish:
|
||||||
|
name: Post-publish tasks
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [publish-pypi, publish-test]
|
||||||
|
if: always() && (needs.publish-pypi.result == 'success' || needs.publish-test.result == 'success')
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Create deployment summary
|
||||||
|
run: |
|
||||||
|
echo "## 🚀 Deployment Summary" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Item | Status |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "|------|--------|" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
if [ "${{ needs.publish-pypi.result }}" = "success" ]; then
|
||||||
|
echo "| PyPI | ✅ Published |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
elif [ "${{ needs.publish-test.result }}" = "success" ]; then
|
||||||
|
echo "| Test PyPI | ✅ Published |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "| GitHub Release | ✅ Assets uploaded |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "| Version | ${{ github.event.release.tag_name || 'test' }} |" >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
# 为将来的通知预留
|
||||||
|
- name: Notify team
|
||||||
|
run: |
|
||||||
|
echo "Package published successfully!"
|
||||||
|
# 可以添加 Slack、Discord 等通知
|
||||||
|
|
||||||
113
.pre-commit-config.yaml
Normal file
113
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
repos:
|
||||||
|
# Code formatting
|
||||||
|
- repo: https://github.com/psf/black
|
||||||
|
rev: 23.12.1
|
||||||
|
hooks:
|
||||||
|
- id: black
|
||||||
|
language_version: python3
|
||||||
|
args: ["--line-length=88"]
|
||||||
|
|
||||||
|
# Import sorting
|
||||||
|
- repo: https://github.com/pycqa/isort
|
||||||
|
rev: 5.13.2
|
||||||
|
hooks:
|
||||||
|
- id: isort
|
||||||
|
args: ["--profile", "black", "--multi-line", "3"]
|
||||||
|
|
||||||
|
# Linting
|
||||||
|
- repo: https://github.com/pycqa/flake8
|
||||||
|
rev: 7.0.0
|
||||||
|
hooks:
|
||||||
|
- id: flake8
|
||||||
|
args:
|
||||||
|
- "--max-line-length=88"
|
||||||
|
- "--extend-ignore=E203,W503,F401"
|
||||||
|
- "--exclude=build,dist,.eggs"
|
||||||
|
|
||||||
|
# Type checking
|
||||||
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||||
|
rev: v1.8.0
|
||||||
|
hooks:
|
||||||
|
- id: mypy
|
||||||
|
additional_dependencies: [types-PyYAML]
|
||||||
|
args: ["--ignore-missing-imports", "--scripts-are-modules"]
|
||||||
|
exclude: "^(tests/|examples/)"
|
||||||
|
|
||||||
|
# General pre-commit hooks
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: v4.5.0
|
||||||
|
hooks:
|
||||||
|
# File checks
|
||||||
|
- id: trailing-whitespace
|
||||||
|
args: [--markdown-linebreak-ext=md]
|
||||||
|
- id: end-of-file-fixer
|
||||||
|
- id: check-yaml
|
||||||
|
- id: check-json
|
||||||
|
- id: check-toml
|
||||||
|
- id: check-xml
|
||||||
|
|
||||||
|
# Security
|
||||||
|
- id: check-merge-conflict
|
||||||
|
- id: check-case-conflict
|
||||||
|
- id: check-symlinks
|
||||||
|
- id: check-added-large-files
|
||||||
|
args: ["--maxkb=1000"]
|
||||||
|
|
||||||
|
# Python specific
|
||||||
|
- id: check-ast
|
||||||
|
- id: check-builtin-literals
|
||||||
|
- id: check-docstring-first
|
||||||
|
- id: debug-statements
|
||||||
|
- id: name-tests-test
|
||||||
|
args: ["--django"]
|
||||||
|
|
||||||
|
# Security scanning
|
||||||
|
- repo: https://github.com/PyCQA/bandit
|
||||||
|
rev: 1.7.5
|
||||||
|
hooks:
|
||||||
|
- id: bandit
|
||||||
|
args: ["-c", "pyproject.toml"]
|
||||||
|
additional_dependencies: ["bandit[toml]"]
|
||||||
|
exclude: "^tests/"
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
- repo: https://github.com/pycqa/pydocstyle
|
||||||
|
rev: 6.3.0
|
||||||
|
hooks:
|
||||||
|
- id: pydocstyle
|
||||||
|
args: ["--convention=google"]
|
||||||
|
exclude: "^(tests/|examples/)"
|
||||||
|
|
||||||
|
# YAML/JSON formatting
|
||||||
|
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||||
|
rev: v4.0.0-alpha.8
|
||||||
|
hooks:
|
||||||
|
- id: prettier
|
||||||
|
types_or: [yaml, json, markdown]
|
||||||
|
exclude: "^(.github/)"
|
||||||
|
|
||||||
|
# Spell checking (optional)
|
||||||
|
- repo: https://github.com/codespell-project/codespell
|
||||||
|
rev: v2.2.6
|
||||||
|
hooks:
|
||||||
|
- id: codespell
|
||||||
|
args: ["--write-changes"]
|
||||||
|
exclude: "^(.*\\.po|.*\\.pot|CHANGELOG\\.md)$"
|
||||||
|
|
||||||
|
# Global settings
|
||||||
|
default_stages: [commit, push]
|
||||||
|
fail_fast: false
|
||||||
|
|
||||||
|
# CI settings
|
||||||
|
ci:
|
||||||
|
autofix_commit_msg: |
|
||||||
|
[pre-commit.ci] auto fixes from pre-commit.com hooks
|
||||||
|
|
||||||
|
for more information, see https://pre-commit.ci
|
||||||
|
autofix_prs: true
|
||||||
|
autoupdate_branch: ''
|
||||||
|
autoupdate_commit_msg: '[pre-commit.ci] pre-commit autoupdate'
|
||||||
|
autoupdate_schedule: weekly
|
||||||
|
skip: []
|
||||||
|
submodules: false
|
||||||
|
|
||||||
Reference in New Issue
Block a user