mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 06:20:11 +00:00
refactor: migrate branch status pages from Vercel to Cloudflare Pages
Replace Vercel deployment with Cloudflare Pages using the same wrangler deploy pattern as Storybook and Playwright CI workflows. - Delete vercel.json, trigger-vercel-rebuild.yml, fetch-branch-artifacts.sh - Add deploy-branch-status.yml with wrangler pages deploy - Simplify build-pages.sh (no artifact fetching needed) - Revert unrelated CI workflow changes URLs: https://<branch>.comfyui-frontend-reports.pages.dev Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
155
.github/workflows/ci-tests-e2e.yaml
vendored
155
.github/workflows/ci-tests-e2e.yaml
vendored
@@ -1,12 +1,12 @@
|
||||
# Description: End-to-end testing with Playwright across multiple browsers, deploys test reports to Cloudflare Pages
|
||||
name: 'CI: Tests E2E'
|
||||
name: "CI: Tests E2E"
|
||||
description: "End-to-end testing with Playwright across multiple browsers, deploys test reports to Cloudflare Pages"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, master, core/*, desktop/*, sno-deploy-ghpage]
|
||||
branches: [main, master, core/*, desktop/*]
|
||||
pull_request:
|
||||
branches-ignore: [wip/*, draft/*, temp/*]
|
||||
workflow_dispatch:
|
||||
branches-ignore:
|
||||
[wip/*, draft/*, temp/*, vue-nodes-migration, sno-playwright-*]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -15,56 +15,65 @@ concurrency:
|
||||
jobs:
|
||||
setup:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
cache-key: ${{ steps.cache-key.outputs.key }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
# Setup Test Environment, build frontend but do not start server yet
|
||||
- name: Setup ComfyUI server
|
||||
uses: ./.github/actions/setup-comfyui-server
|
||||
- name: Setup frontend
|
||||
uses: ./.github/actions/setup-frontend
|
||||
with:
|
||||
include_build_step: true
|
||||
- name: Setup Playwright
|
||||
uses: ./.github/actions/setup-playwright # Setup Playwright and cache browsers
|
||||
|
||||
# Upload only built dist/ (containerized test jobs will pnpm install without cache)
|
||||
- name: Upload built frontend
|
||||
uses: actions/upload-artifact@v6
|
||||
# Save the entire workspace as cache for later test jobs to restore
|
||||
- name: Generate cache key
|
||||
id: cache-key
|
||||
run: echo "key=$(date +%s)" >> $GITHUB_OUTPUT
|
||||
- name: Save cache
|
||||
uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684
|
||||
with:
|
||||
name: frontend-dist
|
||||
path: dist/
|
||||
retention-days: 1
|
||||
path: .
|
||||
key: comfyui-setup-${{ steps.cache-key.outputs.key }}
|
||||
|
||||
# Sharded chromium tests
|
||||
playwright-tests-chromium-sharded:
|
||||
needs: setup
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
container:
|
||||
image: ghcr.io/comfy-org/comfyui-ci-container:0.0.12
|
||||
credentials:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: read
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
shardIndex: [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
shardTotal: [8]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
- name: Download built frontend
|
||||
uses: actions/download-artifact@v7
|
||||
# download built frontend repo from setup job
|
||||
- name: Wait for cache propagation
|
||||
run: sleep 10
|
||||
- name: Restore cached setup
|
||||
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684
|
||||
with:
|
||||
name: frontend-dist
|
||||
path: dist/
|
||||
fail-on-cache-miss: true
|
||||
path: .
|
||||
key: comfyui-setup-${{ needs.setup.outputs.cache-key }}
|
||||
|
||||
- name: Start ComfyUI server
|
||||
uses: ./.github/actions/start-comfyui-server
|
||||
# Setup Test Environment for this runner, start server, use cached built frontend ./dist from 'setup' job
|
||||
- name: Setup ComfyUI server
|
||||
uses: ./.github/actions/setup-comfyui-server
|
||||
with:
|
||||
launch_server: true
|
||||
- name: Setup nodejs, pnpm, reuse built frontend
|
||||
uses: ./.github/actions/setup-frontend
|
||||
- name: Setup Playwright
|
||||
uses: ./.github/actions/setup-playwright
|
||||
|
||||
- name: Install frontend deps
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
# Run sharded tests (browsers pre-installed in container)
|
||||
# Run sharded tests and upload sharded reports
|
||||
- name: Run Playwright tests (Shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }})
|
||||
id: playwright
|
||||
run: pnpm exec playwright test --project=chromium --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --reporter=blob
|
||||
@@ -72,7 +81,7 @@ jobs:
|
||||
PLAYWRIGHT_BLOB_OUTPUT_DIR: ./blob-report
|
||||
|
||||
- name: Upload blob report
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ !cancelled() }}
|
||||
with:
|
||||
name: blob-report-chromium-${{ matrix.shardIndex }}
|
||||
@@ -84,70 +93,69 @@ jobs:
|
||||
timeout-minutes: 15
|
||||
needs: setup
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/comfy-org/comfyui-ci-container:0.0.12
|
||||
credentials:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
permissions:
|
||||
contents: read
|
||||
packages: read
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
browser: [chromium-2x, chromium-0.5x, mobile-chrome]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
- name: Download built frontend
|
||||
uses: actions/download-artifact@v7
|
||||
# download built frontend repo from setup job
|
||||
- name: Wait for cache propagation
|
||||
run: sleep 10
|
||||
- name: Restore cached setup
|
||||
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684
|
||||
with:
|
||||
name: frontend-dist
|
||||
path: dist/
|
||||
fail-on-cache-miss: true
|
||||
path: .
|
||||
key: comfyui-setup-${{ needs.setup.outputs.cache-key }}
|
||||
|
||||
- name: Start ComfyUI server
|
||||
uses: ./.github/actions/start-comfyui-server
|
||||
# Setup Test Environment for this runner, start server, use cached built frontend ./dist from 'setup' job
|
||||
- name: Setup ComfyUI server
|
||||
uses: ./.github/actions/setup-comfyui-server
|
||||
with:
|
||||
launch_server: true
|
||||
- name: Setup nodejs, pnpm, reuse built frontend
|
||||
uses: ./.github/actions/setup-frontend
|
||||
- name: Setup Playwright
|
||||
uses: ./.github/actions/setup-playwright
|
||||
|
||||
- name: Install frontend deps
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
# Run tests (browsers pre-installed in container)
|
||||
# Run tests and upload reports
|
||||
- name: Run Playwright tests (${{ matrix.browser }})
|
||||
id: playwright
|
||||
run: pnpm exec playwright test --project=${{ matrix.browser }} --reporter=blob
|
||||
env:
|
||||
PLAYWRIGHT_BLOB_OUTPUT_DIR: ./blob-report
|
||||
|
||||
- name: Generate HTML and JSON reports
|
||||
if: always()
|
||||
run: |
|
||||
# Generate HTML report from blob
|
||||
pnpm exec playwright merge-reports --reporter=html ./blob-report
|
||||
# Generate JSON report separately with explicit output path
|
||||
# Run tests with both HTML and JSON reporters
|
||||
PLAYWRIGHT_JSON_OUTPUT_NAME=playwright-report/report.json \
|
||||
pnpm exec playwright merge-reports --reporter=json ./blob-report
|
||||
pnpm exec playwright test --project=${{ matrix.browser }} \
|
||||
--reporter=list \
|
||||
--reporter=html \
|
||||
--reporter=json
|
||||
|
||||
- name: Upload Playwright report
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: playwright-report-${{ matrix.browser }}
|
||||
path: ./playwright-report/
|
||||
retention-days: 30
|
||||
|
||||
# Merge sharded test reports (no container needed - only runs CLI)
|
||||
# Merge sharded test reports
|
||||
merge-reports:
|
||||
needs: [playwright-tests-chromium-sharded]
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ !cancelled() }}
|
||||
steps:
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
|
||||
with:
|
||||
version: 10
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
|
||||
# Setup Test Environment, we only need playwright to merge reports
|
||||
- name: Setup frontend
|
||||
uses: ./.github/actions/setup-frontend
|
||||
- name: Setup Playwright
|
||||
uses: ./.github/actions/setup-playwright
|
||||
|
||||
- name: Download blob reports
|
||||
uses: actions/download-artifact@v7
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: ./all-blob-reports
|
||||
pattern: blob-report-chromium-*
|
||||
@@ -156,13 +164,13 @@ jobs:
|
||||
- name: Merge into HTML Report
|
||||
run: |
|
||||
# Generate HTML report
|
||||
pnpm dlx @playwright/test merge-reports --reporter=html ./all-blob-reports
|
||||
pnpm exec playwright merge-reports --reporter=html ./all-blob-reports
|
||||
# Generate JSON report separately with explicit output path
|
||||
PLAYWRIGHT_JSON_OUTPUT_NAME=playwright-report/report.json \
|
||||
pnpm dlx @playwright/test merge-reports --reporter=json ./all-blob-reports
|
||||
pnpm exec playwright merge-reports --reporter=json ./all-blob-reports
|
||||
|
||||
- name: Upload HTML report
|
||||
uses: actions/upload-artifact@v6
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: playwright-report-chromium
|
||||
path: ./playwright-report/
|
||||
@@ -180,7 +188,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Get start time
|
||||
id: start-time
|
||||
@@ -207,10 +215,10 @@ jobs:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Download all playwright reports
|
||||
uses: actions/download-artifact@v7
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: playwright-report-*
|
||||
path: reports
|
||||
@@ -220,7 +228,6 @@ jobs:
|
||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
GITHUB_SHA: ${{ github.event.pull_request.head.sha }}
|
||||
run: |
|
||||
bash ./scripts/cicd/pr-playwright-deploy-and-comment.sh \
|
||||
"${{ github.event.pull_request.number }}" \
|
||||
|
||||
55
.github/workflows/ci-tests-storybook.yaml
vendored
55
.github/workflows/ci-tests-storybook.yaml
vendored
@@ -1,13 +1,10 @@
|
||||
name: Storybook and Chromatic CI
|
||||
|
||||
# - [Automate Chromatic with GitHub Actions • Chromatic docs]( https://www.chromatic.com/docs/github-actions/ )
|
||||
name: "CI: Tests Storybook"
|
||||
description: "Builds Storybook and runs visual regression testing via Chromatic, deploys previews to Cloudflare Pages"
|
||||
|
||||
on:
|
||||
workflow_dispatch: # Allow manual triggering
|
||||
pull_request:
|
||||
branches: [main, sno-deploy-ghpage]
|
||||
push:
|
||||
branches: [sno-deploy-ghpage]
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
# Post starting comment for non-forked PRs
|
||||
@@ -19,7 +16,7 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
|
||||
|
||||
- name: Post starting comment
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
@@ -34,7 +31,7 @@ jobs:
|
||||
# Build Storybook for all PRs (free Cloudflare deployment)
|
||||
storybook-build:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'pull_request' || github.event_name == 'push'
|
||||
if: github.event_name == 'pull_request'
|
||||
outputs:
|
||||
conclusion: ${{ steps.job-status.outputs.conclusion }}
|
||||
workflow-url: ${{ steps.workflow-url.outputs.url }}
|
||||
@@ -53,19 +50,6 @@ jobs:
|
||||
node-version: '20'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Cache tool outputs
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
.cache
|
||||
storybook-static
|
||||
tsconfig.tsbuildinfo
|
||||
key: storybook-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('src/**/*.{ts,vue,js}', '*.config.*', '.storybook/**/*') }}
|
||||
restore-keys: |
|
||||
storybook-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}-
|
||||
storybook-cache-${{ runner.os }}-
|
||||
storybook-tools-cache-${{ runner.os }}-
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
@@ -118,19 +102,6 @@ jobs:
|
||||
node-version: '20'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Cache tool outputs
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
.cache
|
||||
storybook-static
|
||||
tsconfig.tsbuildinfo
|
||||
key: storybook-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('src/**/*.{ts,vue,js}', '*.config.*', '.storybook/**/*') }}
|
||||
restore-keys: |
|
||||
storybook-cache-${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}-
|
||||
storybook-cache-${{ runner.os }}-
|
||||
storybook-tools-cache-${{ runner.os }}-
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
@@ -167,17 +138,17 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
|
||||
|
||||
- name: Download Storybook build
|
||||
if: needs.storybook-build.outputs.conclusion == 'success'
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: storybook-static
|
||||
path: storybook-static
|
||||
|
||||
|
||||
- name: Make deployment script executable
|
||||
run: chmod +x scripts/cicd/pr-storybook-deploy-and-comment.sh
|
||||
|
||||
|
||||
- name: Deploy Storybook and comment on PR
|
||||
env:
|
||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
@@ -205,25 +176,25 @@ jobs:
|
||||
script: |
|
||||
const buildUrl = '${{ needs.chromatic-deployment.outputs.chromatic-build-url }}';
|
||||
const storybookUrl = '${{ needs.chromatic-deployment.outputs.chromatic-storybook-url }}';
|
||||
|
||||
|
||||
// Find the existing Storybook comment
|
||||
const { data: comments } = await github.rest.issues.listComments({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: ${{ github.event.pull_request.number }}
|
||||
});
|
||||
|
||||
const storybookComment = comments.find(comment =>
|
||||
|
||||
const storybookComment = comments.find(comment =>
|
||||
comment.body.includes('<!-- STORYBOOK_BUILD_STATUS -->')
|
||||
);
|
||||
|
||||
|
||||
if (storybookComment && buildUrl && storybookUrl) {
|
||||
// Append Chromatic info to existing comment
|
||||
const updatedBody = storybookComment.body.replace(
|
||||
/---\n(.*)$/s,
|
||||
`---\n### 🎨 Chromatic Visual Tests\n- 📊 [View Chromatic Build](${buildUrl})\n- 📚 [View Chromatic Storybook](${storybookUrl})\n\n$1`
|
||||
);
|
||||
|
||||
|
||||
await github.rest.issues.updateComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
|
||||
122
.github/workflows/deploy-branch-status.yml
vendored
Normal file
122
.github/workflows/deploy-branch-status.yml
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
name: 'Deploy: Branch Status Pages'
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- 'CI: Tests Storybook'
|
||||
- 'CI: Tests E2E'
|
||||
types:
|
||||
- completed
|
||||
branches-ignore:
|
||||
- main
|
||||
push:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: deploy-branch-status-${{ github.event.workflow_run.head_branch || github.ref_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
name: Deploy to Cloudflare Pages
|
||||
runs-on: ubuntu-latest
|
||||
if: |
|
||||
github.event_name == 'workflow_dispatch' ||
|
||||
github.event_name == 'push' ||
|
||||
(github.event.workflow_run.conclusion == 'success')
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
|
||||
|
||||
- name: Setup frontend
|
||||
uses: ./.github/actions/setup-frontend
|
||||
|
||||
- name: Build status pages
|
||||
run: pnpm pages:build
|
||||
|
||||
- name: Install wrangler
|
||||
run: npm install -g wrangler@^4.0.0
|
||||
|
||||
- name: Deploy to Cloudflare Pages
|
||||
id: deploy
|
||||
env:
|
||||
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
run: |
|
||||
BRANCH="${{ github.event.workflow_run.head_branch || github.ref_name }}"
|
||||
CF_BRANCH=$(echo "$BRANCH" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9-]/-/g' | sed 's/--*/-/g' | sed 's/^-\|-$//g')
|
||||
|
||||
echo "Deploying branch status pages for: $BRANCH (cf: $CF_BRANCH)"
|
||||
|
||||
OUTPUT=$(wrangler pages deploy .pages-dist \
|
||||
--project-name="comfyui-frontend-reports" \
|
||||
--branch="$CF_BRANCH" 2>&1) || {
|
||||
echo "Deployment failed: $OUTPUT"
|
||||
exit 1
|
||||
}
|
||||
|
||||
URL=$(echo "$OUTPUT" | grep -oE 'https://[a-zA-Z0-9.-]+\.pages\.dev\S*' | head -1)
|
||||
URL="${URL:-https://${CF_BRANCH}.comfyui-frontend-reports.pages.dev}"
|
||||
|
||||
echo "url=$URL" >> "$GITHUB_OUTPUT"
|
||||
echo "branch=$BRANCH" >> "$GITHUB_OUTPUT"
|
||||
echo "Deployed to: $URL"
|
||||
|
||||
- name: Find PR number
|
||||
id: pr
|
||||
if: github.event_name == 'workflow_run'
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const branch = '${{ steps.deploy.outputs.branch }}';
|
||||
const { data: prs } = await github.rest.pulls.list({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
head: `${context.repo.owner}:${branch}`,
|
||||
state: 'open'
|
||||
});
|
||||
return prs.length > 0 ? prs[0].number : null;
|
||||
|
||||
- name: Comment on PR
|
||||
if: steps.pr.outputs.result && steps.pr.outputs.result != 'null'
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const marker = '<!-- BRANCH_STATUS_DEPLOY -->';
|
||||
const prNumber = ${{ steps.pr.outputs.result }};
|
||||
const url = '${{ steps.deploy.outputs.url }}';
|
||||
|
||||
const body = `${marker}
|
||||
**Branch Status Page** deployed: ${url}
|
||||
|
||||
Includes: Storybook links, Nx graph, Knip report, test report links`;
|
||||
|
||||
const { data: comments } = await github.rest.issues.listComments({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: prNumber
|
||||
});
|
||||
|
||||
const existing = comments.find(c => c.body.includes(marker));
|
||||
if (existing) {
|
||||
await github.rest.issues.updateComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
comment_id: existing.id,
|
||||
body
|
||||
});
|
||||
} else {
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: prNumber,
|
||||
body
|
||||
});
|
||||
}
|
||||
134
.github/workflows/trigger-vercel-rebuild.yml
vendored
134
.github/workflows/trigger-vercel-rebuild.yml
vendored
@@ -1,134 +0,0 @@
|
||||
name: Trigger Vercel Rebuild
|
||||
|
||||
# Trigger when all important CI workflows complete
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- "Storybook and Chromatic CI"
|
||||
- "Tests CI"
|
||||
types:
|
||||
- completed
|
||||
branches-ignore:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
check-and-trigger:
|
||||
name: Trigger Vercel Rebuild
|
||||
runs-on: ubuntu-latest
|
||||
# Only run on PRs and only on success
|
||||
if: |
|
||||
github.event.workflow_run.event == 'pull_request' &&
|
||||
github.event.workflow_run.conclusion == 'success'
|
||||
|
||||
steps:
|
||||
- name: Get PR branch
|
||||
id: pr
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const { data: pullRequests } = await github.rest.pulls.list({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
head: `${context.repo.owner}:${context.payload.workflow_run.head_branch}`,
|
||||
state: 'open'
|
||||
});
|
||||
|
||||
if (pullRequests.length === 0) {
|
||||
console.log('No open PR found for this branch');
|
||||
return null;
|
||||
}
|
||||
|
||||
return pullRequests[0].number;
|
||||
|
||||
- name: Check all required workflows completed
|
||||
id: check
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
if (!${{ steps.pr.outputs.result }}) {
|
||||
console.log('No PR found, skipping');
|
||||
return false;
|
||||
}
|
||||
|
||||
const requiredWorkflows = [
|
||||
'Storybook and Chromatic CI',
|
||||
'Tests CI'
|
||||
];
|
||||
|
||||
const { data: workflowRuns } = await github.rest.actions.listWorkflowRunsForRepo({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
branch: context.payload.workflow_run.head_branch,
|
||||
per_page: 100
|
||||
});
|
||||
|
||||
// Get the latest run for each required workflow
|
||||
const latestRuns = {};
|
||||
for (const run of workflowRuns.workflow_runs) {
|
||||
const workflowName = run.name;
|
||||
if (requiredWorkflows.includes(workflowName)) {
|
||||
if (!latestRuns[workflowName] || run.created_at > latestRuns[workflowName].created_at) {
|
||||
latestRuns[workflowName] = run;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if all required workflows have completed successfully
|
||||
const allComplete = requiredWorkflows.every(name => {
|
||||
const run = latestRuns[name];
|
||||
return run && run.conclusion === 'success';
|
||||
});
|
||||
|
||||
console.log('Workflow status:');
|
||||
requiredWorkflows.forEach(name => {
|
||||
const run = latestRuns[name];
|
||||
console.log(` ${name}: ${run ? run.conclusion : 'not found'}`);
|
||||
});
|
||||
|
||||
console.log(`All workflows complete: ${allComplete}`);
|
||||
return allComplete;
|
||||
|
||||
- name: Trigger Vercel Deploy Hook
|
||||
if: steps.check.outputs.result == 'true'
|
||||
run: |
|
||||
echo "🚀 All CI workflows completed successfully"
|
||||
echo "📦 Triggering Vercel rebuild with fresh artifacts..."
|
||||
|
||||
curl -X POST "${{ secrets.VERCEL_DEPLOY_HOOK_URL }}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"ref": "${{ github.event.workflow_run.head_branch }}",
|
||||
"reason": "All CI workflows completed"
|
||||
}'
|
||||
|
||||
echo "✅ Vercel rebuild triggered"
|
||||
|
||||
- name: Comment on PR
|
||||
if: steps.check.outputs.result == 'true' && steps.pr.outputs.result
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const prNumber = ${{ steps.pr.outputs.result }};
|
||||
const branch = '${{ github.event.workflow_run.head_branch }}';
|
||||
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: prNumber,
|
||||
body: `🔄 **Vercel Rebuild Triggered**
|
||||
|
||||
All CI workflows completed successfully. Vercel is rebuilding with fresh artifacts:
|
||||
- ✅ Storybook
|
||||
- ✅ E2E Test Reports
|
||||
- ✅ Vitest Reports
|
||||
|
||||
Your branch status page will update shortly with the latest test results.
|
||||
|
||||
Preview URL: \`https://${branch}-comfyui-frontend-reports.vercel.app\`
|
||||
`
|
||||
});
|
||||
|
||||
- name: Skip rebuild
|
||||
if: steps.check.outputs.result != 'true'
|
||||
run: |
|
||||
echo "⏭️ Skipping Vercel rebuild - not all workflows complete yet"
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -96,8 +96,3 @@ vitest.config.*.timestamp*
|
||||
# Generated reports in .pages (exclude generated, keep HTML templates)
|
||||
/.pages/*/**/*
|
||||
/.pages-dist/
|
||||
|
||||
# Fetched artifacts for Vercel builds
|
||||
/.page/
|
||||
|
||||
.vercel
|
||||
|
||||
163
.pages/README.md
163
.pages/README.md
@@ -1,153 +1,54 @@
|
||||
# Branch Status Pages
|
||||
|
||||
This directory contains the source for the branch status pages that aggregate development tools and test reports.
|
||||
This directory contains the source for branch status pages deployed to **Cloudflare Pages**.
|
||||
|
||||
## Deployment
|
||||
|
||||
The branch status pages are automatically deployed to **Vercel** on every push to any branch.
|
||||
|
||||
### Architecture
|
||||
## Architecture
|
||||
|
||||
```
|
||||
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
|
||||
|
|
||||
+-> GitHub Actions (runs tests, deploys artifacts)
|
||||
| +-> Storybook -> comfy-storybook.pages.dev
|
||||
| +-> E2E Tests -> comfyui-playwright-*.pages.dev
|
||||
| +-> Branch Status -> comfyui-frontend-reports.pages.dev
|
||||
|
|
||||
+-> deploy-branch-status.yml
|
||||
|
|
||||
Runs: pnpm pages:build
|
||||
|
|
||||
Deploys to Cloudflare Pages via wrangler
|
||||
```
|
||||
|
||||
### URLs
|
||||
## URLs
|
||||
|
||||
- **Production** (main branch): `https://comfyui-frontend-reports.vercel.app`
|
||||
- **Preview** (PR branches): `https://<branch>-comfyui-frontend-reports.vercel.app`
|
||||
- **Production** (main branch): `https://comfyui-frontend-reports.pages.dev`
|
||||
- **Preview** (PR branches): `https://<branch>.comfyui-frontend-reports.pages.dev`
|
||||
|
||||
## What's Included
|
||||
|
||||
The branch status page aggregates:
|
||||
|
||||
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
|
||||
|
||||
## How It Works
|
||||
|
||||
### Artifact Fetching
|
||||
|
||||
The `scripts/fetch-branch-artifacts.sh` script fetches test results from:
|
||||
|
||||
- **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)
|
||||
|
||||
### 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.
|
||||
1. **Storybook** - Links to Cloudflare Pages deployment
|
||||
2. **Nx Dependency Graph** - Generated during build
|
||||
3. **Playwright Reports** - Links to Cloudflare Pages deployments
|
||||
4. **Vitest Reports** - Links to CI artifacts
|
||||
5. **Coverage Report** - Links to CI artifacts
|
||||
6. **Knip Report** - Generated fresh during build
|
||||
|
||||
## Local Development
|
||||
|
||||
```bash
|
||||
# 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
|
||||
pnpm pages:dev # Dev server
|
||||
pnpm pages:build # Build
|
||||
```
|
||||
|
||||
## Environment Variables (Vercel)
|
||||
## Secrets
|
||||
|
||||
Configure these in Vercel project settings:
|
||||
|
||||
- `GITHUB_TOKEN` - For fetching artifacts via GitHub API (required)
|
||||
- `CLOUDFLARE_ACCOUNT_ID` - For Cloudflare API (optional)
|
||||
- `CLOUDFLARE_API_TOKEN` - For Cloudflare API (optional)
|
||||
Required in GitHub Actions:
|
||||
- `CLOUDFLARE_API_TOKEN`
|
||||
- `CLOUDFLARE_ACCOUNT_ID`
|
||||
|
||||
## Files
|
||||
|
||||
- **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
|
||||
|
||||
## Adding New Reports
|
||||
|
||||
To add a new report to the status page:
|
||||
|
||||
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
|
||||
|
||||
### Artifacts not appearing
|
||||
|
||||
- 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)
|
||||
|
||||
### Slow builds
|
||||
|
||||
- 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)
|
||||
|
||||
### Storybook redirect not working
|
||||
|
||||
- Verify Cloudflare Pages deployment succeeded
|
||||
- Check PR comments for correct Storybook URL
|
||||
- Fallback: Storybook will show placeholder page
|
||||
|
||||
## CI Integration
|
||||
|
||||
No GitHub Actions workflow is needed for Vercel deployments. Vercel automatically:
|
||||
|
||||
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
|
||||
|
||||
## Migration Notes
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
## Primary Use Case: Development Team
|
||||
|
||||
This deployment provides:
|
||||
|
||||
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
|
||||
|
||||
- [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)
|
||||
- [Playwright Documentation](https://playwright.dev)
|
||||
- **index.html** - Landing page with links to all reports
|
||||
- **vite.config.ts** - Vite config for building the static site
|
||||
- **knip.html** - Knip markdown report viewer
|
||||
- **playwright-reports.html** - E2E test report viewer
|
||||
|
||||
@@ -10,8 +10,13 @@ const discoverHtmlEntries = () => {
|
||||
const topLevel = resolve(rootDir, 'index.html')
|
||||
if (fs.existsSync(topLevel)) entries.set('index', topLevel)
|
||||
|
||||
// Directories with pre-built assets (e.g. nx-graph) are copied directly
|
||||
// in build-pages.sh to avoid CSS minification issues
|
||||
const skipDirs = new Set(['nx-graph'])
|
||||
|
||||
for (const dirent of fs.readdirSync(rootDir, { withFileTypes: true })) {
|
||||
if (!dirent.isDirectory() || dirent.name.startsWith('.')) continue
|
||||
if (skipDirs.has(dirent.name)) continue
|
||||
const candidate = resolve(rootDir, dirent.name, 'index.html')
|
||||
if (fs.existsSync(candidate)) entries.set(dirent.name, candidate)
|
||||
}
|
||||
@@ -21,7 +26,7 @@ const discoverHtmlEntries = () => {
|
||||
|
||||
export default defineConfig({
|
||||
root: rootDir,
|
||||
base: '/ComfyUI_frontend/',
|
||||
base: '/',
|
||||
appType: 'mpa',
|
||||
logLevel: 'info',
|
||||
publicDir: false,
|
||||
|
||||
@@ -15,15 +15,11 @@ const config: KnipConfig = {
|
||||
'packages/tailwind-utils': {
|
||||
project: ['src/**/*.{js,ts}']
|
||||
},
|
||||
'packages/design-system': {
|
||||
entry: ['src/**/*.ts'],
|
||||
project: ['src/**/*.{js,ts}', '*.{js,ts,mts}']
|
||||
},
|
||||
'packages/registry-types': {
|
||||
project: ['src/**/*.{js,ts}']
|
||||
}
|
||||
},
|
||||
ignoreBinaries: ['python3'],
|
||||
ignoreBinaries: ['python3', 'gh'],
|
||||
ignoreDependencies: [
|
||||
// Weird importmap things
|
||||
'@iconify/json',
|
||||
@@ -31,11 +27,10 @@ const config: KnipConfig = {
|
||||
'@primeuix/styled',
|
||||
'@primeuix/utils',
|
||||
'@primevue/icons',
|
||||
// Dev
|
||||
'@trivago/prettier-plugin-sort-imports',
|
||||
// 3D and collaboration libraries
|
||||
'three',
|
||||
'@types/three',
|
||||
// Unused but kept for potential future use
|
||||
'@sparkjsdev/spark',
|
||||
'wwobjloader2',
|
||||
'@iconify-json/lucide',
|
||||
'yjs'
|
||||
],
|
||||
ignore: [
|
||||
@@ -54,7 +49,22 @@ const config: KnipConfig = {
|
||||
'src/renderer/extensions/vueNodes/composables/slotLinkDragContext.ts',
|
||||
'src/types/spatialIndex.ts',
|
||||
'src/lib/litegraph/src/litegraph.ts',
|
||||
'src/utils/vintageClipboard.ts'
|
||||
'src/utils/vintageClipboard.ts',
|
||||
'src/platform/auth/session/useSessionCookie.ts',
|
||||
'src/platform/support/config.ts',
|
||||
'src/renderer/utils/nodeTypeGuards.ts',
|
||||
'src/schemas/nodeDefSchema.ts',
|
||||
'src/scripts/defaultGraph.ts',
|
||||
'src/scripts/ui.ts',
|
||||
'src/scripts/widgets.ts',
|
||||
'src/services/litegraphService.ts',
|
||||
'src/storybook/mocks/useJobActions.ts',
|
||||
'src/storybook/mocks/useJobList.ts',
|
||||
'src/utils/executableGroupNodeDto.ts',
|
||||
'src/utils/litegraphUtil.ts',
|
||||
'src/lib/litegraph/src/LGraph.ts',
|
||||
'src/schemas/apiSchema.ts',
|
||||
'src/schemas/nodeDef/nodeDefSchemaV2.ts'
|
||||
],
|
||||
compilers: {
|
||||
// https://github.com/webpro-nl/knip/issues/1008#issuecomment-3207756199
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
"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,8 +36,7 @@
|
||||
"lint:desktop": "nx run @comfyorg/desktop-ui:lint",
|
||||
"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:build": "bash scripts/build-pages.sh && vite build --config ./.pages/vite.config.ts && cp -r .pages/nx-graph .pages-dist/nx-graph 2>/dev/null || true",
|
||||
"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",
|
||||
|
||||
@@ -43,24 +43,11 @@ create_placeholder() {
|
||||
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>
|
||||
@@ -69,38 +56,18 @@ EOF
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Storybook
|
||||
# Storybook (deployed separately to Cloudflare Pages)
|
||||
# ============================================================================
|
||||
echo "[build-pages] Setting up Storybook"
|
||||
rm -rf ".pages/storybook"
|
||||
|
||||
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"
|
||||
if [ -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 " ⚠️ No Storybook build available, creating placeholder"
|
||||
echo " Creating placeholder (Storybook deployed separately to comfy-storybook.pages.dev)"
|
||||
create_placeholder ".pages/storybook" "Storybook" \
|
||||
"Storybook is being built by CI. Please check back in a few minutes."
|
||||
"Storybook is deployed separately. Check the PR comments for the Cloudflare Pages link."
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
@@ -110,29 +77,26 @@ echo "[build-pages] Generating Nx dependency graph"
|
||||
rm -rf ".pages/nx-graph" && mkdir -p ".pages/nx-graph"
|
||||
|
||||
if pnpm nx graph --file=".pages/nx-graph/index.html" 2>/dev/null; then
|
||||
echo " ✅ Nx graph generated"
|
||||
echo " Nx graph generated"
|
||||
else
|
||||
echo " ⚠️ Nx graph generation failed, creating placeholder"
|
||||
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
|
||||
# Playwright E2E Test Reports (deployed separately to Cloudflare Pages)
|
||||
# ============================================================================
|
||||
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"
|
||||
if [ -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"
|
||||
echo " Creating placeholder (Playwright reports deployed separately)"
|
||||
create_placeholder ".pages/playwright-reports" "E2E Test Reports" \
|
||||
"Playwright tests are running in CI. Results will appear here when complete."
|
||||
"Playwright reports are deployed separately. Check the PR comments for Cloudflare Pages links."
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
@@ -141,29 +105,17 @@ fi
|
||||
echo "[build-pages] Setting up Vitest test reports"
|
||||
rm -rf ".pages/vitest-reports" && mkdir -p ".pages/vitest-reports"
|
||||
|
||||
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 " ℹ️ 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
|
||||
create_placeholder ".pages/vitest-reports" "Vitest Test Reports" \
|
||||
"Unit test results are available in CI. Check the GitHub Actions workflow run."
|
||||
|
||||
# ============================================================================
|
||||
# Coverage Report (Optional - slow to generate)
|
||||
# Coverage Report
|
||||
# ============================================================================
|
||||
echo "[build-pages] Setting up coverage report"
|
||||
mkdir -p ".pages/coverage"
|
||||
|
||||
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 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
|
||||
create_placeholder ".pages/coverage" "Coverage Report" \
|
||||
"Code coverage is generated in CI. Check the GitHub Actions workflow run."
|
||||
|
||||
# ============================================================================
|
||||
# Knip Report (Fast - generate fresh)
|
||||
@@ -173,13 +125,13 @@ 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"
|
||||
echo " Knip report generated"
|
||||
else
|
||||
echo " ⚠️ Knip report failed, creating placeholder"
|
||||
echo " Knip report failed, creating placeholder"
|
||||
cat > ".pages/knip/report.md" <<'EOF'
|
||||
# Knip Report
|
||||
|
||||
> ⚠️ Knip report generation failed
|
||||
> Knip report generation failed
|
||||
|
||||
Knip analysis could not be completed in this build environment.
|
||||
Please check the CI logs for details.
|
||||
@@ -198,6 +150,3 @@ 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 ""
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
#!/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
19
vercel.json
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"$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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user