Skip to content

chore: Add basic login tests #19

chore: Add basic login tests

chore: Add basic login tests #19

Workflow file for this run

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