name: Readiness Gate on: push: branches: [main, develop] pull_request: branches: [main, develop] workflow_dispatch: jobs: # =========================================== # BACKEND QUALITY GATES # =========================================== backend-lint: name: Backend Lint & Type Check runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: submodules: recursive - name: Install system dependencies run: sudo apt-get update && sudo apt-get install -y libev-dev - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' cache: 'pip' - name: Install dev dependencies run: | python -m pip install --upgrade pip pip install ruff mypy pytest - name: Run ruff linting run: ruff check src/swingmusic --output-format=github - name: Run ruff format check run: ruff format --check src/swingmusic backend-tests: name: Backend Tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: submodules: recursive - name: Install system dependencies run: sudo apt-get update && sudo apt-get install -y libev-dev - 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 -e . pip install pytest pytest-cov - name: Run tests with coverage run: python -m pytest tests/ -v --tb=short --cov=src/swingmusic --cov-report=xml --cov-report=term-missing - name: Upload coverage uses: codecov/codecov-action@v5 with: files: ./coverage.xml fail_ci_if_error: false backend-startup: name: Backend Startup Check runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: submodules: recursive - name: Install system dependencies run: sudo apt-get update && sudo apt-get install -y libev-dev - 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 -e . - name: Check backend startup run: python -c "from swingmusic.app_builder import build; app = build(); print('Backend OK')" mobile: name: Mobile (Flutter) runs-on: ubuntu-latest defaults: run: working-directory: swingmusic_mobile steps: - uses: actions/checkout@v6 with: submodules: recursive - name: Set up Flutter uses: subosito/flutter-action@v2 with: flutter-version: '3.24.0' channel: 'stable' - name: Get dependencies run: flutter pub get - name: Analyze run: flutter analyze --no-fatal-infos - name: Build APK (debug) run: flutter build apk --debug --target-platform android-arm64 web: name: Web Client runs-on: ubuntu-latest defaults: run: working-directory: swingmusic-webclient steps: - uses: actions/checkout@v6 with: submodules: recursive - name: Set up Node.js uses: actions/setup-node@v6 with: node-version: '20' cache: 'npm' cache-dependency-path: swingmusic-webclient/package-lock.json - name: Install dependencies run: npm ci || npm install - name: TypeScript type check run: npx tsc --noEmit - name: Lint run: npm run lint - name: Build run: npm run build desktop: name: Desktop Client runs-on: ubuntu-latest defaults: run: working-directory: swingmusic-desktop steps: - uses: actions/checkout@v6 with: submodules: recursive - name: Set up Node.js uses: actions/setup-node@v6 with: node-version: '20' cache: 'npm' cache-dependency-path: swingmusic-desktop/package-lock.json - name: Install dependencies run: npm ci || npm install - name: Build check run: npm run build readiness-gate: name: Readiness Gate Summary runs-on: ubuntu-latest needs: [backend-lint, backend-tests, backend-startup, mobile, web, desktop] if: always() steps: - uses: actions/checkout@v6 with: submodules: recursive - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Run readiness gate script run: | chmod +x scripts/readiness_gate.sh ./scripts/readiness_gate.sh - name: Check overall status run: | if [ "${{ needs.backend-lint.result }}" == "success" ] && \ [ "${{ needs.backend-tests.result }}" == "success" ] && \ [ "${{ needs.backend-startup.result }}" == "success" ] && \ [ "${{ needs.mobile.result }}" == "success" ] && \ [ "${{ needs.web.result }}" == "success" ] && \ [ "${{ needs.desktop.result }}" == "success" ]; then echo "✅ All platform checks passed" exit 0 else echo "❌ Some platform checks failed" exit 1 fi