# GitHub Actions CI Workflow for Ohm Streaming # Runs tests, coverage, and quality checks on push and pull requests name: CI on: push: branches: [main, dev] pull_request: branches: [main, dev] # Cancel in-progress runs when a new workflow with the same group name starts concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: # Run pytest tests with coverage test: name: Test (Python ${{ matrix.python-version }}) runs-on: ubuntu-latest timeout-minutes: 10 strategy: 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@v5 with: python-version: ${{ matrix.python-version }} cache: 'pip' cache-dependency-path: 'requirements.txt' - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt - name: Run pytest (exclude slow tests by default) run: | pytest -m "not slow" --cov=app --cov-report=term-missing --cov-report=html --no-cov-on-fail -v - name: Upload coverage reports uses: actions/upload-artifact@v4 if: success() with: name: coverage-report-${{ matrix.python-version }} path: htmlcov/ retention-days: 30 - name: Upload test logs uses: actions/upload-artifact@v4 if: failure() with: name: test-logs-${{ matrix.python-version }} path: | .pytest_cache/ *.html retention-days: 7 # Run linting with ruff lint: name: Lint runs-on: ubuntu-latest timeout-minutes: 5 steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' cache: 'pip' - name: Install ruff run: pip install ruff - name: Run ruff run: ruff check app/ --output-format=github - name: Run ruff (format check) run: ruff format --check app/ # Run type checking with mypy type-check: name: Type Check runs-on: ubuntu-latest timeout-minutes: 10 steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' cache: 'pip' - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt pip install mypy types-requests types-aiohttp types-python-jose - name: Run mypy run: | mypy app/ --ignore-missing-imports --no-error-summary # Summary job - runs after all other jobs summary: name: Summary runs-on: ubuntu-latest timeout-minutes: 2 needs: [test, lint, type-check] steps: - name: Create summary run: | echo "## CI Results" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY # Test results echo "### Tests" >> $GITHUB_STEP_SUMMARY if [ "${{ needs.test.result }}" = "success" ]; then echo "✅ Tests passed for Python 3.11 and 3.12" >> $GITHUB_STEP_SUMMARY else echo "❌ Tests failed" >> $GITHUB_STEP_SUMMARY fi echo "" >> $GITHUB_STEP_SUMMARY # Lint results echo "### Linting" >> $GITHUB_STEP_SUMMARY if [ "${{ needs.lint.result }}" = "success" ]; then echo "✅ Linting passed" >> $GITHUB_STEP_SUMMARY else echo "❌ Linting failed" >> $GITHUB_STEP_SUMMARY fi echo "" >> $GITHUB_STEP_SUMMARY # Type check results echo "### Type Checking" >> $GITHUB_STEP_SUMMARY if [ "${{ needs.type-check.result }}" = "success" ]; then echo "✅ Type checking passed" >> $GITHUB_STEP_SUMMARY else echo "⚠️ Type checking had issues" >> $GITHUB_STEP_SUMMARY fi