From 01a2ca3bcf82af2152ae8521dfab2f55420a72b1 Mon Sep 17 00:00:00 2001 From: snomiao Date: Thu, 12 Feb 2026 08:07:33 +0000 Subject: [PATCH] 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 --- .github/workflows/release-pages.yml | 186 ------------------------ .gitignore | 3 + .pages/README.md | 211 +++++++++++++-------------- package.json | 2 + scripts/build-pages.sh | 216 ++++++++++++++++++++++------ scripts/fetch-branch-artifacts.sh | 168 ++++++++++++++++++++++ vercel.json | 19 +++ 7 files changed, 466 insertions(+), 339 deletions(-) delete mode 100644 .github/workflows/release-pages.yml create mode 100755 scripts/fetch-branch-artifacts.sh create mode 100644 vercel.json diff --git a/.github/workflows/release-pages.yml b/.github/workflows/release-pages.yml deleted file mode 100644 index 943f16db57..0000000000 --- a/.github/workflows/release-pages.yml +++ /dev/null @@ -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 diff --git a/.gitignore b/.gitignore index 7b42c0ef0b..57a73a0cf3 100644 --- a/.gitignore +++ b/.gitignore @@ -97,4 +97,7 @@ vitest.config.*.timestamp* /.pages/*/**/* /.pages-dist/ +# Fetched artifacts for Vercel builds +/.page/ + .vercel diff --git a/.pages/README.md b/.pages/README.md index 3aec49ca01..1efb989e18 100644 --- a/.pages/README.md +++ b/.pages/README.md @@ -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://-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) \ No newline at end of file +- [Knip Documentation](https://knip.dev) +- [Playwright Documentation](https://playwright.dev) diff --git a/package.json b/package.json index d352ef324d..4878b9a664 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/scripts/build-pages.sh b/scripts/build-pages.sh index fe63c086fd..ccd9309746 100755 --- a/scripts/build-pages.sh +++ b/scripts/build-pages.sh @@ -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" < + + + + + $title + + + +
+

$title

+
+

$message

+
+ + +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" < + + + + Redirecting to Storybook... + + +

Redirecting to Storybook...

+ + +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 "" diff --git a/scripts/fetch-branch-artifacts.sh b/scripts/fetch-branch-artifacts.sh new file mode 100755 index 0000000000..0382017622 --- /dev/null +++ b/scripts/fetch-branch-artifacts.sh @@ -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 "" diff --git a/vercel.json b/vercel.json new file mode 100644 index 0000000000..cbc716af97 --- /dev/null +++ b/vercel.json @@ -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 + } +}