PR CI #85
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: PR CI | |
| on: | |
| pull_request: | |
| branches: | |
| - main | |
| paths-ignore: | |
| - '**.md' | |
| - 'docs/**' | |
| - '.gitignore' | |
| - 'LICENSE' | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # Stage 1: Fast Unit Tests (Parallel) | |
| backend-unit-tests: | |
| name: Backend Unit Tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Java 25 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '25' | |
| distribution: 'temurin' | |
| cache: 'maven' | |
| - name: Cache Maven dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.m2/repository | |
| key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-maven- | |
| - name: Run backend unit tests | |
| run: ./mvnw -pl backend clean test | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: backend-unit-test-results | |
| path: backend/target/surefire-reports/ | |
| retention-days: 7 | |
| backend-integration-tests: | |
| name: Backend Integration Tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| services: | |
| postgres: | |
| image: postgis/postgis:17-3.5 | |
| env: | |
| POSTGRES_DB: geopulse_test | |
| POSTGRES_USER: geopulse_test | |
| POSTGRES_PASSWORD: testpass | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd "pg_isready -U geopulse_test -d geopulse_test" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Java 25 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '25' | |
| distribution: 'temurin' | |
| cache: 'maven' | |
| - name: Cache Maven dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.m2/repository | |
| key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-maven- | |
| - name: Compile integration test classes | |
| run: ./mvnw -pl backend -DskipITs=false test-compile | |
| env: | |
| QUARKUS_DATASOURCE_JDBC_URL: jdbc:postgresql://localhost:5432/geopulse_test | |
| QUARKUS_DATASOURCE_USERNAME: geopulse_test | |
| QUARKUS_DATASOURCE_PASSWORD: testpass | |
| - name: Run backend integration tests | |
| run: ./mvnw -pl backend -DskipITs=false failsafe:integration-test failsafe:verify | |
| env: | |
| QUARKUS_DATASOURCE_JDBC_URL: jdbc:postgresql://localhost:5432/geopulse_test | |
| QUARKUS_DATASOURCE_USERNAME: geopulse_test | |
| QUARKUS_DATASOURCE_PASSWORD: testpass | |
| - name: Upload integration test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: backend-integration-test-results | |
| path: backend/target/failsafe-reports/ | |
| retention-days: 7 | |
| frontend-unit-tests: | |
| name: Frontend Unit Tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - 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 ci | |
| - name: Run frontend unit tests | |
| run: | | |
| cd frontend | |
| npm run test:run -- --passWithNoTests | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: frontend-test-results | |
| path: frontend/coverage/ | |
| retention-days: 7 | |
| code-quality: | |
| name: Code Quality (PMD) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| continue-on-error: true # Non-blocking | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Java 25 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '25' | |
| distribution: 'temurin' | |
| cache: 'maven' | |
| - name: Run PMD analysis | |
| run: ./mvnw -pl backend pmd:check | |
| - name: Show PMD violations | |
| if: always() | |
| run: | | |
| if [ -f backend/target/pmd.xml ]; then | |
| echo "=== PMD Violations ===" | |
| cat backend/target/pmd.xml | |
| fi | |
| - name: Upload PMD report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: pmd-report | |
| path: backend/target/pmd.xml | |
| retention-days: 7 | |
| # Stage 2: Smoke E2E Tests | |
| smoke-e2e-tests: | |
| name: Smoke E2E Tests | |
| runs-on: ubuntu-latest | |
| needs: [backend-unit-tests, backend-integration-tests, frontend-unit-tests] | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Start E2E environment | |
| run: | | |
| docker compose -f tests/docker-compose.e2e.yml up -d geopulse-postgres-e2e geopulse-backend-e2e geopulse-ui-e2e | |
| - name: Wait for services to be healthy | |
| run: | | |
| echo "Waiting for backend to be ready..." | |
| timeout 120 bash -c 'until curl -f http://localhost:8081/api/health; do echo "Waiting..."; sleep 5; done' | |
| echo "Waiting for frontend to be ready..." | |
| timeout 60 bash -c 'until curl -f http://localhost:5556; do echo "Waiting..."; sleep 5; done' | |
| echo "All services are ready!" | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| cache-dependency-path: tests/package-lock.json | |
| - name: Install Playwright dependencies | |
| run: | | |
| cd tests | |
| npm ci | |
| npx playwright install --with-deps chromium | |
| - name: Run smoke E2E tests | |
| run: | | |
| cd tests | |
| npx playwright test \ | |
| e2e/authentication.spec.js \ | |
| e2e/health.spec.js \ | |
| e2e/user-registration.spec.js \ | |
| e2e/error-handling.spec.js | |
| env: | |
| BASE_URL: http://localhost:5556 | |
| PLAYWRIGHT_WORKERS: 4 | |
| CI: true | |
| - name: Upload Playwright report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: playwright-smoke-report | |
| path: tests/playwright-report/ | |
| retention-days: 7 | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: playwright-smoke-results | |
| path: tests/test-results/ | |
| retention-days: 7 | |
| - name: Show environment logs on failure | |
| if: failure() | |
| run: | | |
| echo "=== Backend logs ===" | |
| docker logs geopulse-backend-e2e || true | |
| echo "=== Frontend logs ===" | |
| docker logs geopulse-ui-e2e || true | |
| echo "=== Database logs ===" | |
| docker logs geopulse-postgres-e2e || true | |
| - name: Cleanup | |
| if: always() | |
| run: | | |
| docker compose -f tests/docker-compose.e2e.yml down -v || echo "Cleanup failed but continuing" | |
| docker system prune -f || true | |
| # Summary job - required for branch protection | |
| pr-ci-summary: | |
| name: PR CI Summary | |
| runs-on: ubuntu-latest | |
| needs: [backend-unit-tests, backend-integration-tests, frontend-unit-tests, smoke-e2e-tests] | |
| if: always() | |
| steps: | |
| - name: Check all jobs status | |
| run: | | |
| if [[ "${{ needs.backend-unit-tests.result }}" != "success" ]] || \ | |
| [[ "${{ needs.backend-integration-tests.result }}" != "success" ]] || \ | |
| [[ "${{ needs.frontend-unit-tests.result }}" != "success" ]] || \ | |
| [[ "${{ needs.smoke-e2e-tests.result }}" != "success" ]]; then | |
| echo "❌ PR CI failed. Check the logs above for details." | |
| exit 1 | |
| fi | |
| echo "✅ All PR CI checks passed!" |