diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 000000000..f62e91eda --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,21 @@ +# GitHub Workflows + +## Naming Convention + +Workflow files follow a consistent naming pattern: `-.yaml` + +### Category Prefixes + +| Prefix | Purpose | Example | +| ---------- | ----------------------------------- | ------------------------------------ | +| `ci-` | Testing, linting, validation | `ci-tests-e2e.yaml` | +| `release-` | Version management, publishing | `release-version-bump.yaml` | +| `pr-` | PR automation (triggered by labels) | `pr-claude-review.yaml` | +| `api-` | External Api type generation | `api-update-registry-api-types.yaml` | +| `i18n-` | Internationalization updates | `i18n-update-core.yaml` | + +## Documentation + +Each workflow file contains comments explaining its purpose, triggers, and behavior. For specific details about what each workflow does, refer to the comments at the top of each `.yaml` file. + +For GitHub Actions documentation, see [Events that trigger workflows](https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows). diff --git a/.github/workflows/update-electron-types.yaml b/.github/workflows/api-update-electron-api-types.yaml similarity index 91% rename from .github/workflows/update-electron-types.yaml rename to .github/workflows/api-update-electron-api-types.yaml index 45d959b86..90a08e02c 100644 --- a/.github/workflows/update-electron-types.yaml +++ b/.github/workflows/api-update-electron-api-types.yaml @@ -1,4 +1,5 @@ -name: Update Electron Types +name: 'Api: Update Electron API Types' +description: 'When upstream electron API is updated, click dispatch to update the TypeScript type definitions in this repo' on: workflow_dispatch: diff --git a/.github/workflows/update-comfyui-manager-api-types.yaml b/.github/workflows/api-update-manager-api-types.yaml similarity index 96% rename from .github/workflows/update-comfyui-manager-api-types.yaml rename to .github/workflows/api-update-manager-api-types.yaml index 7e307dfda..5a1e8ec74 100644 --- a/.github/workflows/update-comfyui-manager-api-types.yaml +++ b/.github/workflows/api-update-manager-api-types.yaml @@ -1,4 +1,5 @@ -name: Update ComfyUI-Manager API Types +name: 'Api: Update Manager API Types' +description: 'When upstream ComfyUI-Manager API is updated, click dispatch to update the TypeScript type definitions in this repo' on: # Manual trigger diff --git a/.github/workflows/update-comfy-registry-api-types.yaml b/.github/workflows/api-update-registry-api-types.yaml similarity index 96% rename from .github/workflows/update-comfy-registry-api-types.yaml rename to .github/workflows/api-update-registry-api-types.yaml index 41a4db9ab..69b4ad5b2 100644 --- a/.github/workflows/update-comfy-registry-api-types.yaml +++ b/.github/workflows/api-update-registry-api-types.yaml @@ -1,4 +1,5 @@ -name: Update Comfy Registry API Types +name: 'Api: Update Registry API Types' +description: 'When upstream comfy-api is updated, click dispatch to update the TypeScript type definitions in this repo' on: # Manual trigger diff --git a/.github/workflows/validate-json.yaml b/.github/workflows/ci-json-validation.yaml similarity index 63% rename from .github/workflows/validate-json.yaml rename to .github/workflows/ci-json-validation.yaml index 2986d23ed..0d8c9392f 100644 --- a/.github/workflows/validate-json.yaml +++ b/.github/workflows/ci-json-validation.yaml @@ -1,4 +1,5 @@ -name: Validate JSON +name: "CI: JSON Validation" +description: "Validates JSON syntax in all tracked .json files (excluding tsconfig*.json) using jq" on: push: diff --git a/.github/workflows/lint-and-format.yaml b/.github/workflows/ci-lint-format.yaml similarity index 97% rename from .github/workflows/lint-and-format.yaml rename to .github/workflows/ci-lint-format.yaml index 62956cadb..5c4e0011b 100644 --- a/.github/workflows/lint-and-format.yaml +++ b/.github/workflows/ci-lint-format.yaml @@ -1,4 +1,5 @@ -name: Lint and Format +name: "CI: Lint Format" +description: "Linting and code formatting validation for pull requests" on: pull_request: diff --git a/.github/workflows/devtools-python-check.yaml b/.github/workflows/ci-python-validation.yaml similarity index 82% rename from .github/workflows/devtools-python-check.yaml rename to .github/workflows/ci-python-validation.yaml index f0893e99d..698f467bf 100644 --- a/.github/workflows/devtools-python-check.yaml +++ b/.github/workflows/ci-python-validation.yaml @@ -1,4 +1,5 @@ -name: Devtools Python Check +name: "CI: Python Validation" +description: "Validates Python code in tools/devtools directory" on: pull_request: diff --git a/.github/workflows/pr-playwright-deploy-forks.yaml b/.github/workflows/ci-tests-e2e-forks.yaml similarity index 95% rename from .github/workflows/pr-playwright-deploy-forks.yaml rename to .github/workflows/ci-tests-e2e-forks.yaml index 660fee77f..5d3767f8e 100644 --- a/.github/workflows/pr-playwright-deploy-forks.yaml +++ b/.github/workflows/ci-tests-e2e-forks.yaml @@ -1,8 +1,9 @@ -name: PR Playwright Deploy (Forks) +name: "CI: Tests E2E (Deploy for Forks)" +description: "Deploys test results from forked PRs (forks can't access deployment secrets)" on: workflow_run: - workflows: ["Tests CI"] + workflows: ["CI: Tests E2E"] types: [requested, completed] env: diff --git a/.github/workflows/tests-ci.yaml b/.github/workflows/ci-tests-e2e.yaml similarity index 98% rename from .github/workflows/tests-ci.yaml rename to .github/workflows/ci-tests-e2e.yaml index 0d33ecf19..690417a04 100644 --- a/.github/workflows/tests-ci.yaml +++ b/.github/workflows/ci-tests-e2e.yaml @@ -1,4 +1,5 @@ -name: Tests CI +name: "CI: Tests E2E" +description: "End-to-end testing with Playwright across multiple browsers, deploys test reports to Cloudflare Pages" on: push: diff --git a/.github/workflows/pr-storybook-deploy-forks.yaml b/.github/workflows/ci-tests-storybook-forks.yaml similarity index 95% rename from .github/workflows/pr-storybook-deploy-forks.yaml rename to .github/workflows/ci-tests-storybook-forks.yaml index da27867c4..083a85f1d 100644 --- a/.github/workflows/pr-storybook-deploy-forks.yaml +++ b/.github/workflows/ci-tests-storybook-forks.yaml @@ -1,8 +1,9 @@ -name: PR Storybook Deploy (Forks) +name: "CI: Tests Storybook (Deploy for Forks)" +description: "Deploys Storybook previews from forked PRs (forks can't access deployment secrets)" on: workflow_run: - workflows: ['Storybook and Chromatic CI'] + workflows: ["CI: Tests Storybook"] types: [requested, completed] env: diff --git a/.github/workflows/storybook-and-chromatic-ci.yaml b/.github/workflows/ci-tests-storybook.yaml similarity index 98% rename from .github/workflows/storybook-and-chromatic-ci.yaml rename to .github/workflows/ci-tests-storybook.yaml index bfac96530..65e97ed91 100644 --- a/.github/workflows/storybook-and-chromatic-ci.yaml +++ b/.github/workflows/ci-tests-storybook.yaml @@ -1,6 +1,5 @@ -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 diff --git a/.github/workflows/vitest-tests.yaml b/.github/workflows/ci-tests-unit.yaml similarity index 93% rename from .github/workflows/vitest-tests.yaml rename to .github/workflows/ci-tests-unit.yaml index 394145188..152f78885 100644 --- a/.github/workflows/vitest-tests.yaml +++ b/.github/workflows/ci-tests-unit.yaml @@ -1,4 +1,5 @@ -name: Vitest Tests +name: "CI: Tests Unit" +description: "Unit and component testing with Vitest" on: push: diff --git a/.github/workflows/update-locales.yaml b/.github/workflows/i18n-update-core.yaml similarity index 94% rename from .github/workflows/update-locales.yaml rename to .github/workflows/i18n-update-core.yaml index 9ffa702ca..8a20af4c0 100644 --- a/.github/workflows/update-locales.yaml +++ b/.github/workflows/i18n-update-core.yaml @@ -1,4 +1,5 @@ -name: Update Locales +name: "i18n: Update Core" +description: "Generates and updates translations for core ComfyUI components using OpenAI" on: # Manual dispatch for urgent translation updates @@ -54,5 +55,5 @@ jobs: # Apply the stashed changes if any git stash pop || true git add src/locales/ - git diff --staged --quiet || git commit -m "Update locales [skip ci]" + git diff --staged --quiet || git commit -m "Update locales" git push origin HEAD:${{ github.head_ref }} diff --git a/.github/workflows/update-locales-for-given-custom-node-repository.yaml b/.github/workflows/i18n-update-custom-nodes.yaml similarity index 98% rename from .github/workflows/update-locales-for-given-custom-node-repository.yaml rename to .github/workflows/i18n-update-custom-nodes.yaml index b9d1b33b9..61076f031 100644 --- a/.github/workflows/update-locales-for-given-custom-node-repository.yaml +++ b/.github/workflows/i18n-update-custom-nodes.yaml @@ -1,4 +1,4 @@ -name: Update Locales for given custom node repository +name: i18n Update Custom Nodes on: workflow_dispatch: diff --git a/.github/workflows/update-node-definitions-locales.yaml b/.github/workflows/i18n-update-nodes.yaml similarity index 97% rename from .github/workflows/update-node-definitions-locales.yaml rename to .github/workflows/i18n-update-nodes.yaml index ce991d09e..0b9f1534d 100644 --- a/.github/workflows/update-node-definitions-locales.yaml +++ b/.github/workflows/i18n-update-nodes.yaml @@ -1,4 +1,4 @@ -name: Update Node Definitions Locales +name: i18n Update Nodes on: workflow_dispatch: diff --git a/.github/workflows/auto-backport.yaml b/.github/workflows/pr-backport.yaml similarity index 99% rename from .github/workflows/auto-backport.yaml rename to .github/workflows/pr-backport.yaml index 20eadc0c9..13e6dd74e 100644 --- a/.github/workflows/auto-backport.yaml +++ b/.github/workflows/pr-backport.yaml @@ -1,4 +1,4 @@ -name: Auto Backport +name: PR Backport on: pull_request_target: diff --git a/.github/workflows/claude-pr-review.yml b/.github/workflows/pr-claude-review.yaml similarity index 96% rename from .github/workflows/claude-pr-review.yml rename to .github/workflows/pr-claude-review.yaml index 76a9eb0f3..b09fde14f 100644 --- a/.github/workflows/claude-pr-review.yml +++ b/.github/workflows/pr-claude-review.yaml @@ -1,4 +1,5 @@ -name: Claude PR Review +name: "PR: Claude Review" +description: "AI-powered code review triggered by adding the 'claude-review' label to a PR" permissions: contents: read diff --git a/.github/workflows/update-playwright-expectations.yaml b/.github/workflows/pr-update-playwright-expectations.yaml similarity index 98% rename from .github/workflows/update-playwright-expectations.yaml rename to .github/workflows/pr-update-playwright-expectations.yaml index 61d5051d4..f688c3250 100644 --- a/.github/workflows/update-playwright-expectations.yaml +++ b/.github/workflows/pr-update-playwright-expectations.yaml @@ -1,5 +1,5 @@ # Setting test expectation screenshots for Playwright -name: Update Playwright Expectations +name: "PR: Update Playwright Expectations" on: pull_request: diff --git a/.github/workflows/create-release-branch.yaml b/.github/workflows/release-branch-create.yaml similarity index 99% rename from .github/workflows/create-release-branch.yaml rename to .github/workflows/release-branch-create.yaml index 7891a845d..992e779dd 100644 --- a/.github/workflows/create-release-branch.yaml +++ b/.github/workflows/release-branch-create.yaml @@ -1,4 +1,4 @@ -name: Create Release Branch +name: Release Branch Create on: pull_request: diff --git a/.github/workflows/create-release-draft.yaml b/.github/workflows/release-draft-create.yaml similarity index 98% rename from .github/workflows/create-release-draft.yaml rename to .github/workflows/release-draft-create.yaml index c359e3da4..240a89f1f 100644 --- a/.github/workflows/create-release-draft.yaml +++ b/.github/workflows/release-draft-create.yaml @@ -1,4 +1,4 @@ -name: Create Release Draft +name: Release Draft Create on: pull_request: @@ -126,7 +126,7 @@ jobs: publish_types: needs: build - uses: ./.github/workflows/publish-frontend-types.yaml + uses: ./.github/workflows/release-npm-types.yaml with: version: ${{ needs.build.outputs.version }} ref: ${{ github.event.pull_request.merge_commit_sha }} diff --git a/.github/workflows/publish-frontend-types.yaml b/.github/workflows/release-npm-types.yaml similarity index 99% rename from .github/workflows/publish-frontend-types.yaml rename to .github/workflows/release-npm-types.yaml index 142a22a93..23f0cc016 100644 --- a/.github/workflows/publish-frontend-types.yaml +++ b/.github/workflows/release-npm-types.yaml @@ -1,4 +1,4 @@ -name: Publish Frontend Types +name: Release NPM Types on: workflow_dispatch: diff --git a/.github/workflows/create-dev-pypi-package.yaml b/.github/workflows/release-pypi-dev.yaml similarity index 98% rename from .github/workflows/create-dev-pypi-package.yaml rename to .github/workflows/release-pypi-dev.yaml index b592a8371..88675e82e 100644 --- a/.github/workflows/create-dev-pypi-package.yaml +++ b/.github/workflows/release-pypi-dev.yaml @@ -1,4 +1,4 @@ -name: Create Dev PyPI Package +name: Release PyPI Dev on: workflow_dispatch: diff --git a/.github/workflows/version-bump.yaml b/.github/workflows/release-version-bump.yaml similarity index 94% rename from .github/workflows/version-bump.yaml rename to .github/workflows/release-version-bump.yaml index 4073729db..337bf6975 100644 --- a/.github/workflows/version-bump.yaml +++ b/.github/workflows/release-version-bump.yaml @@ -1,4 +1,5 @@ -name: Version Bump +name: "Release: Version Bump" +description: "Manual workflow to increment package version with semantic versioning support" on: workflow_dispatch: diff --git a/src/core/graph/subgraph/proxyWidget.ts b/src/core/graph/subgraph/proxyWidget.ts index 74e0c733d..26d3d8870 100644 --- a/src/core/graph/subgraph/proxyWidget.ts +++ b/src/core/graph/subgraph/proxyWidget.ts @@ -119,6 +119,7 @@ const onConfigure = function ( this.properties.proxyWidgets = serialisedNode.properties.proxyWidgets const parsed = parseProxyWidgets(serialisedNode.properties.proxyWidgets) serialisedNode.widgets_values?.forEach((v, index) => { + if (parsed[index]?.[0] !== '-1') return const widget = this.widgets.find((w) => w.name == parsed[index][1]) if (v !== null && widget) widget.value = v }) diff --git a/src/platform/assets/components/AssetCard.stories.ts b/src/platform/assets/components/AssetCard.stories.ts index 2b3532a05..2915a219a 100644 --- a/src/platform/assets/components/AssetCard.stories.ts +++ b/src/platform/assets/components/AssetCard.stories.ts @@ -84,6 +84,51 @@ export const NonInteractive: Story = { } } +export const WithPreviewImage: Story = { + args: { + asset: createAssetData({ + preview_url: '/assets/images/comfy-logo-single.svg' + }), + interactive: true + }, + decorators: [ + () => ({ + template: + '
' + }) + ], + parameters: { + docs: { + description: { + story: 'AssetCard with a preview image displayed.' + } + } + } +} + +export const FallbackGradient: Story = { + args: { + asset: createAssetData({ + preview_url: undefined + }), + interactive: true + }, + decorators: [ + () => ({ + template: + '
' + }) + ], + parameters: { + docs: { + description: { + story: + 'AssetCard showing fallback gradient when no preview image is available.' + } + } + } +} + export const EdgeCases: Story = { render: () => ({ components: { AssetCard }, diff --git a/src/platform/assets/components/AssetCard.vue b/src/platform/assets/components/AssetCard.vue index dca0d2d64..dd35b4fc1 100644 --- a/src/platform/assets/components/AssetCard.vue +++ b/src/platform/assets/components/AssetCard.vue @@ -4,38 +4,29 @@ data-component-id="AssetCard" :data-asset-id="asset.id" v-bind="elementProps" - :class=" - cn( - // Base layout and container styles (always applied) - 'rounded-xl overflow-hidden transition-all duration-200', - interactive && 'group', - // Button-specific styles - interactive && [ - 'appearance-none bg-transparent p-0 m-0 font-inherit text-inherit outline-none cursor-pointer text-left', - 'bg-gray-100 dark-theme:bg-charcoal-800', - 'hover:bg-gray-200 dark-theme:hover:bg-charcoal-600', - 'border-none', - 'focus:outline-solid outline-blue-100 outline-4' - ], - // Div-specific styles - !interactive && 'bg-gray-100 dark-theme:bg-charcoal-800' - ) - " + :class="cardClasses" @click="interactive && $emit('select', asset)" @keydown.enter="interactive && $emit('select', asset)" > -
+
+

