diff --git a/.github/workflows/publish-desktop-bridge-types.yaml b/.github/workflows/publish-desktop-bridge-types.yaml new file mode 100644 index 0000000000..2116bbfad2 --- /dev/null +++ b/.github/workflows/publish-desktop-bridge-types.yaml @@ -0,0 +1,142 @@ +name: Publish Desktop Bridge Types + +on: + workflow_dispatch: + inputs: + version: + description: 'Version to publish (e.g., 0.1.2)' + required: true + type: string + dist_tag: + description: 'npm dist-tag to use' + required: true + default: latest + type: string + ref: + description: 'Git ref to checkout (commit SHA, tag, or branch)' + required: false + type: string + workflow_call: + inputs: + version: + required: true + type: string + dist_tag: + required: false + type: string + default: latest + ref: + required: false + type: string + secrets: + NPM_TOKEN: + required: true + +concurrency: + group: publish-desktop-bridge-types-${{ github.workflow }}-${{ inputs.version }}-${{ inputs.dist_tag }} + cancel-in-progress: false + +jobs: + publish_desktop_bridge_types: + name: Publish @comfyorg/comfyui-desktop-bridge-types + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Validate inputs + env: + VERSION: ${{ inputs.version }} + shell: bash + run: | + set -euo pipefail + SEMVER_REGEX='^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)(\.(0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*))*))?(\+([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?$' + if [[ ! "$VERSION" =~ $SEMVER_REGEX ]]; then + echo "::error title=Invalid version::Version '$VERSION' must follow semantic versioning (x.y.z[-suffix][+build])" >&2 + exit 1 + fi + + - name: Determine ref to checkout + id: resolve_ref + env: + REF: ${{ inputs.ref }} + DEFAULT_REF: ${{ github.ref_name }} + shell: bash + run: | + set -euo pipefail + if [ -z "$REF" ]; then + REF="$DEFAULT_REF" + fi + if ! git check-ref-format --allow-onelevel "$REF"; then + echo "::error title=Invalid ref::Ref '$REF' fails git check-ref-format validation." >&2 + exit 1 + fi + echo "ref=$REF" >> "$GITHUB_OUTPUT" + + - name: Checkout repository + uses: actions/checkout@v6 + with: + ref: ${{ steps.resolve_ref.outputs.ref }} + fetch-depth: 1 + persist-credentials: false + + - name: Install pnpm + uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0 + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version-file: '.nvmrc' + cache: 'pnpm' + registry-url: https://registry.npmjs.org + + - name: Install dependencies + run: pnpm install --frozen-lockfile --ignore-scripts + env: + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1' + + - name: Verify package + id: pkg + env: + INPUT_VERSION: ${{ inputs.version }} + shell: bash + run: | + set -euo pipefail + PACKAGE_JSON=packages/comfyui-desktop-bridge-types/package.json + NAME=$(node -p "require('./${PACKAGE_JSON}').name") + VERSION=$(node -p "require('./${PACKAGE_JSON}').version") + if [ "$VERSION" != "$INPUT_VERSION" ]; then + echo "::error title=Version mismatch::${PACKAGE_JSON} version $VERSION does not match input $INPUT_VERSION" >&2 + exit 1 + fi + echo "name=$NAME" >> "$GITHUB_OUTPUT" + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + + - name: Check if version already on npm + id: check_npm + env: + NAME: ${{ steps.pkg.outputs.name }} + VER: ${{ steps.pkg.outputs.version }} + shell: bash + run: | + set -euo pipefail + STATUS=0 + OUTPUT=$(npm view "${NAME}@${VER}" --json 2>&1) || STATUS=$? + if [ "$STATUS" -eq 0 ]; then + echo "exists=true" >> "$GITHUB_OUTPUT" + echo "::warning title=Already published::${NAME}@${VER} already exists on npm. Skipping publish." + else + if echo "$OUTPUT" | grep -q "E404"; then + echo "exists=false" >> "$GITHUB_OUTPUT" + else + echo "::error title=Registry lookup failed::$OUTPUT" >&2 + exit "$STATUS" + fi + fi + + - name: Publish package + if: steps.check_npm.outputs.exists == 'false' + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + DIST_TAG: ${{ inputs.dist_tag }} + run: pnpm publish --access public --tag "$DIST_TAG" --no-git-checks --ignore-scripts + working-directory: packages/comfyui-desktop-bridge-types diff --git a/.github/workflows/release-draft-create.yaml b/.github/workflows/release-draft-create.yaml index a39ca0d026..5ed222046c 100644 --- a/.github/workflows/release-draft-create.yaml +++ b/.github/workflows/release-draft-create.yaml @@ -92,9 +92,7 @@ jobs: make_latest: >- ${{ github.event.pull_request.base.ref == 'main' && needs.build.outputs.is_prerelease == 'false' }} - draft: >- - ${{ github.event.pull_request.base.ref != 'main' || - needs.build.outputs.is_prerelease == 'true' }} + draft: ${{ needs.build.outputs.is_prerelease == 'true' }} prerelease: >- ${{ needs.build.outputs.is_prerelease == 'true' }} generate_release_notes: true diff --git a/apps/website/components.json b/apps/website/components.json new file mode 100644 index 0000000000..9a42978fcb --- /dev/null +++ b/apps/website/components.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://shadcn-vue.com/schema.json", + "style": "new-york", + "font": "inter", + "typescript": true, + "tailwind": { + "config": "", + "css": "src/styles/global.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "iconLibrary": "lucide", + "rtl": false, + "pointer": true, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "composables": "@/composables" + }, + "registries": {} +} diff --git a/apps/website/e2e/navigation.spec.ts b/apps/website/e2e/navigation.spec.ts index 682baddbca..999cef164d 100644 --- a/apps/website/e2e/navigation.spec.ts +++ b/apps/website/e2e/navigation.spec.ts @@ -2,6 +2,13 @@ import { expect } from '@playwright/test' import { test } from './fixtures/blockExternalMedia' +const TOP_LEVEL_LABELS = [ + 'Products', + 'Pricing', + 'Community', + 'Company' +] as const + test.describe('Desktop navigation @smoke', () => { test.beforeEach(async ({ page }) => { await page.goto('/') @@ -17,14 +24,10 @@ test.describe('Desktop navigation @smoke', () => { const nav = page.getByRole('navigation', { name: 'Main navigation' }) const desktopLinks = nav.getByTestId('desktop-nav-links') - for (const label of [ - 'PRODUCTS', - 'PRICING', - 'COMMUNITY', - 'RESOURCES', - 'COMPANY' - ]) { - await expect(desktopLinks.getByText(label).first()).toBeVisible() + for (const label of TOP_LEVEL_LABELS) { + await expect( + desktopLinks.getByText(label, { exact: true }).first() + ).toBeVisible() } }) @@ -49,11 +52,11 @@ test.describe('Desktop dropdown @interaction', () => { const nav = page.getByRole('navigation', { name: 'Main navigation' }) const desktopLinks = nav.getByTestId('desktop-nav-links') const productsButton = desktopLinks.getByRole('button', { - name: /PRODUCTS/i + name: 'Products' }) await productsButton.hover() - const dropdown = productsButton.locator('..').getByTestId('nav-dropdown') + const dropdown = nav.getByTestId('nav-dropdown') for (const item of [ 'Comfy Desktop', 'Comfy Cloud', @@ -67,19 +70,20 @@ test.describe('Desktop dropdown @interaction', () => { test('moving mouse away closes dropdown', async ({ page }) => { const nav = page.getByRole('navigation', { name: 'Main navigation' }) const desktopLinks = nav.getByTestId('desktop-nav-links') - await desktopLinks.getByRole('button', { name: /PRODUCTS/i }).hover() + await desktopLinks.getByRole('button', { name: 'Products' }).hover() const comfyLocal = nav.getByRole('link', { name: 'Comfy Desktop' }).first() await expect(comfyLocal).toBeVisible() - await page.locator('main').hover() + const viewport = page.viewportSize() + await page.mouse.move(10, (viewport?.height ?? 800) - 10) await expect(comfyLocal).toBeHidden() }) test('Escape key closes dropdown', async ({ page }) => { const nav = page.getByRole('navigation', { name: 'Main navigation' }) const desktopLinks = nav.getByTestId('desktop-nav-links') - await desktopLinks.getByRole('button', { name: /PRODUCTS/i }).hover() + await desktopLinks.getByRole('button', { name: 'Products' }).hover() const comfyLocal = nav.getByRole('link', { name: 'Comfy Desktop' }).first() await expect(comfyLocal).toBeVisible() @@ -105,11 +109,11 @@ test.describe('Mobile menu @mobile', () => { }) => { await page.getByRole('button', { name: 'Toggle menu' }).click() - const menu = page.locator('#site-mobile-menu') + const menu = page.getByRole('dialog') await expect(menu).toBeVisible() - for (const label of ['PRODUCTS', 'PRICING', 'COMMUNITY']) { - await expect(menu.getByText(label).first()).toBeVisible() + for (const label of ['Products', 'Pricing', 'Community']) { + await expect(menu.getByText(label, { exact: true }).first()).toBeVisible() } }) @@ -118,24 +122,14 @@ test.describe('Mobile menu @mobile', () => { }) => { await page.getByRole('button', { name: 'Toggle menu' }).click() - const menu = page.locator('#site-mobile-menu') - await menu.getByText('PRODUCTS').first().click() + const menu = page.getByRole('dialog') + await menu.getByRole('button', { name: 'Products' }).click() await expect(menu.getByText('Comfy Desktop')).toBeVisible() await expect(menu.getByText('Comfy Cloud')).toBeVisible() await menu.getByRole('button', { name: /BACK/i }).click() - await expect(menu.getByText('PRODUCTS').first()).toBeVisible() - }) - - test('CTA buttons visible in mobile menu', async ({ page }) => { - await page.getByRole('button', { name: 'Toggle menu' }).click() - - const menu = page.locator('#site-mobile-menu') - await expect( - menu.getByRole('link', { name: 'DOWNLOAD DESKTOP' }) - ).toBeVisible() - await expect(menu.getByRole('link', { name: 'LAUNCH CLOUD' })).toBeVisible() + await expect(menu.getByRole('button', { name: 'Products' })).toBeVisible() }) }) diff --git a/apps/website/e2e/visual-responsive.spec.ts-snapshots/home-get-started-3-lg-visual-linux.png b/apps/website/e2e/visual-responsive.spec.ts-snapshots/home-get-started-3-lg-visual-linux.png index 8baa457ed9..9cca495e6e 100644 Binary files a/apps/website/e2e/visual-responsive.spec.ts-snapshots/home-get-started-3-lg-visual-linux.png and b/apps/website/e2e/visual-responsive.spec.ts-snapshots/home-get-started-3-lg-visual-linux.png differ diff --git a/apps/website/e2e/visual-responsive.spec.ts-snapshots/home-get-started-4-xl-visual-linux.png b/apps/website/e2e/visual-responsive.spec.ts-snapshots/home-get-started-4-xl-visual-linux.png index 467114e646..664794c6ef 100644 Binary files a/apps/website/e2e/visual-responsive.spec.ts-snapshots/home-get-started-4-xl-visual-linux.png and b/apps/website/e2e/visual-responsive.spec.ts-snapshots/home-get-started-4-xl-visual-linux.png differ diff --git a/apps/website/e2e/visual-responsive.spec.ts-snapshots/home-product-cards-3-lg-visual-linux.png b/apps/website/e2e/visual-responsive.spec.ts-snapshots/home-product-cards-3-lg-visual-linux.png index cb240c61e0..79cb386349 100644 Binary files a/apps/website/e2e/visual-responsive.spec.ts-snapshots/home-product-cards-3-lg-visual-linux.png and b/apps/website/e2e/visual-responsive.spec.ts-snapshots/home-product-cards-3-lg-visual-linux.png differ diff --git a/apps/website/e2e/visual-responsive.spec.ts-snapshots/home-product-cards-4-xl-visual-linux.png b/apps/website/e2e/visual-responsive.spec.ts-snapshots/home-product-cards-4-xl-visual-linux.png index eff4a0aee9..88afa29215 100644 Binary files a/apps/website/e2e/visual-responsive.spec.ts-snapshots/home-product-cards-4-xl-visual-linux.png and b/apps/website/e2e/visual-responsive.spec.ts-snapshots/home-product-cards-4-xl-visual-linux.png differ diff --git a/apps/website/e2e/visual-responsive.spec.ts-snapshots/pricing-tiers-3-lg-visual-linux.png b/apps/website/e2e/visual-responsive.spec.ts-snapshots/pricing-tiers-3-lg-visual-linux.png index 9b1571d022..8bf7c36cd9 100644 Binary files a/apps/website/e2e/visual-responsive.spec.ts-snapshots/pricing-tiers-3-lg-visual-linux.png and b/apps/website/e2e/visual-responsive.spec.ts-snapshots/pricing-tiers-3-lg-visual-linux.png differ diff --git a/apps/website/e2e/visual-responsive.spec.ts-snapshots/pricing-tiers-4-xl-visual-linux.png b/apps/website/e2e/visual-responsive.spec.ts-snapshots/pricing-tiers-4-xl-visual-linux.png index 56674ca703..b6ba02ec4b 100644 Binary files a/apps/website/e2e/visual-responsive.spec.ts-snapshots/pricing-tiers-4-xl-visual-linux.png and b/apps/website/e2e/visual-responsive.spec.ts-snapshots/pricing-tiers-4-xl-visual-linux.png differ diff --git a/apps/website/package.json b/apps/website/package.json index 2c7cfe834a..e1168b7102 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -25,12 +25,15 @@ "@comfyorg/object-info-parser": "workspace:*", "@comfyorg/shared-frontend-utils": "workspace:*", "@comfyorg/tailwind-utils": "workspace:*", + "@lucide/vue": "catalog:", "@vercel/analytics": "catalog:", "@vueuse/core": "catalog:", + "class-variance-authority": "catalog:", "cva": "catalog:", "gsap": "catalog:", "lenis": "catalog:", "posthog-js": "catalog:", + "reka-ui": "catalog:", "three": "catalog:", "vue": "catalog:", "zod": "catalog:" @@ -43,6 +46,7 @@ "astro": "catalog:", "tailwindcss": "catalog:", "tsx": "catalog:", + "tw-animate-css": "catalog:", "typescript": "catalog:", "vitest": "catalog:" } diff --git a/apps/website/src/components/common/Badge.vue b/apps/website/src/components/common/Badge.vue deleted file mode 100644 index 0d7879f02a..0000000000 --- a/apps/website/src/components/common/Badge.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/apps/website/src/components/common/ContentSection.vue b/apps/website/src/components/common/ContentSection.vue index a45794b915..17c0a12d17 100644 --- a/apps/website/src/components/common/ContentSection.vue +++ b/apps/website/src/components/common/ContentSection.vue @@ -114,7 +114,7 @@ function scrollToSection(id: string) {
-