Files
Elevator/.github/workflows/code-quality.yml
2025-09-28 20:28:12 +08:00

270 lines
7.5 KiB
YAML

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