Skip to content

CI/CD

CI/CD #20

Workflow file for this run

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