Skip to content

fix(client): remove hardcoded Vite HMR client script #215

fix(client): remove hardcoded Vite HMR client script

fix(client): remove hardcoded Vite HMR client script #215

name: 🚀 FluxStack v1.4.0 - Complete Build & Test Suite
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
workflow_dispatch: # Allow manual triggering
env:
BUN_VERSION: '1.1.34'
NODE_VERSION: '20'
jobs:
# 📦 Test unified dependency installation
installation-test:
name: 📦 Monorepo Installation Test
runs-on: ubuntu-latest
steps:
- name: 📥 Checkout repository
uses: actions/checkout@v4
- name: 🚀 Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: ${{ env.BUN_VERSION }}
- name: 📊 Test installation performance
run: |
echo "## 📦 Installation Performance Test"
echo "| Metric | Value | Status |"
echo "|--------|-------|--------|"
time_start=$(date +%s)
bun install
time_end=$(date +%s)
duration=$((time_end - time_start))
echo "| Installation Time | ${duration}s | ✅ |"
# Verify single node_modules
if [ -d "node_modules" ] && [ ! -d "app/client/node_modules" ]; then
echo "| Monorepo Structure | Unified | ✅ |"
echo "| node_modules Location | Root Only | ✅ |"
else
echo "| Monorepo Structure | Invalid | ❌ |"
exit 1
fi
echo ""
echo "✅ **Installation completed successfully in ${duration}s**"
- name: 📋 Verify dependencies availability
run: |
echo "## 📦 Dependency Availability Check"
echo "| Component | Package | Status | Version |"
echo "|-----------|---------|--------|---------|"
# Check React (frontend)
react_version=$(bun pm ls | grep "react@" | head -1 | awk '{print $2}' || echo "missing")
if bun pm ls | grep -q "react@"; then
echo "| Frontend | React | ✅ | $react_version |"
else
echo "| Frontend | React | ❌ | missing |"
exit 1
fi
# Check Elysia (backend)
elysia_version=$(bun pm ls | grep "elysia@" | head -1 | awk '{print $2}' || echo "missing")
if bun pm ls | grep -q "elysia@"; then
echo "| Backend | Elysia | ✅ | $elysia_version |"
else
echo "| Backend | Elysia | ❌ | missing |"
exit 1
fi
# Check TypeScript (shared)
typescript_version=$(bun pm ls | grep "typescript@" | head -1 | awk '{print $2}' || echo "missing")
if bun pm ls | grep -q "typescript@"; then
echo "| Shared | TypeScript | ✅ | $typescript_version |"
else
echo "| Shared | TypeScript | ❌ | missing |"
exit 1
fi
# Check Vite (build)
vite_version=$(bun pm ls | grep "vite@" | head -1 | awk '{print $2}' || echo "missing")
if bun pm ls | grep -q "vite@"; then
echo "| Build | Vite | ✅ | $vite_version |"
else
echo "| Build | Vite | ❌ | missing |"
fi
echo ""
echo "✅ **All critical dependencies verified**"
# 🧪 Run all 30 tests
test-suite:
name: 🧪 Complete Test Suite (30 Tests)
runs-on: ubuntu-latest
needs: installation-test
steps:
- name: 📥 Checkout repository
uses: actions/checkout@v4
- name: 🚀 Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: ${{ env.BUN_VERSION }}
- name: 📦 Install dependencies
run: bun install
- name: 🧪 Run all tests
run: |
echo "🔬 Running complete test suite..."
bun run test
- name: 📊 Generate test coverage
run: |
echo "📈 Generating test coverage report..."
bun run test:coverage
- name: 📋 Upload coverage reports
uses: codecov/codecov-action@v3
with:
fail_ci_if_error: false
# 🎨 Frontend build isolation test
frontend-build-test:
name: 🎨 Frontend Build Isolation
runs-on: ubuntu-latest
needs: installation-test
steps:
- name: 📥 Checkout repository
uses: actions/checkout@v4
- name: 🚀 Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: ${{ env.BUN_VERSION }}
- name: 📦 Install dependencies
run: bun install
- name: 🎨 Build frontend only
run: |
echo "🏗️ Testing isolated frontend build..."
bun run build:frontend
- name: ✅ Verify frontend build artifacts
run: |
echo "## 🎨 Frontend Build Verification"
echo "| Artifact | Status | Size |"
echo "|----------|--------|------|"
# Check dist/client directory
if [ -d "dist/client" ]; then
dist_size=$(du -sh dist/client/ | cut -f1)
echo "| dist/client/ | ✅ | $dist_size |"
else
echo "| dist/client/ | ❌ | missing |"
exit 1
fi
# Check index.html
if [ -f "dist/client/index.html" ]; then
html_size=$(du -sh dist/client/index.html | cut -f1)
echo "| index.html | ✅ | $html_size |"
else
echo "| index.html | ❌ | missing |"
exit 1
fi
# Check assets directory
if [ -d "dist/client/assets" ]; then
assets_size=$(du -sh dist/client/assets/ | cut -f1)
assets_count=$(ls -1 dist/client/assets/ | wc -l)
echo "| assets/ | ✅ | $assets_size ($assets_count files) |"
echo ""
echo "### 📋 Generated Assets"
echo "| File | Size | Type |"
echo "|------|------|------|"
for file in dist/client/assets/*; do
if [ -f "$file" ]; then
filename=$(basename "$file")
filesize=$(du -sh "$file" | cut -f1)
extension="${filename##*.}"
echo "| $filename | $filesize | $extension |"
fi
done
else
echo "| assets/ | ❌ | missing |"
exit 1
fi
echo ""
echo "✅ **Frontend build verification completed**"
- name: 📏 Check bundle size
run: |
echo "## 📊 Bundle Size Analysis"
total_size=$(du -sh dist/client/ | cut -f1)
echo "**Total Frontend Bundle:** $total_size"
echo ""
echo "| Asset Type | Count | Total Size | Avg Size |"
echo "|------------|-------|------------|----------|"
# JavaScript files
js_count=$(find dist/client/assets -name "*.js" 2>/dev/null | wc -l)
if [ "$js_count" -gt 0 ]; then
js_total=$(find dist/client/assets -name "*.js" -exec du -c {} + 2>/dev/null | tail -1 | cut -f1)
js_total_kb=$((js_total / 1024))
js_avg=$((js_total_kb / js_count))
echo "| JavaScript | $js_count | ${js_total_kb}KB | ${js_avg}KB |"
else
echo "| JavaScript | 0 | 0KB | 0KB |"
fi
# CSS files
css_count=$(find dist/client/assets -name "*.css" 2>/dev/null | wc -l)
if [ "$css_count" -gt 0 ]; then
css_total=$(find dist/client/assets -name "*.css" -exec du -c {} + 2>/dev/null | tail -1 | cut -f1)
css_total_kb=$((css_total / 1024))
css_avg=$((css_total_kb / css_count))
echo "| CSS | $css_count | ${css_total_kb}KB | ${css_avg}KB |"
else
echo "| CSS | 0 | 0KB | 0KB |"
fi
# Other assets
other_count=$(find dist/client/assets -type f ! -name "*.js" ! -name "*.css" 2>/dev/null | wc -l)
if [ "$other_count" -gt 0 ]; then
other_total=$(find dist/client/assets -type f ! -name "*.js" ! -name "*.css" -exec du -c {} + 2>/dev/null | tail -1 | cut -f1)
other_total_kb=$((other_total / 1024))
other_avg=$((other_total_kb / other_count))
echo "| Other | $other_count | ${other_total_kb}KB | ${other_avg}KB |"
else
echo "| Other | 0 | 0KB | 0KB |"
fi
echo ""
echo "✅ **Bundle analysis completed**"
# ⚡ Backend build isolation test
backend-build-test:
name: ⚡ Backend Build Isolation
runs-on: ubuntu-latest
needs: installation-test
steps:
- name: 📥 Checkout repository
uses: actions/checkout@v4
- name: 🚀 Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: ${{ env.BUN_VERSION }}
- name: 📦 Install dependencies
run: bun install
- name: ⚡ Build backend only
run: |
echo "🏗️ Testing isolated backend build..."
bun run build:backend
- name: ✅ Verify backend build artifacts
run: |
echo "## ⚡ Backend Build Verification"
echo "| Artifact | Status | Size | Type |"
echo "|----------|--------|------|------|"
if [ -f "dist/index.js" ]; then
bundle_size=$(du -sh dist/index.js | cut -f1)
bundle_size_bytes=$(stat -c%s dist/index.js)
echo "| dist/index.js | ✅ | $bundle_size | Bundle |"
# Additional backend files
if [ -d "dist" ]; then
file_count=$(find dist -type f | wc -l)
total_size=$(du -sh dist/ | cut -f1)
echo "| Total dist/ | ✅ | $total_size | $file_count files |"
fi
echo ""
echo "### 📊 Bundle Analysis"
echo "| Metric | Value |"
echo "|--------|-------|"
echo "| Size (bytes) | $bundle_size_bytes |"
echo "| Size (human) | $bundle_size |"
if [ "$bundle_size_bytes" -gt 5000000 ]; then
echo "| Status | ⚠️ Large (>5MB) |"
elif [ "$bundle_size_bytes" -gt 1000000 ]; then
echo "| Status | ✅ Medium (1-5MB) |"
else
echo "| Status | ✅ Small (<1MB) |"
fi
else
echo "| dist/index.js | ❌ | missing | Bundle |"
exit 1
fi
echo ""
echo "✅ **Backend build verification completed**"
- name: 🧪 Test backend bundle execution
run: |
echo "## 🧪 Backend Execution Test"
echo "| Test | Status | Result |"
echo "|------|--------|--------|"
if timeout 10s bun dist/index.js 2>&1 | grep -q "Server running" || true; then
echo "| Bundle Execution | ✅ | Successful |"
echo "| Server Startup | ✅ | Detected |"
else
echo "| Bundle Execution | ⚠️ | No server output |"
fi
echo "| Timeout Test | ✅ | 10s limit |"
echo ""
echo "✅ **Backend execution test completed**"
# 🚀 Full-stack unified build test
fullstack-build-test:
name: 🚀 Full-Stack Unified Build
runs-on: ubuntu-latest
needs: installation-test
steps:
- name: 📥 Checkout repository
uses: actions/checkout@v4
- name: 🚀 Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: ${{ env.BUN_VERSION }}
- name: 📦 Install dependencies
run: bun install
- name: 🏗️ Full unified build
run: |
echo "🔧 Testing unified full-stack build..."
bun run build
- name: ✅ Verify complete build artifacts
run: |
echo "🔍 Checking complete build output..."
# Check frontend artifacts
if [ -d "dist/client" ] && [ -f "dist/client/index.html" ]; then
echo "✅ Frontend build completed"
else
echo "❌ Frontend build incomplete"
exit 1
fi
# Check backend artifacts
if [ -f "dist/index.js" ]; then
echo "✅ Backend build completed"
else
echo "❌ Backend build incomplete"
exit 1
fi
echo "📊 Complete build size:"
du -sh dist/
- name: 🚀 Test production server simulation
run: |
echo "🌐 Testing production server startup..."
timeout 15s bun dist/index.js &
sleep 5
# Test API endpoint
if curl -f http://localhost:3000/api/health; then
echo "✅ Production server API responding"
else
echo "❌ Production server API not responding"
exit 1
fi
# 🔧 Development mode tests
development-mode-test:
name: 🔧 Development Modes Test
runs-on: ubuntu-latest
needs: installation-test
strategy:
matrix:
mode: [frontend, backend]
steps:
- name: 📥 Checkout repository
uses: actions/checkout@v4
- name: 🚀 Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: ${{ env.BUN_VERSION }}
- name: 📦 Install dependencies
run: bun install
- name: 🔧 Test ${{ matrix.mode }} development mode
run: |
echo "🚀 Testing ${{ matrix.mode }} development mode..."
if [ "${{ matrix.mode }}" == "frontend" ]; then
timeout 30s bun run dev:frontend &
sleep 10
if curl -f http://localhost:5173; then
echo "✅ Frontend dev server responding"
else
echo "❌ Frontend dev server not responding"
exit 1
fi
fi
if [ "${{ matrix.mode }}" == "backend" ]; then
timeout 30s bun run dev:backend &
sleep 10
if curl -f http://localhost:3000/api/health; then
echo "✅ Backend dev server responding"
else
echo "❌ Backend dev server not responding"
exit 1
fi
fi
docker-build-test:
name: Docker Build Test
runs-on: ubuntu-latest
needs: [frontend-build-test, backend-build-test]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build Docker image
run: docker build -t fluxstack:test .
timeout-minutes: 5
- name: Test Docker container
run: |
docker run -d -p 3000:3000 --name fluxstack-test fluxstack:test
sleep 15
if curl -f http://localhost:3000/api/health; then
echo "Docker container healthy"
else
echo "Docker container not responding"
docker logs fluxstack-test
exit 1
fi
docker stop fluxstack-test
# 🔄 Hot reload simulation test
hot-reload-test:
name: 🔄 Hot Reload Independence Test
runs-on: ubuntu-latest
needs: installation-test
steps:
- name: 📥 Checkout repository
uses: actions/checkout@v4
- name: 🚀 Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: ${{ env.BUN_VERSION }}
- name: 📦 Install dependencies
run: bun install
- name: 🔥 Test hot reload independence
run: |
echo "🔄 Testing hot reload independence..."
# Start full-stack dev mode
timeout 60s bun run dev &
DEV_PID=$!
sleep 15
# Verify both servers are running
if curl -f http://localhost:3000/api/health && curl -f http://localhost:5173; then
echo "✅ Both frontend and backend started successfully"
else
echo "❌ Development servers failed to start"
kill $DEV_PID 2>/dev/null || true
exit 1
fi
kill $DEV_PID 2>/dev/null || true
# 📊 Performance benchmarks
performance-test:
name: 📊 Performance Benchmarks
runs-on: ubuntu-latest
needs: installation-test
steps:
- name: 📥 Checkout repository
uses: actions/checkout@v4
- name: 🚀 Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: ${{ env.BUN_VERSION }}
- name: ⏱️ Benchmark installation speed
run: |
echo "## ⚡ Installation Performance Benchmark"
rm -rf node_modules bun.lockb
time_start=$(date +%s%3N)
bun install
time_end=$(date +%s%3N)
duration=$((time_end - time_start))
echo "| Metric | Value | Target | Status |"
echo "|--------|-------|--------|--------|"
echo "| Install Time | ${duration}ms | <15000ms | $([[ $duration -lt 15000 ]] && echo '✅ PASS' || echo '⚠️ SLOW') |"
# Additional metrics
package_count=$(bun pm ls --depth=0 | wc -l)
node_modules_size=$(du -sh node_modules | cut -f1)
echo "| Package Count | $package_count | - | ℹ️ |"
echo "| node_modules Size | $node_modules_size | - | ℹ️ |"
duration_seconds=$((duration / 1000))
packages_per_second=$((package_count / duration_seconds))
echo "| Packages/Second | $packages_per_second | - | ℹ️ |"
echo ""
if [ $duration -lt 15000 ]; then
echo "✅ **Installation performance acceptable** (${duration}ms)"
else
echo "⚠️ **Installation slower than expected** (${duration}ms vs 15000ms target)"
fi
- name: ⏱️ Benchmark build performance
run: |
echo "## 🏗️ Build Performance Benchmarks"
echo "| Build Type | Duration | Target | Status | Output Size |"
echo "|------------|----------|--------|--------|-------------|"
# Frontend build benchmark
time_start=$(date +%s%3N)
bun run build:frontend
time_end=$(date +%s%3N)
frontend_duration=$((time_end - time_start))
frontend_size="0B"
if [ -d "dist/client" ]; then
frontend_size=$(du -sh dist/client | cut -f1)
fi
echo "| 🎨 Frontend | ${frontend_duration}ms | <30000ms | $([[ $frontend_duration -lt 30000 ]] && echo '✅ FAST' || echo '⚠️ SLOW') | $frontend_size |"
# Backend build benchmark
rm -rf dist/index.js 2>/dev/null || true
time_start=$(date +%s%3N)
bun run build:backend
time_end=$(date +%s%3N)
backend_duration=$((time_end - time_start))
backend_size="0B"
if [ -f "dist/index.js" ]; then
backend_size=$(du -sh dist/index.js | cut -f1)
fi
echo "| ⚡ Backend | ${backend_duration}ms | <20000ms | $([[ $backend_duration -lt 20000 ]] && echo '✅ FAST' || echo '⚠️ SLOW') | $backend_size |"
# Total unified build
rm -rf dist/ 2>/dev/null || true
time_start=$(date +%s%3N)
bun run build
time_end=$(date +%s%3N)
total_duration=$((time_end - time_start))
total_size="0B"
if [ -d "dist" ]; then
total_size=$(du -sh dist | cut -f1)
fi
echo "| 🚀 Full-Stack | ${total_duration}ms | <45000ms | $([[ $total_duration -lt 45000 ]] && echo '✅ FAST' || echo '⚠️ SLOW') | $total_size |"
echo ""
echo "### 📊 Build Efficiency Analysis"
echo "| Metric | Value |"
echo "|--------|-------|"
# Calculate efficiency metrics
total_seconds=$((total_duration / 1000))
if [ $total_seconds -gt 0 ]; then
mb_per_second="0"
if [ -d "dist" ]; then
total_bytes=$(du -sb dist | cut -f1)
total_mb=$((total_bytes / 1024 / 1024))
if [ $total_mb -gt 0 ]; then
mb_per_second=$((total_mb / total_seconds))
fi
fi
echo "| Build Speed | ${mb_per_second}MB/s |"
fi
frontend_seconds=$((frontend_duration / 1000))
backend_seconds=$((backend_duration / 1000))
if [ $frontend_seconds -gt $backend_seconds ]; then
parallel_estimate=$frontend_seconds
else
parallel_estimate=$backend_seconds
fi
echo "| Sequential Time | ${total_seconds}s |"
echo "| Parallel Estimate | ${parallel_estimate}s |"
echo "| Time Saved | $((total_seconds - parallel_estimate))s |"
echo ""
echo "✅ **Build performance analysis completed**"
# ✅ Summary job
build-summary:
name: ✅ Build Test Summary
runs-on: ubuntu-latest
needs: [
installation-test,
test-suite,
frontend-build-test,
backend-build-test,
fullstack-build-test,
development-mode-test,
hot-reload-test,
performance-test
]
if: always()
steps:
- name: 📋 Build Summary
run: |
echo "# 🎉 FluxStack v1.4.0 Build Test Summary"
echo ""
echo "## 📊 Test Results Overview"
echo "| Test Suite | Status | Duration |"
echo "|------------|--------|----------|"
# Format each result with appropriate emoji
installation_icon="$([[ "${{ needs.installation-test.result }}" == "success" ]] && echo '✅' || echo '❌')"
test_suite_icon="$([[ "${{ needs.test-suite.result }}" == "success" ]] && echo '✅' || echo '❌')"
frontend_icon="$([[ "${{ needs.frontend-build-test.result }}" == "success" ]] && echo '✅' || echo '❌')"
backend_icon="$([[ "${{ needs.backend-build-test.result }}" == "success" ]] && echo '✅' || echo '❌')"
fullstack_icon="$([[ "${{ needs.fullstack-build-test.result }}" == "success" ]] && echo '✅' || echo '❌')"
dev_modes_icon="$([[ "${{ needs.development-mode-test.result }}" == "success" ]] && echo '✅' || echo '❌')"
hot_reload_icon="$([[ "${{ needs.hot-reload-test.result }}" == "success" ]] && echo '✅' || echo '❌')"
performance_icon="$([[ "${{ needs.performance-test.result }}" == "success" ]] && echo '✅' || echo '❌')"
echo "| 📦 Monorepo Installation | $installation_icon ${{ needs.installation-test.result }} | - |"
echo "| 🧪 Test Suite (30 tests) | $test_suite_icon ${{ needs.test-suite.result }} | - |"
echo "| 🎨 Frontend Build | $frontend_icon ${{ needs.frontend-build-test.result }} | - |"
echo "| ⚡ Backend Build | $backend_icon ${{ needs.backend-build-test.result }} | - |"
echo "| 🚀 Full-Stack Build | $fullstack_icon ${{ needs.fullstack-build-test.result }} | - |"
echo "| 🔧 Development Modes | $dev_modes_icon ${{ needs.development-mode-test.result }} | - |"
echo "| 🔄 Hot Reload | $hot_reload_icon ${{ needs.hot-reload-test.result }} | - |"
echo "| 📈 Performance | $performance_icon ${{ needs.performance-test.result }} | - |"
echo ""
# Count successes
success_count=0
total_count=8
[[ "${{ needs.installation-test.result }}" == "success" ]] && success_count=$((success_count + 1)) || true
[[ "${{ needs.test-suite.result }}" == "success" ]] && success_count=$((success_count + 1)) || true
[[ "${{ needs.frontend-build-test.result }}" == "success" ]] && success_count=$((success_count + 1)) || true
[[ "${{ needs.backend-build-test.result }}" == "success" ]] && success_count=$((success_count + 1)) || true
[[ "${{ needs.fullstack-build-test.result }}" == "success" ]] && success_count=$((success_count + 1)) || true
[[ "${{ needs.development-mode-test.result }}" == "success" ]] && success_count=$((success_count + 1)) || true
[[ "${{ needs.hot-reload-test.result }}" == "success" ]] && success_count=$((success_count + 1)) || true
[[ "${{ needs.performance-test.result }}" == "success" ]] && success_count=$((success_count + 1)) || true
success_percentage=$((success_count * 100 / total_count))
echo "## 📈 Overall Results"
echo "| Metric | Value |"
echo "|--------|-------|"
echo "| Success Rate | $success_count/$total_count ($success_percentage%) |"
echo "| Failed Tests | $((total_count - success_count)) |"
echo "| Status | $([[ $success_count -eq $total_count ]] && echo '🎉 ALL PASSED' || echo '❌ SOME FAILED') |"
echo ""
if [ $success_count -eq $total_count ]; then
echo "🎉 **FluxStack v1.4.0 monorepo architecture fully validated!**"
echo "✅ Ready for production deployment"
else
echo "❌ **Some tests failed - check individual job results**"
echo "⚠️ Review failed tests before proceeding"
echo "📊 Detailed Results:"
echo "- Installation: ${{ needs.installation-test.result }}"
echo "- Test Suite: ${{ needs.test-suite.result }}"
echo "- Frontend: ${{ needs.frontend-build-test.result }}"
echo "- Backend: ${{ needs.backend-build-test.result }}"
echo "- Full-Stack: ${{ needs.fullstack-build-test.result }}"
echo "- Dev Modes: ${{ needs.development-mode-test.result }}"
echo "- Hot Reload: ${{ needs.hot-reload-test.result }}"
echo "- Performance: ${{ needs.performance-test.result }}"
exit 1
fi