CI/CD #20
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: Core CI | |
| on: | |
| push: | |
| branches: [ main, develop ] | |
| pull_request: | |
| branches: [ main, develop ] | |
| workflow_dispatch: | |
| env: | |
| PYTHONUNBUFFERED: 1 | |
| FORCE_COLOR: 1 | |
| jobs: | |
| unit-tests: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ["3.11", "3.12"] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y ffmpeg portaudio19-dev | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| with: | |
| version: "latest" | |
| - name: Install Python dependencies | |
| run: | | |
| uv sync --extra dev --extra test | |
| uv add pytest-xdist pytest-timeout pytest-cov | |
| - name: Run unit tests | |
| run: | | |
| uv run python -m pytest tests/unit/ \ | |
| -v \ | |
| --tb=short \ | |
| --cov=marvis \ | |
| --cov-report=xml \ | |
| --cov-report=html \ | |
| -m "not gpu and not api and not vlm and not ci_skip" \ | |
| --maxfail=5 \ | |
| --timeout=60 \ | |
| --benchmark-disable \ | |
| -n auto | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@v3 | |
| if: matrix.python-version == '3.11' | |
| with: | |
| file: ./coverage.xml | |
| flags: unit-tests | |
| name: codecov-umbrella | |
| integration-tests: | |
| runs-on: ubuntu-latest | |
| needs: unit-tests | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.11' | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y ffmpeg portaudio19-dev | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| with: | |
| version: "latest" | |
| - name: Install Python dependencies | |
| run: | | |
| uv sync --extra dev --extra test --extra audio --extra vision | |
| uv add pytest-xdist pytest-timeout | |
| - name: Run integration tests | |
| run: | | |
| uv run python -m pytest tests/integration/ \ | |
| -v \ | |
| --tb=short \ | |
| -m "not gpu and not api and not vlm and not slow and not ci_skip" \ | |
| --maxfail=3 \ | |
| --timeout=300 \ | |
| --benchmark-disable \ | |
| -n 2 | |
| e2e-tests: | |
| runs-on: ubuntu-latest | |
| needs: [unit-tests, integration-tests] | |
| if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && contains(github.event.head_commit.message, '[run-e2e]')) | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.11' | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y ffmpeg portaudio19-dev | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| with: | |
| version: "latest" | |
| - name: Install Python dependencies | |
| run: | | |
| uv sync --extra dev --extra test --extra audio --extra vision | |
| uv add pytest-xdist pytest-timeout | |
| - name: Run E2E tests | |
| run: | | |
| uv run python -m pytest tests/e2e/ \ | |
| -v \ | |
| --tb=short \ | |
| -m "not gpu and not api and not vlm and not very_slow and not ci_skip" \ | |
| --maxfail=1 \ | |
| --timeout=600 \ | |
| --benchmark-disable \ | |
| -x | |
| lint-and-format: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.11' | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| with: | |
| version: "latest" | |
| - name: Install dependencies | |
| run: | | |
| uv sync --extra dev | |
| - name: Run Black formatter check | |
| run: | | |
| uv run black --check --diff marvis/ tests/ examples/ | |
| - name: Run Ruff linter | |
| run: | | |
| uv run ruff check --select=E9,F63,F7,F82 marvis/ tests/ examples/ | |
| - name: Run MyPy type checker | |
| run: | | |
| uv run mypy marvis/ --ignore-missing-imports | |
| continue-on-error: true # Type checking errors shouldn't fail CI | |
| - name: Check import sorting | |
| run: | | |
| uv add isort | |
| uv run isort --check-only --diff marvis/ tests/ | |
| continue-on-error: true | |
| security-scan: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Run Bandit security linter | |
| uses: PyCQA/bandit-action@v1 | |
| with: | |
| path: marvis/ | |
| dependency-check: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.11' | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| with: | |
| version: "latest" | |
| - name: Install dependencies | |
| run: | | |
| uv sync --extra dev | |
| uv add safety pip-audit | |
| - name: Run Safety check | |
| run: | | |
| safety check --json --output safety-report.json | |
| continue-on-error: true | |
| - name: Run pip-audit | |
| run: | | |
| pip-audit --format=json --output=audit-report.json | |
| continue-on-error: true | |
| build-test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.11' | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| with: | |
| version: "latest" | |
| - name: Install build dependencies | |
| run: | | |
| uv add build twine | |
| - name: Build package | |
| run: | | |
| uv run python -m build | |
| - name: Check package | |
| run: | | |
| uv run twine check dist/* | |
| - name: Test installation | |
| run: | | |
| # Create a temporary virtual environment to test the wheel installation | |
| python -m venv test_env | |
| source test_env/bin/activate | |
| pip install dist/*.whl | |
| python -c "import marvis; print('✓ Package installed successfully')" | |
| docs-check: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.11' | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| with: | |
| version: "latest" | |
| - name: Install dependencies | |
| run: | | |
| # Install docs dependencies and core project | |
| uv sync --extra docs | |
| - name: Build documentation | |
| run: | | |
| cd docs/ | |
| # Clean any existing build artifacts | |
| rm -rf _build/ || true | |
| # Build with verbose output but don't fail on warnings | |
| uv run sphinx-build --keep-going -b html . _build/html | |
| continue-on-error: true # Docs errors shouldn't fail CI | |
| env: | |
| CUDA_VISIBLE_DEVICES: "" | |
| VLLM_AVAILABLE: false | |
| MARVIS_DOCS_BUILD: true | |
| - name: Check documentation links | |
| run: | | |
| cd docs/ | |
| uv run sphinx-build -b linkcheck . _build/linkcheck | |
| continue-on-error: true | |
| test-summary: | |
| runs-on: ubuntu-latest | |
| needs: [unit-tests, integration-tests, lint-and-format, security-scan, dependency-check, build-test] | |
| if: always() | |
| steps: | |
| - name: Test Results Summary | |
| run: | | |
| echo "## CI Results Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "| Job | Status |" >> $GITHUB_STEP_SUMMARY | |
| echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY | |
| echo "| Unit Tests | ${{ needs.unit-tests.result }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Integration Tests | ${{ needs.integration-tests.result }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Lint and Format | ${{ needs.lint-and-format.result }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Security Scan | ${{ needs.security-scan.result }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Dependency Check | ${{ needs.dependency-check.result }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Build Test | ${{ needs.build-test.result }} |" >> $GITHUB_STEP_SUMMARY | |
| # Fail if critical jobs failed | |
| if [[ "${{ needs.unit-tests.result }}" == "failure" || "${{ needs.integration-tests.result }}" == "failure" ]]; then | |
| echo "Critical tests failed!" | |
| exit 1 | |
| fi |