-import { computed } from 'vue' +import { useImage } from '@vueuse/core' +import { computed, useId } from 'vue' import AssetBadgeGroup from '@/platform/assets/components/AssetBadgeGroup.vue' import type { AssetDisplayItem } from '@/platform/assets/composables/useAssetBrowser' @@ -94,13 +87,51 @@ const props = defineProps<{ interactive?: boolean }>() +const titleId = useId() +const descId = useId() + +const { error } = useImage({ + src: props.asset.preview_url ?? '', + alt: props.asset.name +}) + +const shouldShowImage = computed(() => props.asset.preview_url && !error.value) + +const cardClasses = computed(() => { + const base = [ + 'rounded-xl', + 'overflow-hidden', + 'transition-all', + 'duration-200' + ] + + if (!props.interactive) { + return cn(...base, 'bg-gray-100 dark-theme:bg-charcoal-800') + } + + return cn( + ...base, + 'group', + 'appearance-none bg-transparent p-0 m-0', + 'font-inherit text-inherit outline-none cursor-pointer text-left', + 'bg-gray-100 dark-theme:bg-charcoal-800', + 'hover:bg-gray-200 dark-theme:hover:bg-charcoal-600', + 'border-none', + 'focus:outline-solid outline-blue-100 outline-4' + ) +}) + const elementProps = computed(() => props.interactive ? { type: 'button', - 'aria-label': `Select asset ${props.asset.name}` + 'aria-labelledby': titleId, + 'aria-describedby': descId + } + : { + 'aria-labelledby': titleId, + 'aria-describedby': descId } - : {} ) defineEmits<{ diff --git a/src/platform/assets/services/assetService.ts b/src/platform/assets/services/assetService.ts index 613e244a9..626a52d20 100644 --- a/src/platform/assets/services/assetService.ts +++ b/src/platform/assets/services/assetService.ts @@ -12,7 +12,7 @@ import { useModelToNodeStore } from '@/stores/modelToNodeStore' const ASSETS_ENDPOINT = '/assets' const EXPERIMENTAL_WARNING = `EXPERIMENTAL: If you are seeing this please make sure "Comfy.Assets.UseAssetAPI" is set to "false" in your ComfyUI Settings.\n` -const DEFAULT_LIMIT = 300 +const DEFAULT_LIMIT = 500 export const MODELS_TAG = 'models' export const MISSING_TAG = 'missing' diff --git a/tests-ui/tests/services/assetService.test.ts b/tests-ui/tests/services/assetService.test.ts index a1394dace..b6386bc2b 100644 --- a/tests-ui/tests/services/assetService.test.ts +++ b/tests-ui/tests/services/assetService.test.ts @@ -117,7 +117,7 @@ describe('assetService', () => { const result = await assetService.getAssetModelFolders() expect(api.fetchApi).toHaveBeenCalledWith( - '/assets?include_tags=models&limit=300' + '/assets?include_tags=models&limit=500' ) expect(result).toHaveLength(2) @@ -163,7 +163,7 @@ describe('assetService', () => { const result = await assetService.getAssetModels('checkpoints') expect(api.fetchApi).toHaveBeenCalledWith( - '/assets?include_tags=models,checkpoints&limit=300' + '/assets?include_tags=models,checkpoints&limit=500' ) expect(result).toEqual([ expect.objectContaining({ name: 'valid.safetensors', pathIndex: 0 }) @@ -236,7 +236,7 @@ describe('assetService', () => { // Verify API call includes correct category expect(api.fetchApi).toHaveBeenCalledWith( - '/assets?include_tags=models,checkpoints&limit=300' + '/assets?include_tags=models,checkpoints&limit=500' ) }) @@ -297,7 +297,7 @@ describe('assetService', () => { const result = await assetService.getAssetsByTag('models') expect(api.fetchApi).toHaveBeenCalledWith( - '/assets?include_tags=models&limit=300' + '/assets?include_tags=models&limit=500' ) expect(result).toEqual(testAssets) })