name: CI on: push: branches: [main, develop] pull_request: branches: [main, develop] jobs: # ============================================================================= # Backend Tests - PHP 8.5, PHPStan, PHPUnit # ============================================================================= test-backend: name: Backend Tests runs-on: ubuntu-latest defaults: run: working-directory: backend services: postgres: image: postgres:18.1-alpine env: POSTGRES_DB: classeo_test POSTGRES_USER: classeo POSTGRES_PASSWORD: classeo ports: - 5432:5432 options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 redis: image: redis:7.4-alpine ports: - 6379:6379 options: >- --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5 steps: - uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: '8.5' extensions: intl, pdo_pgsql, amqp, redis, zip coverage: xdebug - name: Get Composer cache directory id: composer-cache run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - name: Cache Composer dependencies uses: actions/cache@v4 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} restore-keys: ${{ runner.os }}-composer- - name: Install dependencies run: composer install --prefer-dist --no-progress - name: Run PHP CS Fixer (check) run: composer cs-check - name: Run PHPStan run: composer phpstan - name: Run PHPUnit run: composer test env: DATABASE_URL: postgresql://classeo:classeo@localhost:5432/classeo_test?serverVersion=18 REDIS_URL: redis://localhost:6379 - name: Run BC Isolation Check working-directory: . run: ./scripts/check-bc-isolation.sh # ============================================================================= # Frontend Tests - Vitest, Playwright # ============================================================================= test-frontend: name: Frontend Tests runs-on: ubuntu-latest defaults: run: working-directory: frontend steps: - uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '22' - name: Setup pnpm uses: pnpm/action-setup@v3 with: version: 9 - name: Get pnpm store directory id: pnpm-cache run: echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT - name: Cache pnpm dependencies uses: actions/cache@v4 with: path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: ${{ runner.os }}-pnpm-store- - name: Install dependencies run: pnpm install --frozen-lockfile - name: Run linter run: pnpm run lint - name: Run TypeScript check run: pnpm run check - name: Run unit tests run: pnpm run test - name: Install Playwright browsers run: pnpm exec playwright install --with-deps - name: Run E2E tests run: pnpm run test:e2e - name: Upload Playwright report uses: actions/upload-artifact@v4 if: failure() with: name: playwright-report path: frontend/playwright-report/ retention-days: 7 # ============================================================================= # Naming Conventions Check # ============================================================================= check-naming: name: Naming Conventions runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run Naming Check run: ./scripts/check-naming.sh # ============================================================================= # Build Check # ============================================================================= build: name: Build Check runs-on: ubuntu-latest needs: [test-backend, test-frontend] steps: - uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build backend image uses: docker/build-push-action@v6 with: context: ./backend push: false cache-from: type=gha cache-to: type=gha,mode=max - name: Build frontend image uses: docker/build-push-action@v6 with: context: ./frontend push: false cache-from: type=gha cache-to: type=gha,mode=max