name: StreamFlow CI/CD on: push: branches: [main, develop] pull_request: branches: [main] env: PYTHON_VERSION: "3.11" JAVA_VERSION: "21" jobs: # ==================== # Backend Tests # ==================== backend-test: name: Backend Tests 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 }} cache: 'pip' cache-dependency-path: backend/requirements.txt - name: Install dependencies run: | cd backend pip install -r requirements.txt pip install pytest pytest-asyncio pytest-cov httpx - name: Run tests run: | cd backend python -m pytest tests/ -v --cov=. --cov-report=xml env: STREAMFLIX_DEBUG: true - name: Upload coverage uses: codecov/codecov-action@v3 with: files: backend/coverage.xml fail_ci_if_error: false # ==================== # Backend Lint # ==================== backend-lint: name: Backend Lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} - name: Install linters run: pip install ruff mypy - name: Run ruff run: ruff check backend/ --ignore=E501 - name: Run mypy run: mypy backend/ --ignore-missing-imports || true # ==================== # Android TV Build # ==================== android-build: name: Android TV Build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up JDK uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: ${{ env.JAVA_VERSION }} cache: 'gradle' - name: Grant execute permission run: chmod +x android-tv/gradlew - name: Build Debug APK run: | cd android-tv ./gradlew assembleDebug --no-daemon - name: Upload APK uses: actions/upload-artifact@v4 with: name: android-tv-debug path: android-tv/app/build/outputs/apk/debug/*.apk retention-days: 7 # ==================== # Android Mobile Build # ==================== mobile-build: name: Android Mobile Build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up JDK uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: ${{ env.JAVA_VERSION }} cache: 'gradle' - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm' cache-dependency-path: frontend/package-lock.json - name: Install dependencies run: | cd frontend npm install - name: Build Web App run: | cd frontend npm run build - name: Sync Capacitor run: | cd frontend npx cap sync android - name: Grant execute permission run: chmod +x frontend/android/gradlew - name: Build Mobile APK run: | cd frontend/android ./gradlew assembleDebug --no-daemon - name: Upload APK uses: actions/upload-artifact@v4 with: name: android-mobile-debug path: frontend/android/app/build/outputs/apk/debug/*.apk retention-days: 7 # ==================== # Docker Build # ==================== docker-build: name: Docker Build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build Docker image uses: docker/build-push-action@v5 with: context: . push: false load: true tags: streamflix:test cache-from: type=gha cache-to: type=gha,mode=max - name: Test Docker image run: | docker run -d --name test -p 8000:8000 \ -e STREAMFLIX_DEBUG=true \ -e STREAMFLIX_SECRET_KEY=sf_tv_secure_9s8d7f6g5h4j3k2l1 \ streamflix:test sleep 10 curl -f http://localhost:8000/api/health || exit 1 docker stop test # ==================== # Docker Publish (on main only) # ==================== docker-publish: name: Docker Publish runs-on: ubuntu-latest needs: [docker-build] if: github.ref == 'refs/heads/main' && github.event_name == 'push' steps: - uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to DockerHub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Extract version id: version run: echo "version=$(cat backend/config.py | grep 'app_version' | cut -d'"' -f2)" >> $GITHUB_OUTPUT - name: Build and push uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64 push: true tags: | ${{ secrets.DOCKERHUB_USERNAME }}/streamflix:latest ${{ secrets.DOCKERHUB_USERNAME }}/streamflix:${{ steps.version.outputs.version }} cache-from: type=gha cache-to: type=gha,mode=max