This repository was archived by the owner on Aug 29, 2026. It is now read-only.
chore(deps): bump the npm-frontend group across 1 directory with 58 updates #4338
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: Public API Test | |
| on: | |
| pull_request: | |
| branches: [main] | |
| push: | |
| branches: [main] | |
| jobs: | |
| # ─────────────────────────────────────────────────────────────────── | |
| # Build: compile the backend Docker image once, share via artifact | |
| # ─────────────────────────────────────────────────────────────────── | |
| build: | |
| if: >- | |
| github.event_name != 'pull_request' || | |
| (github.event.pull_request.head.repo.full_name == github.repository && | |
| github.actor != 'dependabot[bot]') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha }} | |
| - name: Build test backend image | |
| run: | | |
| echo "Building backend image for testing..." | |
| docker build -t test-backend:latest ./backend | |
| - name: Export backend image | |
| run: docker save test-backend:latest | gzip > /tmp/test-backend-image.tar.gz | |
| - name: Upload backend image | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: test-backend-image | |
| path: /tmp/test-backend-image.tar.gz | |
| retention-days: 1 | |
| # ─────────────────────────────────────────────────────────────────── | |
| # Test: 5 parallel runners, each with its own Docker Compose stack | |
| # ─────────────────────────────────────────────────────────────────── | |
| test-public-api: | |
| needs: build | |
| runs-on: ubuntu-latest | |
| environment: dev | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| group: [0, 1, 2, 3, 4] | |
| steps: | |
| - name: Verify prerequisites | |
| run: | | |
| echo "Docker version:" | |
| docker --version | |
| echo "Docker Compose version:" | |
| docker compose version | |
| - name: Checkout code | |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha }} | |
| - name: Set up Python | |
| uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 | |
| with: | |
| python-version: "3.13" | |
| - name: Install Python dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| cd backend | |
| pip install -r tests/e2e/requirements.txt | |
| - name: Download backend image | |
| uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 | |
| with: | |
| name: test-backend-image | |
| path: /tmp | |
| - name: Load backend image | |
| run: | | |
| echo "Loading pre-built backend image..." | |
| docker load < /tmp/test-backend-image.tar.gz | |
| docker images test-backend | |
| - name: Pre-pull heavy Docker images | |
| run: | | |
| echo "Pre-pulling Docker images in parallel..." | |
| echo "Note: text2vec-transformers disabled via docker-compose profile (backend uses OpenAI)" | |
| docker pull postgres:16 & | |
| docker pull redis:7-alpine & | |
| docker pull temporalio/auto-setup:1.24.2 & | |
| docker pull temporalio/ui:2.26.2 & | |
| docker pull vespaengine/vespa:8 & | |
| docker pull svix/svix-server & | |
| docker pull alpine:3.19 & | |
| docker pull ghcr.io/docling-project/docling-serve & | |
| wait | |
| echo "All images pre-pulled successfully" | |
| - name: Setup environment and start services | |
| env: | |
| BACKEND_IMAGE: test-backend:latest | |
| OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} | |
| STRIPE_API_KEY: ${{ secrets.STRIPE_API_KEY }} | |
| MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY || 'dummy-key' }} | |
| COHERE_API_KEY: ${{ secrets.COHERE_API_KEY || 'dummy-key' }} | |
| GROQ_API_KEY: ${{ secrets.GROQ_API_KEY || 'dummy-key' }} | |
| CEREBRAS_API_KEY: ${{ secrets.CEREBRAS_API_KEY || 'dummy-key' }} | |
| TOGETHER_API_KEY: ${{ secrets.TOGETHER_API_KEY || 'dummy-key' }} | |
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY || 'dummy-key' }} | |
| # Required for start.sh to skip interactive prompts | |
| NONINTERACTIVE: "1" | |
| # Skip services not needed for backend API tests | |
| SKIP_LOCAL_EMBEDDINGS: "1" # Use OpenAI embeddings (saves ~2GB) | |
| SKIP_FRONTEND: "1" # Backend-only testing (saves time) | |
| SKIP_CONNECT: "1" # Backend-only testing (saves time) | |
| # Enable docling-serve for OCR fallback testing | |
| ENABLE_DOCLING: "1" | |
| # Set required environment variables for the containers | |
| AUTH0_ENABLED: "false" | |
| DEV_MODE: "true" | |
| ENABLE_INTERNAL_SOURCES: "true" | |
| run: | | |
| # Create .env from example | |
| cp .env.example .env | |
| # Add AI keys to .env before starting services | |
| echo "OPENAI_API_KEY=$OPENAI_API_KEY" >> .env | |
| echo "STRIPE_API_KEY=$STRIPE_API_KEY" >> .env | |
| echo "MISTRAL_API_KEY=$MISTRAL_API_KEY" >> .env | |
| echo "COHERE_API_KEY=$COHERE_API_KEY" >> .env | |
| echo "GROQ_API_KEY=$GROQ_API_KEY" >> .env | |
| echo "CEREBRAS_API_KEY=$CEREBRAS_API_KEY" >> .env | |
| echo "TOGETHER_API_KEY=$TOGETHER_API_KEY" >> .env | |
| echo "ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY" >> .env | |
| # Point backend at the docling-serve container | |
| echo "DOCLING_BASE_URL=http://docling:5001" >> .env | |
| # Disable rate limiting for regular tests | |
| echo "DISABLE_RATE_LIMIT=true" >> .env | |
| # Enable internal sources (stub, snapshot) for testing | |
| echo "ENABLE_INTERNAL_SOURCES=true" >> .env | |
| # Disable webhook endpoint verification (tests use fake URLs) | |
| echo "WEBHOOK_VERIFY_ENDPOINTS=false" >> .env | |
| # Set embedding config (OpenAI text-embedding-3-small, 1536 dims) | |
| echo "DENSE_EMBEDDER=openai_text_embedding_3_small" >> .env | |
| echo "EMBEDDING_DIMENSIONS=1536" >> .env | |
| echo "SPARSE_EMBEDDER=fastembed_bm25" >> .env | |
| echo "Starting services using start.sh..." | |
| ./start.sh --noninteractive | |
| # The script already does health checks, but let's verify | |
| echo "" | |
| echo "Verifying we're using the correct test images:" | |
| docker ps --format "table {{.Names}}\t{{.Image}}" | grep airweave | |
| echo "" | |
| echo "Final verification of services:" | |
| docker ps | |
| # Backend runs on port 8001 according to start.sh | |
| echo "Testing backend on port 8001..." | |
| curl -f http://localhost:8001/health || (echo "Backend not healthy"; docker logs airweave-backend; exit 1) | |
| echo "Backend is healthy and ready for API tests!" | |
| - name: Verify embedding configuration | |
| run: | | |
| echo "Checking embedding stack configuration..." | |
| # Verify embedding validation passed at startup (no errors in logs) | |
| if docker logs airweave-backend 2>&1 | grep -q "EmbeddingConfigurationError"; then | |
| echo "ERROR: Embedding configuration failed!" | |
| docker logs airweave-backend 2>&1 | grep -A5 "EmbeddingConfigurationError" | |
| exit 1 | |
| fi | |
| # Check for successful embedding validation message | |
| if docker logs airweave-backend 2>&1 | grep -q "Embedding stack validated"; then | |
| echo "✓ Embedding stack validated successfully" | |
| docker logs airweave-backend 2>&1 | grep "Embedding stack" | head -5 | |
| else | |
| echo "Note: Embedding validation message not found (may be at DEBUG level)" | |
| fi | |
| # Verify Vespa schema was deployed with correct dimensions | |
| echo "" | |
| echo "Checking Vespa deployment..." | |
| VESPA_DIMS=$(docker logs airweave-vespa-init 2>&1 | grep -o "EMBEDDING_DIMENSIONS=[0-9]*" | cut -d= -f2 || echo "unknown") | |
| if [ "$VESPA_DIMS" = "1536" ]; then | |
| echo "✓ Vespa deployed with EMBEDDING_DIMENSIONS=1536" | |
| elif [ "$VESPA_DIMS" = "unknown" ]; then | |
| echo "Note: Could not verify Vespa dimensions from init logs" | |
| else | |
| echo "WARNING: Vespa may have unexpected dimensions: $VESPA_DIMS" | |
| fi | |
| echo "" | |
| echo "Embedding configuration verification complete!" | |
| - name: Run E2E Smoke Tests (group ${{ matrix.group }}) | |
| env: | |
| TEST_ENV: local | |
| OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} | |
| TEST_STRIPE_API_KEY: ${{ secrets.STRIPE_API_KEY }} | |
| # Required test environment variables | |
| TEST_NOTION_TOKEN: ${{ secrets.TEST_NOTION_TOKEN }} | |
| TEST_GOOGLE_CLIENT_ID: ${{ secrets.TEST_GOOGLE_CLIENT_ID }} | |
| TEST_GOOGLE_CLIENT_SECRET: ${{ secrets.TEST_GOOGLE_CLIENT_SECRET }} | |
| # OAuth1 (Trello) credentials | |
| TEST_TRELLO_CONSUMER_KEY: ${{ secrets.TEST_TRELLO_CONSUMER_KEY }} | |
| TEST_TRELLO_CONSUMER_SECRET: ${{ secrets.TEST_TRELLO_CONSUMER_SECRET }} | |
| TEST_AUTH_PROVIDER_NAME: composio | |
| TEST_COMPOSIO_API_KEY: ${{ secrets.TEST_COMPOSIO_API_KEY }} | |
| # Composio service-specific configurations | |
| TEST_COMPOSIO_TODOIST_AUTH_CONFIG_ID: ac_wcspYMD22UDD | |
| TEST_COMPOSIO_TODOIST_ACCOUNT_ID: ca_h1xDM7cdVzeI | |
| TEST_COMPOSIO_ASANA_AUTH_CONFIG_ID: ac_hBi29B_-iU3B | |
| TEST_COMPOSIO_ASANA_ACCOUNT_ID: ca_ooqwRcKOwHmo | |
| TEST_COMPOSIO_GMAIL_AUTH_CONFIG_ID: ac_HocwjtTv-dqb | |
| TEST_COMPOSIO_GMAIL_ACCOUNT_ID: ca_jEA4l17nSPzN | |
| # Pipedream configurations (regular tests) | |
| TEST_PIPEDREAM_CLIENT_ID: ${{ secrets.TEST_PIPEDREAM_CLIENT_ID }} | |
| TEST_PIPEDREAM_CLIENT_SECRET: ${{ secrets.TEST_PIPEDREAM_CLIENT_SECRET }} | |
| TEST_PIPEDREAM_PROJECT_ID: ${{ secrets.TEST_PIPEDREAM_PROJECT_ID }} | |
| TEST_PIPEDREAM_ACCOUNT_ID: ${{ secrets.TEST_PIPEDREAM_ACCOUNT_ID }} | |
| TEST_PIPEDREAM_EXTERNAL_USER_ID: ${{ secrets.TEST_PIPEDREAM_EXTERNAL_USER_ID }} | |
| # Pipedream configurations (rate limit tests - separate project) | |
| TEST_PIPEDREAM_RATE_LIMIT_CLIENT_ID: ${{ secrets.TEST_PIPEDREAM_RATE_LIMIT_CLIENT_ID }} | |
| TEST_PIPEDREAM_RATE_LIMIT_CLIENT_SECRET: ${{ secrets.TEST_PIPEDREAM_RATE_LIMIT_CLIENT_SECRET }} | |
| TEST_PIPEDREAM_RATE_LIMIT_PROJECT_ID: ${{ secrets.TEST_PIPEDREAM_RATE_LIMIT_PROJECT_ID }} | |
| TEST_PIPEDREAM_GOOGLE_DRIVE_DEFAULT_OAUTH_ACCOUNT_ID: ${{ secrets.TEST_PIPEDREAM_GOOGLE_DRIVE_DEFAULT_OAUTH_ACCOUNT_ID }} | |
| TEST_PIPEDREAM_GOOGLE_DRIVE_DEFAULT_OAUTH_EXTERNAL_USER_ID: ${{ secrets.TEST_PIPEDREAM_GOOGLE_DRIVE_DEFAULT_OAUTH_EXTERNAL_USER_ID }} | |
| TEST_PIPEDREAM_NOTION_DEFAULT_OAUTH_ACCOUNT_ID: ${{ secrets.TEST_PIPEDREAM_NOTION_DEFAULT_OAUTH_ACCOUNT_ID }} | |
| TEST_PIPEDREAM_NOTION_DEFAULT_OAUTH_EXTERNAL_USER_ID: ${{ secrets.TEST_PIPEDREAM_NOTION_DEFAULT_OAUTH_EXTERNAL_USER_ID }} | |
| # Composio configurations (rate limit tests) | |
| TEST_COMPOSIO_NOTION_AUTH_CONFIG_ID_1: ${{ secrets.TEST_COMPOSIO_NOTION_AUTH_CONFIG_ID_1 }} | |
| TEST_COMPOSIO_NOTION_ACCOUNT_ID_1: ${{ secrets.TEST_COMPOSIO_NOTION_ACCOUNT_ID_1 }} | |
| TEST_COMPOSIO_NOTION_AUTH_CONFIG_ID_2: ${{ secrets.TEST_COMPOSIO_NOTION_AUTH_CONFIG_ID_2 }} | |
| TEST_COMPOSIO_NOTION_ACCOUNT_ID_2: ${{ secrets.TEST_COMPOSIO_NOTION_ACCOUNT_ID_2 }} | |
| TEST_COMPOSIO_GOOGLE_DRIVE_AUTH_CONFIG_ID_1: ${{ secrets.TEST_COMPOSIO_GOOGLE_DRIVE_AUTH_CONFIG_ID_1 }} | |
| TEST_COMPOSIO_GOOGLE_DRIVE_ACCOUNT_ID_1: ${{ secrets.TEST_COMPOSIO_GOOGLE_DRIVE_ACCOUNT_ID_1 }} | |
| TEST_COMPOSIO_GOOGLE_DRIVE_AUTH_CONFIG_ID_2: ${{ secrets.TEST_COMPOSIO_GOOGLE_DRIVE_AUTH_CONFIG_ID_2 }} | |
| TEST_COMPOSIO_GOOGLE_DRIVE_ACCOUNT_ID_2: ${{ secrets.TEST_COMPOSIO_GOOGLE_DRIVE_ACCOUNT_ID_2 }} | |
| # Override images to use locally built test images | |
| BACKEND_IMAGE: test-backend:latest | |
| run: | | |
| cd backend | |
| # ── Dynamically discover and split test files ── | |
| # All matrix jobs see the same file list. We shuffle deterministically | |
| # using the commit SHA so each run gets a different (but reproducible) | |
| # distribution, and each job picks its own slice via round-robin. | |
| COMMIT_SHA="${GITHUB_SHA:-$(date +%Y%m%d)}" | |
| GROUP=${{ matrix.group }} | |
| TOTAL_GROUPS=5 | |
| # Collect all smoke test files (excluding rate-limit-only files) | |
| ALL_FILES=$(find tests/e2e/smoke -maxdepth 1 -name 'test_*.py' \ | |
| ! -name 'test_rate_limiting.py' \ | |
| ! -name 'test_source_rate_limiting.py' \ | |
| | sort) | |
| # Shuffle deterministically: hash each filename with the commit SHA, | |
| # sort by hash, then strip the hash prefix | |
| SHUFFLED=$(echo "$ALL_FILES" | while read -r f; do | |
| hash=$(echo "${f}${COMMIT_SHA}" | md5sum | cut -c1-8) | |
| echo "$hash $f" | |
| done | sort | awk '{print $2}') | |
| TOTAL=$(echo "$SHUFFLED" | wc -l) | |
| # Round-robin: file at position i goes to group (i % TOTAL_GROUPS) | |
| TEST_FILES=$(echo "$SHUFFLED" | awk -v g="$GROUP" -v tg="$TOTAL_GROUPS" '(NR - 1) % tg == g {print}' | tr '\n' ' ') | |
| FILE_COUNT=$(echo "$TEST_FILES" | wc -w) | |
| echo "==========================================" | |
| echo "Group $GROUP of $TOTAL_GROUPS: running $FILE_COUNT / $TOTAL test files" | |
| echo "==========================================" | |
| echo "$TEST_FILES" | tr ' ' '\n' | grep -v '^$' | |
| echo "==========================================" | |
| WORKERS=2 | |
| MAX_RETRIES=2 | |
| # Run tests for this group | |
| # --dist loadscope keeps all tests from the same module/class on one | |
| # worker, so module-scoped fixtures (e.g. synced_file_stub) are only | |
| # created once instead of once per worker. | |
| set +e | |
| pytest $TEST_FILES -m "not rate_limit and not api_rate_limit" -n $WORKERS --dist loadscope -v --tb=short 2>&1 | tee pytest_output.txt | |
| EXIT_CODE=${PIPESTATUS[0]} | |
| set -e | |
| if [ $EXIT_CODE -eq 0 ]; then | |
| echo "All tests passed! (group $GROUP)" | |
| exit 0 | |
| fi | |
| # Count failures from pytest output | |
| FAILURES=$(grep -oP '\d+(?= failed)' pytest_output.txt | head -1 || echo "0") | |
| echo "Detected $FAILURES test failure(s) in group $GROUP" | |
| # If too many failures, don't retry (likely a real issue, not flakiness) | |
| if [ "$FAILURES" -ge 4 ]; then | |
| echo "4 or more tests failed in group $GROUP. Not retrying." | |
| exit 1 | |
| fi | |
| # Retry only the failed tests | |
| ATTEMPT=1 | |
| while [ $ATTEMPT -le $MAX_RETRIES ]; do | |
| echo "" | |
| echo "==========================================" | |
| echo "Retry attempt $ATTEMPT of $MAX_RETRIES (group $GROUP, ONLY failed tests)" | |
| echo "==========================================" | |
| sleep 10 | |
| set +e | |
| pytest $TEST_FILES -m "not rate_limit and not api_rate_limit" --lf -n $WORKERS --dist loadscope -v --tb=short 2>&1 | tee pytest_retry_output.txt | |
| EXIT_CODE=${PIPESTATUS[0]} | |
| set -e | |
| if [ $EXIT_CODE -eq 0 ]; then | |
| echo "Failed tests passed on retry! (group $GROUP)" | |
| exit 0 | |
| fi | |
| ATTEMPT=$((ATTEMPT + 1)) | |
| done | |
| # If we get here, tests failed after retries | |
| echo "Tests in group $GROUP failed after $MAX_RETRIES retry attempts" | |
| exit 1 | |
| - name: Run Source Rate Limit Tests (Sequential) | |
| if: false # Temporarily disabled to reduce CI load | |
| env: | |
| TEST_ENV: local | |
| OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} | |
| TEST_STRIPE_API_KEY: ${{ secrets.STRIPE_API_KEY }} | |
| # Required test environment variables (needed by TestSettings even for rate limit tests) | |
| TEST_NOTION_TOKEN: ${{ secrets.TEST_NOTION_TOKEN }} | |
| TEST_GOOGLE_CLIENT_ID: ${{ secrets.TEST_GOOGLE_CLIENT_ID }} | |
| TEST_GOOGLE_CLIENT_SECRET: ${{ secrets.TEST_GOOGLE_CLIENT_SECRET }} | |
| TEST_TRELLO_CONSUMER_KEY: ${{ secrets.TEST_TRELLO_CONSUMER_KEY }} | |
| TEST_TRELLO_CONSUMER_SECRET: ${{ secrets.TEST_TRELLO_CONSUMER_SECRET }} | |
| TEST_AUTH_PROVIDER_NAME: composio | |
| TEST_COMPOSIO_API_KEY: ${{ secrets.TEST_COMPOSIO_API_KEY }} | |
| # Pipedream configurations (regular tests - required by TestSettings) | |
| TEST_PIPEDREAM_CLIENT_ID: ${{ secrets.TEST_PIPEDREAM_CLIENT_ID }} | |
| TEST_PIPEDREAM_CLIENT_SECRET: ${{ secrets.TEST_PIPEDREAM_CLIENT_SECRET }} | |
| TEST_PIPEDREAM_PROJECT_ID: ${{ secrets.TEST_PIPEDREAM_PROJECT_ID }} | |
| TEST_PIPEDREAM_ACCOUNT_ID: ${{ secrets.TEST_PIPEDREAM_ACCOUNT_ID }} | |
| TEST_PIPEDREAM_EXTERNAL_USER_ID: ${{ secrets.TEST_PIPEDREAM_EXTERNAL_USER_ID }} | |
| # Composio configurations (rate limit tests) | |
| TEST_COMPOSIO_NOTION_AUTH_CONFIG_ID_1: ${{ secrets.TEST_COMPOSIO_NOTION_AUTH_CONFIG_ID_1 }} | |
| TEST_COMPOSIO_NOTION_ACCOUNT_ID_1: ${{ secrets.TEST_COMPOSIO_NOTION_ACCOUNT_ID_1 }} | |
| TEST_COMPOSIO_NOTION_AUTH_CONFIG_ID_2: ${{ secrets.TEST_COMPOSIO_NOTION_AUTH_CONFIG_ID_2 }} | |
| TEST_COMPOSIO_NOTION_ACCOUNT_ID_2: ${{ secrets.TEST_COMPOSIO_NOTION_ACCOUNT_ID_2 }} | |
| TEST_COMPOSIO_GOOGLE_DRIVE_AUTH_CONFIG_ID_1: ${{ secrets.TEST_COMPOSIO_GOOGLE_DRIVE_AUTH_CONFIG_ID_1 }} | |
| TEST_COMPOSIO_GOOGLE_DRIVE_ACCOUNT_ID_1: ${{ secrets.TEST_COMPOSIO_GOOGLE_DRIVE_ACCOUNT_ID_1 }} | |
| TEST_COMPOSIO_GOOGLE_DRIVE_AUTH_CONFIG_ID_2: ${{ secrets.TEST_COMPOSIO_GOOGLE_DRIVE_AUTH_CONFIG_ID_2 }} | |
| TEST_COMPOSIO_GOOGLE_DRIVE_ACCOUNT_ID_2: ${{ secrets.TEST_COMPOSIO_GOOGLE_DRIVE_ACCOUNT_ID_2 }} | |
| # Pipedream configurations (rate limit tests - separate project) | |
| TEST_PIPEDREAM_RATE_LIMIT_CLIENT_ID: ${{ secrets.TEST_PIPEDREAM_RATE_LIMIT_CLIENT_ID }} | |
| TEST_PIPEDREAM_RATE_LIMIT_CLIENT_SECRET: ${{ secrets.TEST_PIPEDREAM_RATE_LIMIT_CLIENT_SECRET }} | |
| TEST_PIPEDREAM_RATE_LIMIT_PROJECT_ID: ${{ secrets.TEST_PIPEDREAM_RATE_LIMIT_PROJECT_ID }} | |
| TEST_PIPEDREAM_GOOGLE_DRIVE_DEFAULT_OAUTH_ACCOUNT_ID: ${{ secrets.TEST_PIPEDREAM_GOOGLE_DRIVE_DEFAULT_OAUTH_ACCOUNT_ID }} | |
| TEST_PIPEDREAM_GOOGLE_DRIVE_DEFAULT_OAUTH_EXTERNAL_USER_ID: ${{ secrets.TEST_PIPEDREAM_GOOGLE_DRIVE_DEFAULT_OAUTH_EXTERNAL_USER_ID }} | |
| TEST_PIPEDREAM_NOTION_DEFAULT_OAUTH_ACCOUNT_ID: ${{ secrets.TEST_PIPEDREAM_NOTION_DEFAULT_OAUTH_ACCOUNT_ID }} | |
| TEST_PIPEDREAM_NOTION_DEFAULT_OAUTH_EXTERNAL_USER_ID: ${{ secrets.TEST_PIPEDREAM_NOTION_DEFAULT_OAUTH_EXTERNAL_USER_ID }} | |
| run: | | |
| cd backend | |
| echo "Running source rate limit tests sequentially (no parallelization for Redis isolation)..." | |
| pytest tests/e2e/smoke -m rate_limit -v --tb=short | |
| - name: Print service logs on failure (group ${{ matrix.group }}) | |
| if: failure() | |
| run: | | |
| echo "==========================================" | |
| echo "FAILED GROUP: ${{ matrix.group }}" | |
| echo "==========================================" | |
| echo "" | |
| echo "==========================================" | |
| echo "CONTAINER STATUS" | |
| echo "==========================================" | |
| docker ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | |
| echo "" | |
| echo "==========================================" | |
| echo "SVIX SERVER LOGS (last 400 lines)" | |
| echo "==========================================" | |
| docker logs airweave-svix --tail 400 2>&1 || echo "Could not fetch Svix logs" | |
| echo "" | |
| echo "==========================================" | |
| echo "FASTAPI SERVER LOGS (last 1000 lines)" | |
| echo "==========================================" | |
| docker logs airweave-backend --tail 1000 2>&1 || echo "Could not fetch backend logs" | |
| echo "" | |
| echo "==========================================" | |
| echo "TEMPORAL WORKER LOGS (last 2000 lines)" | |
| echo "==========================================" | |
| docker logs airweave-temporal-worker --tail 2000 2>&1 || echo "Could not fetch worker logs" | |
| echo "" | |
| echo "==========================================" | |
| echo "ERROR / WARNING LINES (worker, last 200 lines)" | |
| echo "==========================================" | |
| docker logs airweave-temporal-worker 2>&1 | grep -iE "ERROR|WARNING|WARN|exception|traceback" | tail -200 || echo "No error/warning lines found" | |
| echo "" | |
| echo "==========================================" | |
| echo "ERROR / WARNING LINES (backend, last 200 lines)" | |
| echo "==========================================" | |
| docker logs airweave-backend 2>&1 | grep -iE "ERROR|WARNING|WARN|exception|traceback" | tail -200 || echo "No error/warning lines found" | |
| - name: Cleanup Docker containers | |
| if: always() | |
| run: | | |
| echo "Cleaning up Docker containers..." | |
| docker compose down -v || true | |
| docker system prune -f || true |