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:
snomiao
2026-02-12 08:07:33 +00:00
parent 2a466af154
commit 01a2ca3bcf
7 changed files with 466 additions and 339 deletions

View File

@@ -1,186 +0,0 @@
name: Deploy to GitHub Pages
description: Build and deploy to GitHub Pages and Vercel on successful completion of tests and builds
on:
# Triggers when any of these workflows complete on main branch
# Runs ONCE per workflow completion (e.g., if "Vitest Tests" completes, this workflow runs once)
workflow_run:
workflows: ['Storybook and Chromatic CI', 'Vitest Tests', 'Tests CI']
types: [completed]
# Allow direct pushes to the debug branch to kick off the full pipeline
push:
branches: [sno-deploy-ghpage]
# Keep manual trigger for debugging
workflow_dispatch:
jobs:
incremental-build:
runs-on: ubuntu-latest
# Only run if the triggering workflow succeeded (or manual dispatch/push)
if: github.event_name == 'workflow_dispatch' || github.event_name == 'push' || github.event.workflow_run.conclusion == 'success'
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 10
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: '24'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Cache build artifacts
uses: actions/cache@v4
with:
path: |
.pages
storybook-static
coverage
key: build-cache-${{ github.ref_name }}-${{ github.run_id }}-${{ hashFiles('pnpm-lock.yaml', 'package.json') }}
restore-keys: |
build-cache-${{ github.ref_name }}-
build-cache-main-
- name: Download Storybook artifact (source run)
id: fetch_storybook_trigger
continue-on-error: true
if: github.event_name == 'workflow_run' && github.event.workflow_run.name == 'Storybook and Chromatic CI'
uses: dawidd6/action-download-artifact@v6
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: storybook-and-chromatic-ci.yaml
name: storybook-static
run_id: ${{ github.event.workflow_run.id }}
path: storybook-static
- name: Download Storybook artifact (latest successful run on main)
continue-on-error: true
if: steps.fetch_storybook_trigger.outcome != 'success'
uses: dawidd6/action-download-artifact@v6
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: storybook-and-chromatic-ci.yaml
name: storybook-static
branch: main
workflow_conclusion: success
path: storybook-static
- name: Download Vitest reports (source run)
id: fetch_vitest_trigger
continue-on-error: true
if: github.event_name == 'workflow_run' && github.event.workflow_run.name == 'Vitest Tests'
uses: dawidd6/action-download-artifact@v6
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: vitest-tests.yaml
name: vitest-reports
run_id: ${{ github.event.workflow_run.id }}
path: ./.pages/vitest-reports
- name: Download Vitest reports (latest successful run on main)
continue-on-error: true
if: steps.fetch_vitest_trigger.outcome != 'success'
uses: dawidd6/action-download-artifact@v6
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: vitest-tests.yaml
name: vitest-reports
branch: main
workflow_conclusion: success
path: ./.pages/vitest-reports
- name: Download Playwright E2E reports (source run)
id: fetch_playwright_trigger
continue-on-error: true
if: github.event_name == 'workflow_run' && github.event.workflow_run.name == 'Tests CI'
uses: dawidd6/action-download-artifact@v6
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: ci-tests-e2e.yaml
name_is_regexp: true
name: playwright-report-.*
run_id: ${{ github.event.workflow_run.id }}
path: ./playwright-reports-temp
- name: Download Playwright E2E reports (latest successful run on main)
continue-on-error: true
if: steps.fetch_playwright_trigger.outcome != 'success'
uses: dawidd6/action-download-artifact@v6
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: ci-tests-e2e.yaml
name_is_regexp: true
name: playwright-report-.*
branch: main
workflow_conclusion: success
path: ./playwright-reports-temp
- name: Organize Playwright reports by browser
if: always()
run: |
mkdir -p ./.pages/playwright-reports
# Move each browser report to its own directory
if [ -d "./playwright-reports-temp" ]; then
for dir in ./playwright-reports-temp/playwright-report-*; do
if [ -d "$dir" ]; then
browser_name=$(basename "$dir" | sed 's/playwright-report-//')
mkdir -p "./.pages/playwright-reports/${browser_name}"
cp -r "$dir"/* "./.pages/playwright-reports/${browser_name}/"
fi
done
fi
- name: Build static assets (with artifact reuse)
run: ./scripts/build-pages.sh
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Upload built pages as cache
uses: actions/upload-pages-artifact@v4
with:
name: built-pages
path: '.pages'
deploy-vercel-app:
runs-on: ubuntu-latest
needs: incremental-build
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: download built pages
uses: actions/download-artifact@v4
with:
name: built-pages
path: ./artifact
- name: Extract artifact
run: |
mkdir -p ./.pages
cd ./artifact
tar -xf artifact.tar -C ../.pages
# debug ls of ./.pages
- name: List ./.pages contents
run: ls -la ./.pages
- name: Deploy to Vercel
uses: amondnet/vercel-action@v20
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
working-directory: .pages
vercel-args: ${{ github.ref_name == 'main' && '--prod' || '' }}
github-comment: true
alias-domains: |
${{ github.ref_name }}-comfyui-frontend-reports.vercel.app

3
.gitignore vendored
View File

@@ -97,4 +97,7 @@ vitest.config.*.timestamp*
/.pages/*/**/*
/.pages-dist/
# Fetched artifacts for Vercel builds
/.page/
.vercel

View File

@@ -1,160 +1,153 @@
# GitHub Pages Deployment
# Branch Status Pages
This document describes the GitHub Pages deployment setup for ComfyUI Frontend development tools.
This directory contains the source for the branch status pages that aggregate development tools and test reports.
## Overview
## Deployment
The project automatically deploys the following development tools to GitHub Pages on every merge to the `main` branch:
The branch status pages are automatically deployed to **Vercel** on every push to any branch.
- **Storybook** - Interactive component library and design system documentation
- **Nx Dependency Graph** - Visual representation of project dependencies
- **Test Coverage Reports** - Code coverage from Vitest unit tests
- **Vitest Results** - Interactive test results and reports
- **Knip Report** - Unused code and dependency analysis
### Architecture
## Accessing the Tools
Once deployed, all tools are accessible from a single landing page at:
```
https://comfy-org.github.io/ComfyUI_frontend/
Push to Branch
├─→ GitHub Actions (runs tests, deploys artifacts)
│ ├─→ Storybook → Cloudflare Pages
│ ├─→ E2E Tests → GitHub Actions Artifacts
│ └─→ Vitest → GitHub Actions Artifacts
└─→ Vercel (auto-triggered)
Runs: pnpm pages:build:branch-status
1. Fetches test results from deployed sources
2. Builds status pages
3. Deploys automatically
```
## Primary Use Case: Storybook for Design Team
### URLs
The primary motivation for this deployment is to provide the design team with a consistent, bookmarkable URL to reference the latest component system state. Instead of sharing PR-specific Storybook builds, the design team can always access the latest approved components from the main branch.
- **Production** (main branch): `https://comfyui-frontend-reports.vercel.app`
- **Preview** (PR branches): `https://<branch>-comfyui-frontend-reports.vercel.app`
## Deployment Workflow
## What's Included
The deployment is managed by the `.github/workflows/release-pages.yml` workflow, which:
The branch status page aggregates:
1. **Triggers on**:
- Push to `main` branch
- Manual workflow dispatch
1. **Storybook** - Component library documentation
2. **Nx Dependency Graph** - Project structure visualization
3. **Playwright Reports** - E2E test results
4. **Vitest Reports** - Unit test results
5. **Coverage Report** - Code coverage metrics
6. **Knip Report** - Unused code and dependency analysis
2. **Build Process**:
- Installs dependencies with pnpm
- Runs `scripts/build-pages.sh` to generate Storybook, Nx dependency graph, Vitest reports, coverage, and Knip analysis
- Creates a landing page with links to all tools
## How It Works
3. **Deployment**:
- Uses GitHub Pages deploy action
- Deploys to `gh-pages` branch
- Available at the GitHub Pages URL
### Artifact Fetching
## Workflow Details
The `scripts/fetch-branch-artifacts.sh` script fetches test results from:
### Build Steps
- **Storybook**: Deployed to Cloudflare Pages (fetches URL from PR comments)
- **E2E/Vitest**: Downloaded from GitHub Actions artifacts using `gh` CLI
- **Knip**: Generated fresh during build (fast)
The build script handles optional tooling gracefully—if an individual tool fails to build, the remainder of the deployment still proceeds and the failure is logged as a warning.
### Graceful Fallbacks
If artifacts aren't available yet (CI still running), the build script creates placeholder pages with loading indicators. This allows Vercel to deploy immediately without waiting for all CI to complete.
## Local Development
#### Storybook (Required)
```bash
pnpm build-storybook --output-dir dist/storybook
# Develop the index page
pnpm pages:dev
# Build without fetching artifacts (uses local builds)
pnpm pages:build
# Build with artifact fetching (simulates Vercel)
pnpm pages:build:branch-status
```
#### Nx Graph (Optional)
```bash
pnpm nx graph --file=dist/nx-graph/index.html
```
## Environment Variables (Vercel)
#### Test Coverage (Optional)
```bash
pnpm exec vitest --run --coverage --coverage.reporter=html
```
Configure these in Vercel project settings:
#### Vitest Results (Optional)
```bash
pnpm exec vitest --run --reporter=html --outputFile dist/vitest-ui/index.html
```
- `GITHUB_TOKEN` - For fetching artifacts via GitHub API (required)
- `CLOUDFLARE_ACCOUNT_ID` - For Cloudflare API (optional)
- `CLOUDFLARE_API_TOKEN` - For Cloudflare API (optional)
#### Knip Report (Optional)
```bash
pnpm knip --reporter json
```
## Files
### Permissions
- **index.html** - Main landing page with links to all reports
- **vite.config.ts** - Vite configuration for building the static site
- **knip.html** - Wrapper for displaying Knip markdown report
- **playwright-reports.html** - Wrapper for E2E test reports
The workflow requires the following permissions:
```yaml
permissions:
contents: read
pages: write
id-token: write
```
## Adding New Reports
## Manual Deployment
To add a new report to the status page:
You can manually trigger a deployment from the GitHub Actions tab:
1. Go to Actions → Deploy to GitHub Pages
2. Click "Run workflow"
3. Select the `main` branch
4. Click "Run workflow"
1. Update `scripts/fetch-branch-artifacts.sh` to fetch the new artifact
2. Update `scripts/build-pages.sh` to process and copy it
3. Add a link in `index.html`
4. Optionally create a wrapper HTML file for custom styling
## Troubleshooting
### Storybook Build Fails
### Artifacts not appearing
If the Storybook build fails:
1. Check that all Storybook stories are syntactically correct
2. Verify that all components can be imported
3. Run `pnpm build-storybook` locally to reproduce the issue
- Check Vercel build logs for fetch errors
- Verify `GITHUB_TOKEN` is set in Vercel environment
- Ensure GitHub Actions workflows completed successfully
- Artifacts may not be available for old commits (7-day retention)
### Other Tools Fail
### Slow builds
Since all tools except Storybook are marked with `continue-on-error: true`, they will not prevent deployment. If a tool consistently fails:
- Artifact fetching is designed to be fast (<30s)
- If builds are slow, check network connectivity to GitHub/Cloudflare
- Consider skipping slow-to-generate reports (like coverage)
1. Check the GitHub Actions logs for the specific error
2. Test the build command locally
3. Consider adjusting the build command in the workflow
### Storybook redirect not working
### GitHub Pages Not Updating
- Verify Cloudflare Pages deployment succeeded
- Check PR comments for correct Storybook URL
- Fallback: Storybook will show placeholder page
If changes aren't reflected on the live site:
## CI Integration
1. Check the workflow run in the Actions tab
2. Verify that the deployment step succeeded
3. GitHub Pages can take a few minutes to update
4. Clear your browser cache or try an incognito window
No GitHub Actions workflow is needed for Vercel deployments. Vercel automatically:
## Maintenance
1. Detects new commits via GitHub webhook
2. Triggers build with `pnpm pages:build:branch-status`
3. Deploys to branch-specific URL
4. Comments on PR with deployment URL
### Adding New Tools
## Migration Notes
To add a new development tool to the deployment:
This replaces the previous GitHub Pages deployment approach which:
- Required complex artifact passing between GitHub Actions and Vercel
- Had to wait for all CI to complete before deploying
- Was prone to failure due to artifact extraction issues
1. Add a new build step in `.github/workflows/release-pages.yml`
2. Ensure the output goes to a subdirectory of `dist/`
3. Add `continue-on-error: true` if the tool is optional
4. Update the landing page `dist/index.html` with a link to the new tool
The new Vercel-native approach:
- Deploys immediately on every push
- Fetches artifacts on-demand during build
- Shows placeholders for pending CI
- Simpler, more reliable architecture
### Removing Tools
## Primary Use Case: Development Team
To remove a tool from deployment:
This deployment provides:
1. Remove the build step from the workflow
2. Remove the corresponding link from the landing page
## Cost Considerations
GitHub Pages is free for public repositories and includes:
- 1 GB storage
- 100 GB bandwidth per month
- 10 builds per hour
This should be more than sufficient for the development tools deployment.
## Security
The deployment only includes static, built artifacts:
- No source code is directly exposed
- No secrets or credentials are included
- All content is publicly accessible (appropriate for public repo)
1. **For Design Team**: Consistent, bookmarkable URL to reference the latest component system state
2. **For Developers**: Quick access to test results and coverage for any branch
3. **For PR Reviews**: Easy verification of Storybook changes and test results
## Related Documentation
- [GitHub Pages Documentation](https://docs.github.com/en/pages)
- [Vercel Documentation](https://vercel.com/docs)
- [Storybook Documentation](https://storybook.js.org/docs)
- [Nx Documentation](https://nx.dev)
- [Vitest Documentation](https://vitest.dev)
- [Knip Documentation](https://knip.dev)
- [Knip Documentation](https://knip.dev)
- [Playwright Documentation](https://playwright.dev)

View File

@@ -12,6 +12,7 @@
"build-storybook": "storybook build",
"build:types": "nx build --config vite.types.config.mts && node scripts/prepare-types.js",
"build:analyze": "cross-env ANALYZE_BUNDLE=true pnpm build",
"build:branch-status": "...",
"build": "cross-env NODE_OPTIONS='--max-old-space-size=8192' pnpm typecheck && nx build",
"size:collect": "node scripts/size-collect.js",
"size:report": "node scripts/size-report.js",
@@ -37,6 +38,7 @@
"locale": "lobe-i18n locale",
"oxlint": "oxlint src --type-aware",
"pages:build": "bash scripts/build-pages.sh && vite build --config ./.pages/vite.config.ts",
"pages:build:branch-status": "bash scripts/fetch-branch-artifacts.sh && bash scripts/build-pages.sh && vite build --config ./.pages/vite.config.ts",
"pages:dev": "vite --config ./.pages/vite.config.ts",
"preinstall": "pnpm dlx only-allow pnpm",
"prepare": "husky || true && git config blame.ignoreRevsFile .git-blame-ignore-revs || true",

View File

@@ -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
View 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 ""

19
vercel.json Normal file
View File

@@ -0,0 +1,19 @@
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"buildCommand": "pnpm pages:build:branch-status",
"outputDirectory": ".pages/dist",
"installCommand": "pnpm install --frozen-lockfile",
"framework": null,
"devCommand": "pnpm pages:dev",
"git": {
"deploymentEnabled": {
"main": true,
"*": true
}
},
"github": {
"enabled": true,
"autoAlias": true,
"silent": false
}
}