name: Backend Tests on: push: branches: [ main, develop ] paths: - 'backend/**' - '.github/workflows/backend-tests.yml' pull_request: branches: [ main, develop ] paths: - 'backend/**' - '.github/workflows/backend-tests.yml' jobs: test: runs-on: ubuntu-latest strategy: matrix: python-version: ['3.10', '3.11', '3.12'] services: postgres: image: postgres:15 env: POSTGRES_USER: test_user POSTGRES_PASSWORD: test_password POSTGRES_DB: test_db options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 ports: - 5432:5432 redis: image: redis:7-alpine options: >- --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5 ports: - 6379:6379 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 }} cache: 'pip' cache-dependency-path: 'backend/requirements/*.txt' - name: Install dependencies working-directory: ./backend run: | python -m pip install --upgrade pip pip install -r requirements/base.txt pip install -r requirements/dev.txt - name: Lint with flake8 (if installed) working-directory: ./backend run: | pip install flake8 # Stop the build if there are Python syntax errors or undefined names flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics # Exit-zero treats all errors as warnings flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics continue-on-error: true - name: Run tests with pytest working-directory: ./backend env: DATABASE_URL: postgresql://test_user:test_password@localhost:5432/test_db CELERY_BROKER_URL: redis://localhost:6379/0 CELERY_RESULT_BACKEND: redis://localhost:6379/0 SECRET_KEY: test-secret-key JWT_SECRET_KEY: test-jwt-secret-key FLASK_ENV: testing run: | pytest --cov=app --cov-report=xml --cov-report=html --cov-report=term - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 with: file: ./backend/coverage.xml flags: backend name: codecov-umbrella fail_ci_if_error: false - name: Upload coverage HTML as artifact uses: actions/upload-artifact@v3 with: name: coverage-report-python-${{ matrix.python-version }} path: backend/htmlcov/ retention-days: 7 - name: Check coverage thresholds working-directory: ./backend run: | coverage report --fail-under=80 security-scan: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.11' - name: Install dependencies working-directory: ./backend run: | python -m pip install --upgrade pip pip install bandit safety - name: Run Bandit security linter working-directory: ./backend run: | bandit -r app -f json -o bandit-report.json || true continue-on-error: true - name: Check for known security vulnerabilities working-directory: ./backend run: | safety check --json --output safety-report.json || true continue-on-error: true - name: Upload security reports uses: actions/upload-artifact@v3 with: name: security-reports path: | backend/bandit-report.json backend/safety-report.json