feat(ci): workflows #27
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
| name: CI | |
| on: | |
| push: | |
| branches: [master, dev, feat/*, fix/*, docs/*, release/*] | |
| pull_request: | |
| branches: [master, dev, feat/*, fix/*, docs/*, release/*] | |
| workflow_dispatch: | |
| jobs: | |
| lint: | |
| name: Code Quality (Linting & Formatting) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| cache: "pip" | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install ruff black isort pydocstyle mypy bandit[toml] | |
| pip install types-PyYAML types-setuptools | |
| pip install -e . | |
| - name: Run Ruff (linting) | |
| run: | | |
| ruff check visdrone_toolkit/ scripts/ tests/ --exit-non-zero-on-fix | |
| - name: Run Ruff (formatting check) | |
| run: | | |
| ruff format --check visdrone_toolkit/ scripts/ tests/ | |
| - name: Run Black (formatting check) | |
| run: | | |
| black --check --diff visdrone_toolkit/ scripts/ tests/ --line-length=100 | |
| - name: Run isort (import sorting check) | |
| run: | | |
| isort --check-only --diff visdrone_toolkit/ scripts/ tests/ --profile=black --line-length=100 | |
| - name: Run pydocstyle (docstring check) | |
| run: | | |
| pydocstyle visdrone_toolkit/ --convention=google --add-ignore=D100,D101,D102,D103,D104,D105,D107,D212 | |
| continue-on-error: true | |
| - name: Run mypy (type checking) | |
| run: | | |
| mypy visdrone_toolkit/ --ignore-missing-imports --check-untyped-defs | |
| continue-on-error: true | |
| - name: Run Bandit (security linting) | |
| run: | | |
| bandit -r visdrone_toolkit/ -c pyproject.toml | |
| continue-on-error: true | |
| markdown-yaml-lint: | |
| name: Markdown & YAML Linting | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "18" | |
| - name: Install markdownlint-cli | |
| run: npm install -g markdownlint-cli | |
| - name: Run markdownlint | |
| run: | | |
| markdownlint '**/*.md' --disable MD013 MD033 MD041 --ignore node_modules || true | |
| continue-on-error: true | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| - name: Install yamllint | |
| run: pip install yamllint | |
| - name: Run yamllint | |
| run: | | |
| yamllint . -d "{extends: default, rules: {line-length: {max: 120}, document-start: disable}}" || true | |
| continue-on-error: true | |
| test: | |
| name: Tests (Python ${{ matrix.python-version }}) | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ["3.8", "3.9", "3.10", "3.11"] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| cache: "pip" | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libgl1 libglib2.0-0 | |
| - name: Install Python dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu | |
| pip install -e ".[dev]" | |
| - name: Run pytest with coverage | |
| run: | | |
| pytest tests/ -v --cov=visdrone_toolkit --cov-report=xml --cov-report=term | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@v4 | |
| if: matrix.python-version == '3.10' | |
| with: | |
| file: ./coverage.xml | |
| flags: unittests | |
| name: codecov-umbrella | |
| fail_ci_if_error: false | |
| env: | |
| CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | |
| integration-tests: | |
| name: Integration Tests | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| cache: "pip" | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libgl1 libglib2.0-0 | |
| python -m pip install --upgrade pip | |
| pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu | |
| pip install -e ".[dev]" | |
| - name: Test format converters | |
| run: | | |
| pytest tests/test_converters.py -v --tb=short | |
| - name: Test dataset loading | |
| run: | | |
| pytest tests/test_dataset.py -v --tb=short | |
| - name: Test model initialization | |
| run: | | |
| pytest tests/test_models.py -v --tb=short || true | |
| continue-on-error: true | |
| pre-commit: | |
| name: Pre-commit Hooks | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| cache: "pip" | |
| - name: Set up Node.js (for prettier, markdownlint) | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "18" | |
| - name: Install pre-commit | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install pre-commit | |
| - name: Cache pre-commit hooks | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/pre-commit | |
| key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }} | |
| - name: Run pre-commit on all files | |
| run: | | |
| pre-commit run --all-files --show-diff-on-failure | |
| continue-on-error: false | |
| build: | |
| name: Build Distribution | |
| runs-on: ubuntu-latest | |
| needs: [lint, test] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| - name: Install build dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install build twine | |
| - name: Build package | |
| run: | | |
| python -m build | |
| - name: Check distribution | |
| run: | | |
| twine check dist/* | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: dist-packages | |
| path: dist/ | |
| security: | |
| name: Security Scan | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install safety bandit[toml] | |
| pip install -e . | |
| - name: Run safety (dependency vulnerability check) | |
| run: | | |
| safety check --json || true | |
| continue-on-error: true | |
| - name: Run bandit (security linting) | |
| run: | | |
| bandit -r visdrone_toolkit/ -c pyproject.toml -f json -o bandit-report.json || true | |
| continue-on-error: true | |
| - name: Upload security reports | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: security-reports | |
| path: bandit-report.json | |
| shell-check: | |
| name: Shell Script Linting | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Run ShellCheck | |
| uses: ludeeus/action-shellcheck@master | |
| with: | |
| scandir: "./scripts" | |
| severity: warning | |
| continue-on-error: true | |
| docs: | |
| name: Documentation Build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install sphinx sphinx-rtd-theme | |
| pip install -e . | |
| - name: Check README | |
| run: | | |
| if [ ! -f README.md ]; then | |
| README_PATH="README.md" | |
| elif [ -f .github/README.md ]; then | |
| README_PATH=".github/README.md" | |
| else | |
| echo "README.md not found" | |
| exit 1 | |
| fi | |
| if [ $(wc -l < "$README_PATH") -lt 50 ]; then | |
| echo "README.md seems too short" | |
| exit 1 | |
| fi | |
| echo "✓ README.md found and validated" | |
| - name: Validate CHANGELOG | |
| run: | | |
| if [ -f CHANGELOG.md ]; then | |
| CHANGELOG_PATH="CHANGELOG.md" | |
| elif [ -f .github/CHANGELOG.md ]; then | |
| CHANGELOG_PATH=".github/CHANGELOG.md" | |
| else | |
| echo "CHANGELOG.md not found" | |
| exit 0 | |
| fi | |
| if [ $(wc -l < "$CHANGELOG_PATH") -gt 10 ]; then | |
| echo "✓ CHANGELOG.md found" | |
| else | |
| echo "⚠ CHANGELOG.md not found (warning only)" | |
| fi | |
| continue-on-error: true | |
| - name: Check LICENSE | |
| run: | | |
| if [ -f LICENSE ]; then | |
| echo "✓ LICENSE found" | |
| else | |
| echo "✗ LICENSE not found" | |
| exit 1 | |
| fi | |
| python-compatibility: | |
| name: Python Syntax Check (Pyupgrade) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.10" | |
| - name: Install pyupgrade | |
| run: pip install pyupgrade | |
| - name: Check Python 3.8+ syntax | |
| run: | | |
| find visdrone_toolkit/ scripts/ tests/ -name "*.py" -exec pyupgrade --py38-plus {} + | |
| continue-on-error: true | |
| summary: | |
| name: CI Summary | |
| runs-on: ubuntu-latest | |
| needs: | |
| [ | |
| lint, | |
| markdown-yaml-lint, | |
| test, | |
| integration-tests, | |
| pre-commit, | |
| build, | |
| security, | |
| shell-check, | |
| docs, | |
| python-compatibility, | |
| ] | |
| if: always() | |
| steps: | |
| - name: Check CI status | |
| run: | | |
| echo "Lint: ${{ needs.lint.result }}" | |
| echo "Markdown/YAML Lint: ${{ needs.markdown-yaml-lint.result }}" | |
| echo "Tests: ${{ needs.test.result }}" | |
| echo "Integration Tests: ${{ needs.integration-tests.result }}" | |
| echo "Pre-commit: ${{ needs.pre-commit.result }}" | |
| echo "Build: ${{ needs.build.result }}" | |
| echo "Security: ${{ needs.security.result }}" | |
| echo "Shell Check: ${{ needs.shell-check.result }}" | |
| echo "Docs: ${{ needs.docs.result }}" | |
| echo "Python Compatibility: ${{ needs.python-compatibility.result }}" | |
| - name: Fail if critical jobs failed | |
| if: | | |
| needs.lint.result == 'failure' || | |
| needs.test.result == 'failure' || | |
| needs.pre-commit.result == 'failure' || | |
| needs.build.result == 'failure' | |
| run: | | |
| echo "Critical CI checks failed" | |
| exit 1 |