mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-20 06:44:32 +00:00
refactor: migrate to Vercel-native deployment for branch status pages
- Remove GitHub Pages workflow (release-pages.yml) - Add Vercel configuration (vercel.json) - Create artifact fetcher script (scripts/fetch-branch-artifacts.sh) - Fetches Storybook from Cloudflare Pages - Downloads E2E/Vitest reports from GitHub Actions - Uses gh CLI for API access - Update build script with graceful fallbacks - Creates placeholder pages for pending CI - Supports both local and Vercel environments - Handles missing artifacts gracefully - Add pages:build:branch-status npm script - Update documentation with new deployment approach Benefits: - Deploys immediately on every push - Fetches artifacts on-demand during build - Shows loading states for pending CI - Simpler, more reliable architecture - No complex artifact passing between GitHub Actions and Vercel Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,75 +1,203 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeuo pipefail
|
||||
set -Eeo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "$ROOT_DIR"
|
||||
|
||||
echo "======================================================================"
|
||||
echo "Building Branch Status Pages"
|
||||
echo "======================================================================"
|
||||
echo ""
|
||||
|
||||
# Build or reuse Storybook
|
||||
# Helper function to create placeholder HTML
|
||||
create_placeholder() {
|
||||
local dir="$1"
|
||||
local title="$2"
|
||||
local message="$3"
|
||||
|
||||
mkdir -p "$dir"
|
||||
cat > "$dir/index.html" <<EOF
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>$title</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: system-ui, -apple-system, sans-serif;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
margin: 0;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
}
|
||||
.container {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 1rem;
|
||||
backdrop-filter: blur(10px);
|
||||
max-width: 600px;
|
||||
}
|
||||
h1 { margin-top: 0; }
|
||||
.spinner {
|
||||
border: 4px solid rgba(255, 255, 255, 0.3);
|
||||
border-top: 4px solid white;
|
||||
border-radius: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
animation: spin 1s linear infinite;
|
||||
margin: 2rem auto;
|
||||
}
|
||||
@keyframes spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>$title</h1>
|
||||
<div class="spinner"></div>
|
||||
<p>$message</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Storybook
|
||||
# ============================================================================
|
||||
echo "[build-pages] Setting up Storybook"
|
||||
rm -rf ".pages/storybook"
|
||||
if [ -d "./storybook-static" ] && [ "$(find ./storybook-static -name '*.html' | wc -l)" -gt 0 ]; then
|
||||
echo "✅ Reusing downloaded Storybook build"
|
||||
|
||||
if [ -f ".page/storybook-url.txt" ]; then
|
||||
# Fetched Storybook URL available - create redirect
|
||||
STORYBOOK_URL=$(cat ".page/storybook-url.txt")
|
||||
echo " ✅ Using Storybook from: $STORYBOOK_URL"
|
||||
mkdir -p ".pages/storybook"
|
||||
cat > ".pages/storybook/index.html" <<EOF
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; url=$STORYBOOK_URL">
|
||||
<title>Redirecting to Storybook...</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Redirecting to <a href="$STORYBOOK_URL">Storybook</a>...</p>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
elif [ -d "./storybook-static" ] && [ "$(find ./storybook-static -name '*.html' 2>/dev/null | wc -l)" -gt 0 ]; then
|
||||
echo " ✅ Using local Storybook build"
|
||||
cp -r "./storybook-static" ".pages/storybook"
|
||||
elif [ -d ".page/storybook-static" ]; then
|
||||
echo " ✅ Using fetched Storybook build"
|
||||
cp -r ".page/storybook-static" ".pages/storybook"
|
||||
else
|
||||
echo "🔨 Building Storybook from source"
|
||||
pnpm build-storybook && cp -r "storybook-static" ".pages/storybook"
|
||||
echo " ⚠️ No Storybook build available, creating placeholder"
|
||||
create_placeholder ".pages/storybook" "Storybook" \
|
||||
"Storybook is being built by CI. Please check back in a few minutes."
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
# Nx Dependency Graph
|
||||
# ============================================================================
|
||||
echo "[build-pages] Generating Nx dependency graph"
|
||||
rm -rf ".pages/nx-graph" && mkdir -p ".pages/nx-graph"
|
||||
pnpm nx graph --file=".pages/nx-graph/index.html"
|
||||
|
||||
# Generate or reuse Vitest test reports
|
||||
if pnpm nx graph --file=".pages/nx-graph/index.html" 2>/dev/null; then
|
||||
echo " ✅ Nx graph generated"
|
||||
else
|
||||
echo " ⚠️ Nx graph generation failed, creating placeholder"
|
||||
create_placeholder ".pages/nx-graph" "Nx Dependency Graph" \
|
||||
"Graph generation is not available in this environment."
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
# Playwright E2E Test Reports
|
||||
# ============================================================================
|
||||
echo "[build-pages] Setting up Playwright test reports"
|
||||
rm -rf ".pages/playwright-reports" && mkdir -p ".pages/playwright-reports"
|
||||
|
||||
if [ -d ".page/playwright-reports" ] && [ "$(find .page/playwright-reports -name '*.html' 2>/dev/null | wc -l)" -gt 0 ]; then
|
||||
echo " ✅ Using fetched Playwright reports"
|
||||
cp -r ".page/playwright-reports/"* ".pages/playwright-reports/" 2>/dev/null || true
|
||||
elif [ -d "./playwright-report" ] && [ "$(find ./playwright-report -name '*.html' 2>/dev/null | wc -l)" -gt 0 ]; then
|
||||
echo " ✅ Using local Playwright reports"
|
||||
cp -r "./playwright-report/"* ".pages/playwright-reports/" 2>/dev/null || true
|
||||
else
|
||||
echo " ℹ️ No Playwright reports available, creating placeholder"
|
||||
create_placeholder ".pages/playwright-reports" "E2E Test Reports" \
|
||||
"Playwright tests are running in CI. Results will appear here when complete."
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
# Vitest Test Reports
|
||||
# ============================================================================
|
||||
echo "[build-pages] Setting up Vitest test reports"
|
||||
rm -rf ".pages/vitest-reports" && mkdir -p ".pages/vitest-reports"
|
||||
if [ -d ".page/vitest-reports" ]; then
|
||||
echo "✅ Reusing downloaded Vitest reports"
|
||||
cp -r ".page/vitest-reports/"* ".pages/vitest-reports/" 2>/dev/null || echo "⚠️ No vitest reports to copy"
|
||||
|
||||
if [ -d ".page/vitest-reports" ] && [ -f ".page/vitest-reports/index.html" ]; then
|
||||
echo " ✅ Using fetched Vitest reports"
|
||||
cp -r ".page/vitest-reports/"* ".pages/vitest-reports/" 2>/dev/null || true
|
||||
else
|
||||
echo "🔨 Generating Vitest reports from source"
|
||||
pnpm exec vitest \
|
||||
--reporter=json --outputFile.json=".pages/vitest-reports/results.json" \
|
||||
--reporter=html --outputFile.html=".pages/vitest-reports/index.html" \
|
||||
--run
|
||||
echo " ℹ️ No Vitest reports available, creating placeholder"
|
||||
create_placeholder ".pages/vitest-reports" "Vitest Test Reports" \
|
||||
"Unit tests are running in CI. Results will appear here when complete."
|
||||
fi
|
||||
|
||||
# Set up Playwright test reports if available
|
||||
echo "[build-pages] Setting up Playwright test reports"
|
||||
if [ -d ".page/playwright-reports" ]; then
|
||||
echo "✅ Reusing downloaded Playwright reports"
|
||||
mkdir -p ".pages/playwright-reports"
|
||||
cp -r ".page/playwright-reports/"* ".pages/playwright-reports/" 2>/dev/null || echo "⚠️ No playwright reports to copy"
|
||||
fi
|
||||
|
||||
echo "[build-pages] Generating coverage report"
|
||||
# ============================================================================
|
||||
# Coverage Report (Optional - slow to generate)
|
||||
# ============================================================================
|
||||
echo "[build-pages] Setting up coverage report"
|
||||
mkdir -p ".pages/coverage"
|
||||
if pnpm exec vitest --run --coverage --coverage.reporter=html --coverage.reportsDirectory=".pages/coverage"; then
|
||||
echo "✅ Coverage report completed"
|
||||
|
||||
if [ -d ".page/coverage" ] && [ -f ".page/coverage/index.html" ]; then
|
||||
echo " ✅ Using fetched coverage report"
|
||||
cp -r ".page/coverage/"* ".pages/coverage/" 2>/dev/null || true
|
||||
else
|
||||
echo "⚠️ Coverage report failed, continuing..."
|
||||
echo " ℹ️ Coverage report not available (skipping generation in Vercel)"
|
||||
create_placeholder ".pages/coverage" "Coverage Report" \
|
||||
"Code coverage is generated in CI. Results will appear here when complete."
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
# Knip Report (Fast - generate fresh)
|
||||
# ============================================================================
|
||||
echo "[build-pages] Generating Knip report"
|
||||
mkdir -p ".pages/knip"
|
||||
rm -f ".pages/knip/report.md"
|
||||
if pnpm knip --reporter markdown --no-progress --no-exit-code > ".pages/knip/report.md" 2>/dev/null && [ -s ".pages/knip/report.md" ]; then
|
||||
echo "✅ Knip report generated at .pages/knip/report.md"
|
||||
else
|
||||
echo "⚠️ Knip report failed, creating placeholder..."
|
||||
cat > ".pages/knip/report.md" <<'EOF'
|
||||
# Knip report
|
||||
|
||||
> ⚠️ Knip report unavailable.
|
||||
>
|
||||
> Generation failed during build. See CI logs for details.
|
||||
if pnpm knip --reporter markdown --no-progress --no-exit-code > ".pages/knip/report.md" 2>/dev/null && [ -s ".pages/knip/report.md" ]; then
|
||||
echo " ✅ Knip report generated"
|
||||
else
|
||||
echo " ⚠️ Knip report failed, creating placeholder"
|
||||
cat > ".pages/knip/report.md" <<'EOF'
|
||||
# Knip Report
|
||||
|
||||
> ⚠️ Knip report generation failed
|
||||
|
||||
Knip analysis could not be completed in this build environment.
|
||||
Please check the CI logs for details.
|
||||
EOF
|
||||
fi
|
||||
|
||||
echo "[build-pages] Landing page already exists at .pages/index.html"
|
||||
|
||||
echo "[build-pages] Build artifacts ready in ./.pages"
|
||||
|
||||
echo "[build-pages] Note: For local dev, you can develop the .pages/index.html using:
|
||||
pnpm exec vite .pages
|
||||
"
|
||||
# ============================================================================
|
||||
# Summary
|
||||
# ============================================================================
|
||||
echo ""
|
||||
echo "======================================================================"
|
||||
echo "Build Complete"
|
||||
echo "======================================================================"
|
||||
echo ""
|
||||
echo "Generated artifacts in ./.pages:"
|
||||
echo ""
|
||||
ls -lh ".pages" 2>/dev/null | tail -n +2 | awk '{print " " $9}'
|
||||
echo ""
|
||||
echo "Note: For local development, run:"
|
||||
echo " pnpm pages:dev"
|
||||
echo ""
|
||||
|
||||
168
scripts/fetch-branch-artifacts.sh
Executable file
168
scripts/fetch-branch-artifacts.sh
Executable file
@@ -0,0 +1,168 @@
|
||||
#!/usr/bin/env bash
|
||||
set -Eeo pipefail
|
||||
|
||||
# Fetch test artifacts from deployed sources for branch status page
|
||||
# This script runs in Vercel's build environment to fetch test results
|
||||
# without waiting for all CI to complete
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "$ROOT_DIR"
|
||||
|
||||
BRANCH="${VERCEL_GIT_COMMIT_REF:-$(git branch --show-current)}"
|
||||
COMMIT_SHA="${VERCEL_GIT_COMMIT_SHA:-$(git rev-parse HEAD)}"
|
||||
|
||||
echo "[fetch-artifacts] Fetching artifacts for branch: $BRANCH (commit: ${COMMIT_SHA:0:7})"
|
||||
|
||||
# Create artifact staging directory
|
||||
ARTIFACT_DIR=".page"
|
||||
mkdir -p "$ARTIFACT_DIR"
|
||||
|
||||
# ============================================================================
|
||||
# Fetch Storybook from Cloudflare Pages
|
||||
# ============================================================================
|
||||
fetch_storybook() {
|
||||
echo "[fetch-artifacts] Fetching Storybook from Cloudflare Pages..."
|
||||
|
||||
# Try to get Storybook URL from recent PR comment
|
||||
if command -v gh &> /dev/null && [ -n "$GITHUB_TOKEN" ]; then
|
||||
# Get PR number for current branch
|
||||
PR_NUMBER=$(gh pr list --head "$BRANCH" --json number --jq '.[0].number' 2>/dev/null || echo "")
|
||||
|
||||
if [ -n "$PR_NUMBER" ]; then
|
||||
echo " Found PR #$PR_NUMBER"
|
||||
|
||||
# Look for Storybook URL in comments
|
||||
STORYBOOK_URL=$(gh api "repos/{owner}/{repo}/issues/$PR_NUMBER/comments" \
|
||||
--jq '.[] | select(.body | contains("Storybook")) | .body' 2>/dev/null \
|
||||
| grep -oP 'https://[a-z0-9]+-comfyui-frontend\.pages\.dev' \
|
||||
| head -1 || echo "")
|
||||
|
||||
if [ -n "$STORYBOOK_URL" ]; then
|
||||
echo " Found Storybook URL: $STORYBOOK_URL"
|
||||
|
||||
# Download and extract storybook
|
||||
if curl -sSL "$STORYBOOK_URL" -o /dev/null -w "%{http_code}" | grep -q "200"; then
|
||||
echo " ✅ Storybook is accessible, will reference URL"
|
||||
echo "$STORYBOOK_URL" > "$ARTIFACT_DIR/storybook-url.txt"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo " ⚠️ Could not fetch Storybook URL (will show placeholder)"
|
||||
return 1
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Fetch E2E Test Results from GitHub Actions
|
||||
# ============================================================================
|
||||
fetch_e2e_reports() {
|
||||
echo "[fetch-artifacts] Fetching E2E test results from GitHub Actions..."
|
||||
|
||||
if ! command -v gh &> /dev/null; then
|
||||
echo " ⚠️ GitHub CLI not installed, skipping E2E reports"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "$GITHUB_TOKEN" ]; then
|
||||
echo " ⚠️ GITHUB_TOKEN not set, skipping E2E reports"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Get latest workflow run for this commit or branch
|
||||
WORKFLOW_RUN=$(gh api \
|
||||
"repos/{owner}/{repo}/actions/runs?head_sha=$COMMIT_SHA&status=completed" \
|
||||
--jq '.workflow_runs | map(select(.name == "Tests CI")) | .[0]' 2>/dev/null || echo "{}")
|
||||
|
||||
RUN_ID=$(echo "$WORKFLOW_RUN" | jq -r '.id // empty')
|
||||
|
||||
if [ -z "$RUN_ID" ]; then
|
||||
echo " ℹ️ No completed test runs found for commit $COMMIT_SHA"
|
||||
|
||||
# Try latest on branch instead
|
||||
RUN_ID=$(gh api \
|
||||
"repos/{owner}/{repo}/actions/runs?branch=$BRANCH&status=completed" \
|
||||
--jq '.workflow_runs | map(select(.name == "Tests CI")) | .[0].id // empty' 2>/dev/null || echo "")
|
||||
fi
|
||||
|
||||
if [ -n "$RUN_ID" ]; then
|
||||
echo " Found workflow run: $RUN_ID"
|
||||
|
||||
# Download playwright-report artifact
|
||||
if gh run download "$RUN_ID" -n playwright-report -D "$ARTIFACT_DIR/playwright-reports" 2>/dev/null; then
|
||||
echo " ✅ Downloaded E2E test reports"
|
||||
return 0
|
||||
else
|
||||
echo " ℹ️ playwright-report artifact not yet available"
|
||||
fi
|
||||
else
|
||||
echo " ℹ️ No completed workflow runs found"
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Fetch Vitest Results from GitHub Actions
|
||||
# ============================================================================
|
||||
fetch_vitest_reports() {
|
||||
echo "[fetch-artifacts] Fetching Vitest results from GitHub Actions..."
|
||||
|
||||
if ! command -v gh &> /dev/null || [ -z "$GITHUB_TOKEN" ]; then
|
||||
echo " ⚠️ Skipping (GitHub CLI or token not available)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Similar logic to E2E, but for vitest artifacts
|
||||
RUN_ID=$(gh api \
|
||||
"repos/{owner}/{repo}/actions/runs?head_sha=$COMMIT_SHA&status=completed" \
|
||||
--jq '.workflow_runs | map(select(.name == "Vitest Tests")) | .[0].id // empty' 2>/dev/null || echo "")
|
||||
|
||||
if [ -z "$RUN_ID" ]; then
|
||||
RUN_ID=$(gh api \
|
||||
"repos/{owner}/{repo}/actions/runs?branch=$BRANCH&status=completed" \
|
||||
--jq '.workflow_runs | map(select(.name == "Vitest Tests")) | .[0].id // empty' 2>/dev/null || echo "")
|
||||
fi
|
||||
|
||||
if [ -n "$RUN_ID" ]; then
|
||||
echo " Found workflow run: $RUN_ID"
|
||||
|
||||
if gh run download "$RUN_ID" -n vitest-report -D "$ARTIFACT_DIR/vitest-reports" 2>/dev/null; then
|
||||
echo " ✅ Downloaded Vitest reports"
|
||||
return 0
|
||||
else
|
||||
echo " ℹ️ vitest-report artifact not yet available"
|
||||
fi
|
||||
else
|
||||
echo " ℹ️ No completed Vitest runs found"
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Main execution
|
||||
# ============================================================================
|
||||
|
||||
echo ""
|
||||
echo "======================================================================"
|
||||
echo "Fetching Branch Artifacts"
|
||||
echo "======================================================================"
|
||||
echo ""
|
||||
|
||||
# Run all fetchers (don't fail if some are unavailable)
|
||||
fetch_storybook || true
|
||||
fetch_e2e_reports || true
|
||||
fetch_vitest_reports || true
|
||||
|
||||
echo ""
|
||||
echo "======================================================================"
|
||||
echo "Artifact Fetch Complete"
|
||||
echo "======================================================================"
|
||||
echo ""
|
||||
echo "Available artifacts:"
|
||||
ls -lh "$ARTIFACT_DIR" 2>/dev/null || echo " (none)"
|
||||
echo ""
|
||||
echo "Note: Missing artifacts will show placeholder content in the status page"
|
||||
echo ""
|
||||
Reference in New Issue
Block a user