312 lines
No EOL
7.8 KiB
YAML
312 lines
No EOL
7.8 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [ main, develop ]
|
|
pull_request:
|
|
branches: [ main, develop ]
|
|
|
|
env:
|
|
PYTHON_VERSION: "3.11"
|
|
NODE_VERSION: "20"
|
|
|
|
jobs:
|
|
backend-lint-and-test:
|
|
name: Backend Lint & Test
|
|
runs-on: ubuntu-latest
|
|
|
|
services:
|
|
mongodb:
|
|
image: mongo:7.0
|
|
ports:
|
|
- 27017:27017
|
|
options: >-
|
|
--health-cmd "echo 'db.runCommand("ping").ok' | mongosh --quiet"
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
ports:
|
|
- 6379:6379
|
|
options: >-
|
|
--health-cmd "redis-cli ping"
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
|
|
- name: Install Poetry
|
|
uses: snok/install-poetry@v1
|
|
with:
|
|
version: latest
|
|
virtualenvs-create: true
|
|
virtualenvs-in-project: true
|
|
|
|
- name: Load cached dependencies
|
|
id: cached-poetry-dependencies
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: backend/.venv
|
|
key: poetry-${{ runner.os }}-${{ env.PYTHON_VERSION }}-${{ hashFiles('backend/poetry.lock') }}
|
|
|
|
- name: Install dependencies
|
|
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
|
|
working-directory: ./backend
|
|
run: poetry install --no-interaction --no-root
|
|
|
|
- name: Install project
|
|
working-directory: ./backend
|
|
run: poetry install --no-interaction
|
|
|
|
- name: Run linting (ruff)
|
|
working-directory: ./backend
|
|
run: poetry run ruff check .
|
|
|
|
- name: Run type checking (mypy)
|
|
working-directory: ./backend
|
|
run: poetry run mypy .
|
|
|
|
- name: Run unit tests
|
|
working-directory: ./backend
|
|
env:
|
|
MONGODB_URI: mongodb://localhost:27017
|
|
MONGODB_DB: test_accessible_video
|
|
REDIS_URL: redis://localhost:6379
|
|
JWT_SECRET: test_jwt_secret_for_ci
|
|
GEMINI_API_KEY: fake_key_for_testing
|
|
GCP_PROJECT_ID: test-project
|
|
GCS_BUCKET: test-bucket
|
|
SENDGRID_API_KEY: fake_sendgrid_key
|
|
EMAIL_FROM: test@example.com
|
|
CLIENT_BASE_URL: http://localhost:3000
|
|
run: |
|
|
poetry run pytest tests/unit/ -v --cov=app --cov-report=xml --cov-report=term-missing
|
|
|
|
- name: Upload coverage to Codecov
|
|
uses: codecov/codecov-action@v4
|
|
with:
|
|
file: ./backend/coverage.xml
|
|
flags: backend
|
|
name: backend-coverage
|
|
|
|
frontend-lint-and-test:
|
|
name: Frontend Lint & Test
|
|
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: ${{ env.NODE_VERSION }}
|
|
cache: 'npm'
|
|
cache-dependency-path: frontend/package-lock.json
|
|
|
|
- name: Install dependencies
|
|
working-directory: ./frontend
|
|
run: npm ci
|
|
|
|
- name: Run linting (ESLint)
|
|
working-directory: ./frontend
|
|
run: npm run lint
|
|
|
|
- name: Run type checking (TypeScript)
|
|
working-directory: ./frontend
|
|
run: npm run type-check
|
|
|
|
- name: Run unit tests (Vitest)
|
|
working-directory: ./frontend
|
|
run: npm run test -- --coverage --reporter=verbose
|
|
|
|
- name: Upload coverage to Codecov
|
|
uses: codecov/codecov-action@v4
|
|
with:
|
|
file: ./frontend/coverage/lcov.info
|
|
flags: frontend
|
|
name: frontend-coverage
|
|
|
|
integration-tests:
|
|
name: Integration Tests
|
|
runs-on: ubuntu-latest
|
|
needs: [backend-lint-and-test, frontend-lint-and-test]
|
|
|
|
services:
|
|
mongodb:
|
|
image: mongo:7.0
|
|
ports:
|
|
- 27017:27017
|
|
options: >-
|
|
--health-cmd "echo 'db.runCommand("ping").ok' | mongosh --quiet"
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
ports:
|
|
- 6379:6379
|
|
options: >-
|
|
--health-cmd "redis-cli ping"
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
|
|
- name: Install Poetry
|
|
uses: snok/install-poetry@v1
|
|
|
|
- name: Install backend dependencies
|
|
working-directory: ./backend
|
|
run: poetry install
|
|
|
|
- name: Run integration tests
|
|
working-directory: ./backend
|
|
env:
|
|
MONGODB_URI: mongodb://localhost:27017
|
|
MONGODB_DB: test_accessible_video_integration
|
|
REDIS_URL: redis://localhost:6379
|
|
JWT_SECRET: test_jwt_secret_for_integration
|
|
GEMINI_API_KEY: fake_key_for_testing
|
|
GCP_PROJECT_ID: test-project
|
|
GCS_BUCKET: test-bucket
|
|
SENDGRID_API_KEY: fake_sendgrid_key
|
|
EMAIL_FROM: test@example.com
|
|
CLIENT_BASE_URL: http://localhost:3000
|
|
run: |
|
|
poetry run pytest tests/integration/ -v
|
|
|
|
build-backend:
|
|
name: Build Backend Docker Image
|
|
runs-on: ubuntu-latest
|
|
needs: [backend-lint-and-test]
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
|
|
- name: Build backend image
|
|
uses: docker/build-push-action@v5
|
|
with:
|
|
context: ./backend
|
|
file: ./backend/Dockerfile
|
|
push: false
|
|
tags: accessible-video-backend:${{ github.sha }}
|
|
cache-from: type=gha
|
|
cache-to: type=gha,mode=max
|
|
|
|
build-frontend:
|
|
name: Build Frontend
|
|
runs-on: ubuntu-latest
|
|
needs: [frontend-lint-and-test]
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: ${{ env.NODE_VERSION }}
|
|
cache: 'npm'
|
|
cache-dependency-path: frontend/package-lock.json
|
|
|
|
- name: Install dependencies
|
|
working-directory: ./frontend
|
|
run: npm ci
|
|
|
|
- name: Build for production
|
|
working-directory: ./frontend
|
|
env:
|
|
VITE_API_BASE_URL: https://api.example.com # Placeholder for production
|
|
VITE_APP_ENV: production
|
|
run: npm run build
|
|
|
|
- name: Upload build artifacts
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: frontend-dist
|
|
path: frontend/dist/
|
|
retention-days: 7
|
|
|
|
security-scan:
|
|
name: Security Scan
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Run Trivy vulnerability scanner
|
|
uses: aquasecurity/trivy-action@master
|
|
with:
|
|
scan-type: 'fs'
|
|
scan-ref: '.'
|
|
format: 'sarif'
|
|
output: 'trivy-results.sarif'
|
|
|
|
- name: Upload Trivy scan results
|
|
uses: github/codeql-action/upload-sarif@v3
|
|
with:
|
|
sarif_file: 'trivy-results.sarif'
|
|
|
|
- name: Run Semgrep security scan
|
|
uses: semgrep/semgrep-action@v1
|
|
with:
|
|
config: auto
|
|
generateBaseline: false
|
|
|
|
dependency-check:
|
|
name: Dependency Check
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
|
|
- name: Install Poetry
|
|
uses: snok/install-poetry@v1
|
|
|
|
- name: Check backend dependencies
|
|
working-directory: ./backend
|
|
run: |
|
|
poetry check
|
|
poetry run pip-audit
|
|
|
|
- name: Set up Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: ${{ env.NODE_VERSION }}
|
|
|
|
- name: Check frontend dependencies
|
|
working-directory: ./frontend
|
|
run: |
|
|
npm audit --audit-level moderate
|
|
npx better-npm-audit audit |