mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-05 21:54:50 +00:00
## Summary Extract a `.github/actions/changes-filter` composite action and adopt it across path-gated CI workflows, fixing the docs-only PR stall and removing duplicated `paths:` / `paths-ignore:` filtering across 8 workflows. ## Background Docs-only PRs stalled on required status checks because workflows using `paths-ignore: ['**/*.md']` never created a check run, while branch protection still required it. Observed on #11776 (the `test` check from `ci-tests-unit.yaml` never appeared). The fix pattern: keep the workflow triggered, gate downstream jobs on a `changes` job whose outputs are computed from a path filter. Skipped jobs count as passing under branch protection. ## What the action emits | Output | Meaning | |---|---| | `should-run` | Any file outside `apps/`, `docs/`, `.storybook/`, `**/*.md` changed. | | `app-website-changes` | Shared deps or `apps/website/**` changed. | | `app-desktop-changes` | Shared deps or `apps/desktop-ui/**` changed. | | `app-frontend-changes` | Shared deps or `src/**` changed. | | `packages-changes` | Shared deps or `packages/**` changed. | | `storybook-changes` | Shared deps or `.storybook/**` changed. | | `docs-changes` | `docs/**` or any `**/*.md` changed (deps NOT folded in). | | `dependency-changes` | Root `package.json`, `pnpm-lock.yaml`, or `pnpm-workspace.yaml` changed. | Shared deps are folded into every `app-*`, `packages-changes`, and `storybook-changes` output so a lockfile bump correctly invalidates each granular gate. Outputs default to `'true'` for non-`pull_request` events to avoid the silent-skip footgun on push / merge_group. ## Workflows migrated | Workflow | Gate | Notes | |---|---|---| | `ci-tests-unit.yaml` | `should-run` | Required check (`test`). Fixes the original stall. | | `ci-tests-e2e.yaml` | `should-run` | Required check (`e2e-status`). Replaces inline filter. | | `ci-perf-report.yaml` | `should-run` | Removes `paths-ignore`. | | `ci-website-build.yaml` | `app-website-changes \|\| packages-changes` | Refactor — not a required check, but moves to job-level gating. Filter scope broadens from `packages/{design-system}` to all `packages/**` (strictly safer). | | `ci-website-e2e.yaml` | `app-website-changes \|\| packages-changes` | Same restructure; `post-starting-comment` also gated to avoid spurious "tests are running" when E2E is skipped. | | `ci-dist-telemetry-scan.yaml` | `should-run` | New gate; was previously running on every PR including docs-only. | | `ci-oss-assets-validation.yaml` | `should-run` | Same. | | `ci-size-data.yaml` | `should-run` | Preserves existing repository guard on the new `changes` job. | | `ci-tests-storybook.yaml` | `storybook-changes \|\| app-frontend-changes \|\| packages-changes` | Gates 4 of 6 jobs. `deploy-production` (push to main) left ungated; `update-comment-with-chromatic` cascades naturally. | ## Branch protection (verified) Required status checks on `main` and `core/**`/`cloud/**`: `test`, `lint-and-format`, `e2e-status`. Only `test` and `e2e-status` use the composite — `lint-and-format` correctly stays unfiltered (must run on docs/apps too). The other 6 migrations are refactor wins (less wasted CI on docs/apps-only PRs), not stall fixes. ## Changes - **What**: New `.github/actions/changes-filter` composite + 8 workflow migrations to consume it. - **Breaking**: None. - **Dependencies**: New pin on `dorny/paths-filter@de90cc6` — already covered by `ci-validate-action-pins`. ## Review Focus - The `should-run` filter excludes `.storybook/**` (granular `storybook-changes` covers it instead). Storybook's gate combines all three: `storybook-changes || app-frontend-changes || packages-changes`. - Two `dorny/paths-filter` steps inside the composite — `predicate-quantifier=every` is required for the negated globs in `should-run` but breaks the multi-pattern OR filters. - The website filter scope intentionally broadens from `packages/{design-system,tailwind-utils}/**` to all `packages/**` for consistency and safety. Fixes #11776 ┆Issue is synchronized with this [Notion page](https://app.notion.com/p/PR-11785-ci-extract-changes-filter-composite-action-fix-docs-only-PR-stall-3526d73d36508172a1d7fe8c30fa6453) by [Unito](https://www.unito.io) --------- Co-authored-by: Amp <amp@ampcode.com>
243 lines
8.7 KiB
YAML
243 lines
8.7 KiB
YAML
# Description: Builds Storybook and runs visual regression testing via Chromatic, deploys previews to Cloudflare Pages
|
|
name: 'CI: Tests Storybook'
|
|
|
|
on:
|
|
workflow_dispatch: # Allow manual triggering
|
|
pull_request:
|
|
push:
|
|
branches: [main]
|
|
|
|
jobs:
|
|
changes:
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
outputs:
|
|
storybook-changes: ${{ steps.changes.outputs.storybook-changes }}
|
|
app-frontend-changes: ${{ steps.changes.outputs.app-frontend-changes }}
|
|
packages-changes: ${{ steps.changes.outputs.packages-changes }}
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
- id: changes
|
|
uses: ./.github/actions/changes-filter
|
|
|
|
# Post starting comment for non-forked PRs
|
|
comment-on-pr-start:
|
|
needs: changes
|
|
runs-on: ubuntu-latest
|
|
if: |
|
|
github.event_name == 'pull_request'
|
|
&& github.event.pull_request.head.repo.fork == false
|
|
&& (needs.changes.outputs.storybook-changes == 'true'
|
|
|| needs.changes.outputs.app-frontend-changes == 'true'
|
|
|| needs.changes.outputs.packages-changes == 'true')
|
|
permissions:
|
|
pull-requests: write
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v6
|
|
|
|
- name: Post starting comment
|
|
env:
|
|
GITHUB_TOKEN: ${{ github.token }}
|
|
run: |
|
|
chmod +x scripts/cicd/pr-storybook-deploy-and-comment.sh
|
|
./scripts/cicd/pr-storybook-deploy-and-comment.sh \
|
|
"${{ github.event.pull_request.number }}" \
|
|
"${{ github.head_ref }}" \
|
|
"starting"
|
|
|
|
# Build Storybook for all PRs (free Cloudflare deployment)
|
|
storybook-build:
|
|
needs: changes
|
|
runs-on: ubuntu-latest
|
|
if: |
|
|
github.event_name == 'pull_request'
|
|
&& (needs.changes.outputs.storybook-changes == 'true'
|
|
|| needs.changes.outputs.app-frontend-changes == 'true'
|
|
|| needs.changes.outputs.packages-changes == 'true')
|
|
outputs:
|
|
conclusion: ${{ steps.job-status.outputs.conclusion }}
|
|
workflow-url: ${{ steps.workflow-url.outputs.url }}
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v6
|
|
|
|
- name: Setup frontend
|
|
uses: ./.github/actions/setup-frontend
|
|
|
|
- name: Build Storybook
|
|
run: pnpm build-storybook
|
|
|
|
- name: Set job status
|
|
id: job-status
|
|
if: always()
|
|
run: |
|
|
echo "conclusion=${{ job.status }}" >> $GITHUB_OUTPUT
|
|
|
|
- name: Get workflow URL
|
|
id: workflow-url
|
|
if: always()
|
|
run: |
|
|
echo "url=${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> $GITHUB_OUTPUT
|
|
|
|
- name: Upload Storybook build
|
|
if: success() && github.event.pull_request.head.repo.fork == false
|
|
uses: actions/upload-artifact@v6
|
|
with:
|
|
name: storybook-static
|
|
path: storybook-static/
|
|
retention-days: 7
|
|
|
|
# Chromatic deployment only for version-bump-* branches or manual triggers
|
|
chromatic-deployment:
|
|
needs: changes
|
|
runs-on: ubuntu-latest
|
|
if: |
|
|
github.event_name == 'workflow_dispatch'
|
|
|| (github.event_name == 'pull_request'
|
|
&& startsWith(github.head_ref, 'version-bump-')
|
|
&& (needs.changes.outputs.storybook-changes == 'true'
|
|
|| needs.changes.outputs.app-frontend-changes == 'true'
|
|
|| needs.changes.outputs.packages-changes == 'true'))
|
|
outputs:
|
|
conclusion: ${{ steps.job-status.outputs.conclusion }}
|
|
workflow-url: ${{ steps.workflow-url.outputs.url }}
|
|
chromatic-build-url: ${{ steps.chromatic.outputs.buildUrl }}
|
|
chromatic-storybook-url: ${{ steps.chromatic.outputs.storybookUrl }}
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v6
|
|
with:
|
|
fetch-depth: 0 # Required for Chromatic baseline
|
|
|
|
- name: Setup frontend
|
|
uses: ./.github/actions/setup-frontend
|
|
|
|
- name: Build Storybook and run Chromatic
|
|
id: chromatic
|
|
uses: chromaui/action@07791f8243f4cb2698bf4d00426baf4b2d1cb7e0 # v13.3.5
|
|
with:
|
|
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
|
buildScriptName: build-storybook
|
|
autoAcceptChanges: 'main' # Auto-accept changes on main branch
|
|
exitOnceUploaded: true # Don't wait for UI tests to complete
|
|
onlyChanged: true # Only capture changed stories
|
|
|
|
- name: Set job status
|
|
id: job-status
|
|
if: always()
|
|
run: |
|
|
echo "conclusion=${{ job.status }}" >> $GITHUB_OUTPUT
|
|
|
|
- name: Get workflow URL
|
|
id: workflow-url
|
|
if: always()
|
|
run: |
|
|
echo "url=${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> $GITHUB_OUTPUT
|
|
|
|
# Deploy and comment for non-forked PRs only
|
|
deploy-and-comment:
|
|
needs: [changes, storybook-build]
|
|
runs-on: ubuntu-latest
|
|
if: |
|
|
always()
|
|
&& github.event_name == 'pull_request'
|
|
&& github.event.pull_request.head.repo.fork == false
|
|
&& (needs.changes.outputs.storybook-changes == 'true'
|
|
|| needs.changes.outputs.app-frontend-changes == 'true'
|
|
|| needs.changes.outputs.packages-changes == 'true')
|
|
permissions:
|
|
pull-requests: write
|
|
contents: read
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v6
|
|
|
|
- name: Download Storybook build
|
|
if: needs.storybook-build.outputs.conclusion == 'success'
|
|
uses: actions/download-artifact@v7
|
|
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 }}
|
|
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
|
GITHUB_TOKEN: ${{ github.token }}
|
|
WORKFLOW_CONCLUSION: ${{ needs.storybook-build.outputs.conclusion }}
|
|
WORKFLOW_URL: ${{ needs.storybook-build.outputs.workflow-url }}
|
|
run: |
|
|
./scripts/cicd/pr-storybook-deploy-and-comment.sh \
|
|
"${{ github.event.pull_request.number }}" \
|
|
"${{ github.head_ref }}" \
|
|
"completed"
|
|
|
|
# Deploy Storybook to production URL on main branch push
|
|
deploy-production:
|
|
runs-on: ubuntu-latest
|
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v6
|
|
|
|
- name: Setup frontend
|
|
uses: ./.github/actions/setup-frontend
|
|
|
|
- name: Build Storybook
|
|
run: pnpm build-storybook
|
|
|
|
- name: Deploy to Cloudflare Pages (production)
|
|
env:
|
|
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
|
run: |
|
|
npx wrangler@^4.0.0 pages deploy storybook-static \
|
|
--project-name=comfy-storybook \
|
|
--branch=main
|
|
|
|
# Update comment with Chromatic URLs for version-bump branches
|
|
update-comment-with-chromatic:
|
|
needs: [chromatic-deployment, deploy-and-comment]
|
|
runs-on: ubuntu-latest
|
|
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false && startsWith(github.head_ref, 'version-bump-') && needs.chromatic-deployment.outputs.chromatic-build-url != ''
|
|
permissions:
|
|
pull-requests: write
|
|
steps:
|
|
- name: Update comment with Chromatic URLs
|
|
uses: actions/github-script@v8
|
|
with:
|
|
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 =>
|
|
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,
|
|
comment_id: storybookComment.id,
|
|
body: updatedBody
|
|
});
|
|
}
|