diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 6312edd..2f47959 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -120,13 +120,143 @@ jobs: run: sccache --show-stats if: always() + # --------------------------------------------------------------------------- + # Stage 2b: E2E tests (only on main / PRs to main, after quality checks) + # --------------------------------------------------------------------------- + e2e: + name: E2E Tests + runs-on: docker + needs: [fmt, clippy, audit] + if: github.ref == 'refs/heads/main' || github.event_name == 'pull_request' + container: + image: rust:1.89-bookworm + # MongoDB and SearXNG can start immediately (no repo files needed). + # Keycloak requires realm-export.json from the repo, so it is started + # manually after checkout via docker CLI. + services: + mongo: + image: mongo:latest + env: + MONGO_INITDB_ROOT_USERNAME: root + MONGO_INITDB_ROOT_PASSWORD: example + ports: + - 27017:27017 + searxng: + image: searxng/searxng:latest + env: + SEARXNG_BASE_URL: http://localhost:8888 + ports: + - 8888:8080 + env: + KEYCLOAK_URL: http://localhost:8080 + KEYCLOAK_REALM: certifai + KEYCLOAK_CLIENT_ID: certifai-dashboard + MONGODB_URI: mongodb://root:example@mongo:27017 + MONGODB_DATABASE: certifai + SEARXNG_URL: http://searxng:8080 + steps: + - name: Checkout + run: | + git init + git remote add origin "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git" + git fetch --depth=1 origin "${GITHUB_SHA}" + git checkout FETCH_HEAD + - name: Install system dependencies + run: | + apt-get update -qq + apt-get install -y -qq --no-install-recommends \ + unzip curl docker.io \ + libglib2.0-0 libnss3 libnspr4 libdbus-1-3 libatk1.0-0 \ + libatk-bridge2.0-0 libcups2 libdrm2 libxkbcommon0 libxcomposite1 \ + libxdamage1 libxfixes3 libxrandr2 libgbm1 libpango-1.0-0 \ + libcairo2 libasound2 libatspi2.0-0 libxshmfence1 + - name: Start Keycloak + run: | + docker run -d --name ci-keycloak --network host \ + -e KC_BOOTSTRAP_ADMIN_USERNAME=admin \ + -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \ + -e KC_DB=dev-mem \ + -e KC_HEALTH_ENABLED=true \ + -v "$PWD/keycloak/realm-export.json:/opt/keycloak/data/import/realm-export.json:ro" \ + -v "$PWD/keycloak/themes/certifai:/opt/keycloak/themes/certifai:ro" \ + quay.io/keycloak/keycloak:26.0 start-dev --import-realm + + echo "Waiting for Keycloak..." + for i in $(seq 1 60); do + if curl -sf http://localhost:8080/realms/certifai > /dev/null 2>&1; then + echo "Keycloak is ready" + break + fi + if [ "$i" -eq 60 ]; then + echo "Keycloak failed to start within 60s" + docker logs ci-keycloak + exit 1 + fi + sleep 2 + done + - name: Install sccache + run: | + curl -fsSL https://github.com/mozilla/sccache/releases/download/v0.9.1/sccache-v0.9.1-x86_64-unknown-linux-musl.tar.gz \ + | tar xz --strip-components=1 -C /usr/local/bin/ sccache-v0.9.1-x86_64-unknown-linux-musl/sccache + chmod +x /usr/local/bin/sccache + - name: Install dioxus-cli + run: cargo install dioxus-cli --locked + - name: Install bun + run: | + curl -fsSL https://bun.sh/install | bash + echo "$HOME/.bun/bin" >> "$GITHUB_PATH" + - name: Install Playwright + run: | + export PATH="$HOME/.bun/bin:$PATH" + bun install + bunx playwright install chromium + - name: Build app + run: dx build --release + - name: Start app and run E2E tests + run: | + export PATH="$HOME/.bun/bin:$PATH" + # Start the app in the background + dx serve --release --port 8000 & + APP_PID=$! + + # Wait for the app to be ready + echo "Waiting for app to start..." + for i in $(seq 1 60); do + if curl -sf http://localhost:8000 > /dev/null 2>&1; then + echo "App is ready" + break + fi + if [ "$i" -eq 60 ]; then + echo "App failed to start within 60s" + exit 1 + fi + sleep 1 + done + + BASE_URL=http://localhost:8000 bunx playwright test --reporter=list + + kill "$APP_PID" 2>/dev/null || true + - name: Upload test report + if: always() + uses: actions/upload-artifact@v4 + with: + name: playwright-report + path: playwright-report/ + retention-days: 7 + - name: Cleanup Keycloak + if: always() + run: docker rm -f ci-keycloak 2>/dev/null || true + - name: Show sccache stats + run: sccache --show-stats + if: always() + # --------------------------------------------------------------------------- # Stage 3: Deploy (only after tests pass, only on main) # --------------------------------------------------------------------------- deploy: name: Deploy runs-on: docker - needs: [test] + needs: [test, e2e] if: github.ref == 'refs/heads/main' container: image: alpine:latest