chore: Add basic login tests #19
Workflow file for this run
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: Server CI | |
| on: | |
| pull_request: | |
| branches: [2.0.0-alpha] | |
| paths: | |
| - "server/with-node/**" | |
| - ".github/workflows/server-ci.yml" | |
| - ".env.ci.example" | |
| - "package.json" | |
| - "yarn.lock" | |
| - ".yarnrc.yml" | |
| - ".yarn/**" | |
| workflow_dispatch: | |
| inputs: | |
| skip_build: | |
| description: "Skip build step (faster iteration)" | |
| type: boolean | |
| default: false | |
| skip_e2e: | |
| description: "Skip E2E tests" | |
| type: boolean | |
| default: false | |
| concurrency: | |
| group: server-ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| NODE_VERSION: "20.19.0" | |
| # Improve caching and performance | |
| YARN_ENABLE_GLOBAL_CACHE: "false" | |
| YARN_NM_MODE: "hardlinks-local" | |
| NODE_OPTIONS: "--max-old-space-size=4096" | |
| jobs: | |
| # Test server project | |
| test-server: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| name: Test Node.js Server | |
| env: | |
| # Base environment variables | |
| PARA_API_KEY_BETA: ${{ secrets.PARA_API_KEY_BETA }} | |
| PARA_API_KEY_SANDBOX: ${{ secrets.PARA_API_KEY_SANDBOX }} | |
| PARA_API_KEY: ${{ secrets.PARA_API_KEY }} | |
| PARA_ENVIRONMENT: ${{ secrets.PARA_ENVIRONMENT }} | |
| # Server-specific environment variables | |
| ENCRYPTION_KEY: ${{ secrets.ENCRYPTION_KEY }} | |
| ALCHEMY_API_KEY: ${{ secrets.ALCHEMY_API_KEY }} | |
| ALCHEMY_GAS_POLICY_ID: ${{ secrets.ALCHEMY_GAS_POLICY_ID }} | |
| ALCHEMY_ARBITRUM_SEPOLIA_RPC: ${{ secrets.ALCHEMY_ARBITRUM_SEPOLIA_RPC }} | |
| ALCHEMY_RPC_URL: ${{ secrets.ALCHEMY_RPC_URL }} | |
| ZERODEV_PROJECT_ID: ${{ secrets.ZERODEV_PROJECT_ID }} | |
| ZERODEV_BUNDLER_RPC: ${{ secrets.ZERODEV_BUNDLER_RPC }} | |
| ZERODEV_PAYMASTER_RPC: ${{ secrets.ZERODEV_PAYMASTER_RPC }} | |
| ZERODEV_SECRET_KEY: ${{ secrets.ZERODEV_SECRET_KEY }} | |
| ZERODEV_ARBITRUM_SEPOLIA_RPC: ${{ secrets.ZERODEV_ARBITRUM_SEPOLIA_RPC }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| sparse-checkout: | | |
| server/with-node | |
| .github | |
| package.json | |
| yarn.lock | |
| .yarnrc.yml | |
| .yarn | |
| - name: Clean Workspace | |
| run: | | |
| # Ensure we start with a clean workspace | |
| echo "🧹 Pre-job cleanup..." | |
| # Remove any artifacts that might exist from previous runs | |
| find . -name "node_modules" -type d -prune -exec rm -rf '{}' + 2>/dev/null || true | |
| find . -name "dist" -type d -prune -exec rm -rf '{}' + 2>/dev/null || true | |
| find . -name "build" -type d -prune -exec rm -rf '{}' + 2>/dev/null || true | |
| find . -name ".yarn-cache-local" -type d -prune -exec rm -rf '{}' + 2>/dev/null || true | |
| echo "✅ Pre-cleanup complete" | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| - name: Create .env file | |
| run: | | |
| cd server/with-node | |
| echo "Creating .env file for server..." | |
| # Create .env file with proper variable expansion | |
| { | |
| echo "PARA_API_KEY_BETA=${PARA_API_KEY_BETA}" | |
| echo "PARA_API_KEY_SANDBOX=${PARA_API_KEY_SANDBOX}" | |
| echo "PARA_API_KEY=${PARA_API_KEY}" | |
| echo "PARA_ENVIRONMENT=${PARA_ENVIRONMENT}" | |
| echo "ENCRYPTION_KEY=${ENCRYPTION_KEY}" | |
| echo "ALCHEMY_API_KEY=${ALCHEMY_API_KEY}" | |
| echo "ALCHEMY_GAS_POLICY_ID=${ALCHEMY_GAS_POLICY_ID}" | |
| echo "ALCHEMY_ARBITRUM_SEPOLIA_RPC=${ALCHEMY_ARBITRUM_SEPOLIA_RPC}" | |
| echo "ALCHEMY_RPC_URL=${ALCHEMY_RPC_URL}" | |
| echo "ZERODEV_PROJECT_ID=${ZERODEV_PROJECT_ID}" | |
| echo "ZERODEV_BUNDLER_RPC=${ZERODEV_BUNDLER_RPC}" | |
| echo "ZERODEV_PAYMASTER_RPC=${ZERODEV_PAYMASTER_RPC}" | |
| echo "ZERODEV_SECRET_KEY=${ZERODEV_SECRET_KEY}" | |
| echo "ZERODEV_ARBITRUM_SEPOLIA_RPC=${ZERODEV_ARBITRUM_SEPOLIA_RPC}" | |
| } > .env | |
| # Debug: Show file was created and has content | |
| echo "✅ .env file created with $(wc -l < .env) lines" | |
| - name: Run Tests | |
| id: test | |
| run: | | |
| cd server/with-node | |
| # Initialize result tracking | |
| PROJECT_NAME="Node.js Server" | |
| LINT_STATUS="⏭️ skipped" | |
| TYPECHECK_STATUS="⏭️ skipped" | |
| BUILD_STATUS="⏭️ skipped" | |
| FAILED=false | |
| START_TIME=$(date +%s) | |
| # Create summary header for this project | |
| echo "### Testing: $PROJECT_NAME" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| # Show initial disk usage | |
| echo "💾 Initial disk usage:" >> $GITHUB_STEP_SUMMARY | |
| df -h | grep -E "Filesystem|/$" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| # Install dependencies with optimizations | |
| echo "📦 Installing dependencies..." | |
| # Use project-specific yarn cache to avoid conflicts | |
| export YARN_CACHE_FOLDER="$(pwd)/.yarn-cache-local" | |
| if yarn install --immutable --network-timeout 60000; then | |
| echo "✅ Dependencies installed" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "❌ Failed to install dependencies" >> $GITHUB_STEP_SUMMARY | |
| FAILED=true | |
| exit 1 | |
| fi | |
| # Lint | |
| if grep -q '"lint"' package.json; then | |
| echo "" | |
| echo "🔍 Running lint..." | |
| if timeout 300 yarn lint; then | |
| LINT_STATUS="✅ passed" | |
| echo "- Lint: ✅ passed" >> $GITHUB_STEP_SUMMARY | |
| else | |
| LINT_STATUS="❌ failed" | |
| FAILED=true | |
| echo "- Lint: ❌ failed" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| # Clean lint artifacts immediately | |
| echo "🧹 Cleaning lint artifacts..." | |
| rm -rf .eslintcache | |
| else | |
| echo "- Lint: ⏭️ no script" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| # Typecheck | |
| if grep -q '"typecheck"' package.json; then | |
| echo "" | |
| echo "📝 Running typecheck..." | |
| if timeout 300 yarn typecheck; then | |
| TYPECHECK_STATUS="✅ passed" | |
| echo "- Typecheck: ✅ passed" >> $GITHUB_STEP_SUMMARY | |
| else | |
| TYPECHECK_STATUS="❌ failed" | |
| FAILED=true | |
| echo "- Typecheck: ❌ failed" >> $GITHUB_STEP_SUMMARY | |
| # Skip build if typecheck fails | |
| echo "⏭️ Skipping build due to typecheck failure" | |
| BUILD_STATUS="⏭️ skipped (typecheck failed)" | |
| echo "- Build: ⏭️ skipped (typecheck failed)" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| # Clean TypeScript artifacts immediately | |
| echo "🧹 Cleaning TypeScript artifacts..." | |
| rm -rf tsconfig.tsbuildinfo | |
| else | |
| echo "- Typecheck: ⏭️ no script" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| # Build (only if typecheck passed or doesn't exist) | |
| if [[ "$TYPECHECK_STATUS" != "❌ failed" ]] && [[ "${{ github.event.inputs.skip_build }}" != "true" ]]; then | |
| if grep -q '"build"' package.json; then | |
| echo "" | |
| echo "🔨 Running build..." | |
| if timeout 300 yarn build; then | |
| BUILD_STATUS="✅ passed" | |
| echo "- Build: ✅ passed" >> $GITHUB_STEP_SUMMARY | |
| else | |
| BUILD_STATUS="❌ failed" | |
| FAILED=true | |
| echo "- Build: ❌ failed" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| # Clean build artifacts immediately after verification | |
| echo "🧹 Cleaning build artifacts..." | |
| rm -rf dist build | |
| else | |
| echo "- Build: ⏭️ no script" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| fi | |
| # Calculate execution time | |
| END_TIME=$(date +%s) | |
| DURATION=$((END_TIME - START_TIME)) | |
| echo "- Duration: ${DURATION}s" >> $GITHUB_STEP_SUMMARY | |
| # Comprehensive cleanup to prevent disk space issues | |
| echo "" | |
| echo "🧹 Performing comprehensive cleanup..." | |
| # Clean node_modules | |
| echo " - Removing node_modules..." | |
| rm -rf node_modules | |
| # Clean yarn caches and artifacts | |
| echo " - Removing yarn caches..." | |
| rm -rf .yarn-cache-local | |
| rm -rf .yarn/cache | |
| rm -rf .yarn/unplugged | |
| rm -rf .yarn/build-state.yml | |
| rm -rf .yarn/install-state.gz | |
| # Clean build artifacts (in case any were missed) | |
| echo " - Removing remaining build artifacts..." | |
| rm -rf dist build | |
| # Clean other common artifacts | |
| echo " - Removing other artifacts..." | |
| rm -rf .eslintcache tsconfig.tsbuildinfo | |
| rm -rf *.log | |
| # Show final disk usage for this project | |
| echo "💾 Final disk usage after cleanup:" >> $GITHUB_STEP_SUMMARY | |
| df -h | grep -E "Filesystem|/$" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "✅ Cleanup complete" | |
| # Set outputs for summary | |
| echo "project_name=$PROJECT_NAME" >> $GITHUB_OUTPUT | |
| echo "lint_status=$LINT_STATUS" >> $GITHUB_OUTPUT | |
| echo "typecheck_status=$TYPECHECK_STATUS" >> $GITHUB_OUTPUT | |
| echo "build_status=$BUILD_STATUS" >> $GITHUB_OUTPUT | |
| echo "duration=$DURATION" >> $GITHUB_OUTPUT | |
| if [ "$FAILED" = true ]; then | |
| echo "failed=true" >> $GITHUB_OUTPUT | |
| exit 1 | |
| else | |
| echo "failed=false" >> $GITHUB_OUTPUT | |
| fi | |
| # End-to-end tests | |
| e2e: | |
| needs: [test-server] | |
| if: | | |
| always() && | |
| needs.test-server.result == 'success' && | |
| github.event.inputs.skip_e2e != 'true' | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 # E2E tests need more time | |
| name: E2E Server Tests | |
| env: | |
| # Base environment variables | |
| PARA_API_KEY_BETA: ${{ secrets.PARA_API_KEY_BETA }} | |
| PARA_API_KEY_SANDBOX: ${{ secrets.PARA_API_KEY_SANDBOX }} | |
| PARA_API_KEY: ${{ secrets.PARA_API_KEY }} | |
| PARA_ENVIRONMENT: ${{ secrets.PARA_ENVIRONMENT }} | |
| # Server-specific environment variables | |
| ENCRYPTION_KEY: ${{ secrets.ENCRYPTION_KEY }} | |
| ALCHEMY_API_KEY: ${{ secrets.ALCHEMY_API_KEY }} | |
| ALCHEMY_GAS_POLICY_ID: ${{ secrets.ALCHEMY_GAS_POLICY_ID }} | |
| ALCHEMY_ARBITRUM_SEPOLIA_RPC: ${{ secrets.ALCHEMY_ARBITRUM_SEPOLIA_RPC }} | |
| ALCHEMY_RPC_URL: ${{ secrets.ALCHEMY_RPC_URL }} | |
| ZERODEV_PROJECT_ID: ${{ secrets.ZERODEV_PROJECT_ID }} | |
| ZERODEV_BUNDLER_RPC: ${{ secrets.ZERODEV_BUNDLER_RPC }} | |
| ZERODEV_PAYMASTER_RPC: ${{ secrets.ZERODEV_PAYMASTER_RPC }} | |
| ZERODEV_SECRET_KEY: ${{ secrets.ZERODEV_SECRET_KEY }} | |
| ZERODEV_ARBITRUM_SEPOLIA_RPC: ${{ secrets.ZERODEV_ARBITRUM_SEPOLIA_RPC }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| - name: Install Dependencies | |
| run: | | |
| # Use local yarn cache to avoid conflicts | |
| export YARN_CACHE_FOLDER="$(pwd)/.yarn-cache-local" | |
| yarn install --immutable --network-timeout 60000 | |
| - name: Install Playwright | |
| timeout-minutes: 3 | |
| run: npx playwright install chromium | |
| - name: Create .env file for E2E (root and server/with-node) | |
| run: | | |
| # Create .env file in root directory for E2E tests | |
| echo "Creating .env file in root for E2E tests..." | |
| { | |
| echo "PARA_API_KEY_BETA=${PARA_API_KEY_BETA}" | |
| echo "PARA_API_KEY_SANDBOX=${PARA_API_KEY_SANDBOX}" | |
| echo "PARA_API_KEY=${PARA_API_KEY}" | |
| echo "PARA_ENVIRONMENT=${PARA_ENVIRONMENT}" | |
| echo "ENCRYPTION_KEY=${ENCRYPTION_KEY}" | |
| echo "ALCHEMY_API_KEY=${ALCHEMY_API_KEY}" | |
| echo "ALCHEMY_GAS_POLICY_ID=${ALCHEMY_GAS_POLICY_ID}" | |
| echo "ALCHEMY_ARBITRUM_SEPOLIA_RPC=${ALCHEMY_ARBITRUM_SEPOLIA_RPC}" | |
| echo "ALCHEMY_RPC_URL=${ALCHEMY_RPC_URL}" | |
| echo "ZERODEV_PROJECT_ID=${ZERODEV_PROJECT_ID}" | |
| echo "ZERODEV_BUNDLER_RPC=${ZERODEV_BUNDLER_RPC}" | |
| echo "ZERODEV_PAYMASTER_RPC=${ZERODEV_PAYMASTER_RPC}" | |
| echo "ZERODEV_SECRET_KEY=${ZERODEV_SECRET_KEY}" | |
| echo "ZERODEV_ARBITRUM_SEPOLIA_RPC=${ZERODEV_ARBITRUM_SEPOLIA_RPC}" | |
| } > .env | |
| # Also create .env in server/with-node | |
| mkdir -p server/with-node | |
| cp .env server/with-node/.env | |
| echo "✅ .env file copied to server/with-node/.env" | |
| ls -la server/with-node/.env | |
| - name: Run E2E Tests | |
| id: e2e-test | |
| timeout-minutes: 25 | |
| run: | | |
| echo "### E2E Server Tests" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| # Debug: Check if .env exists and has content | |
| echo "Current directory: $(pwd)" | |
| if [ -f .env ]; then | |
| echo "✅ .env file exists in root" | |
| echo "File size: $(wc -c < .env) bytes" | |
| else | |
| echo "❌ .env file not found in root!" | |
| fi | |
| # Run server E2E tests from root directory | |
| yarn test:node | |
| if [ $? -eq 0 ]; then | |
| echo "✅ All server E2E tests passed" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "❌ E2E tests failed" >> $GITHUB_STEP_SUMMARY | |
| exit 1 | |
| fi | |
| - name: Upload Playwright Report | |
| uses: actions/upload-artifact@v4 | |
| if: failure() | |
| with: | |
| name: playwright-report-server | |
| path: playwright-report/ | |
| retention-days: 7 | |
| # Summary job | |
| summary: | |
| if: always() | |
| needs: [test-server, e2e] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Generate Report | |
| run: | | |
| echo "# 📊 Server CI Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| # Overall status | |
| SERVER_STATUS="${{ needs.test-server.result }}" | |
| E2E_STATUS="${{ needs.e2e.result }}" | |
| echo "## Overall Status" >> $GITHUB_STEP_SUMMARY | |
| echo "| Component | Status |" >> $GITHUB_STEP_SUMMARY | |
| echo "|-----------|--------|" >> $GITHUB_STEP_SUMMARY | |
| echo "| Server Tests | ${{ needs.test-server.result == 'success' && '✅ Passed' || needs.test-server.result == 'failure' && '❌ Failed' || '⏭️ Skipped' }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| E2E Tests | ${{ needs.e2e.result == 'success' && '✅ Passed' || needs.e2e.result == 'failure' && '❌ Failed' || '⏭️ Skipped' }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| # Final result | |
| if [ "$SERVER_STATUS" = "success" ] && [ "$E2E_STATUS" = "success" ]; then | |
| echo "## ✅ All checks passed!" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "## ❌ Some checks failed" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "Please check the individual job logs for details." >> $GITHUB_STEP_SUMMARY | |
| exit 1 | |
| fi |