From 5687b44422873e8e31566b3c23094b72c07fdc3b Mon Sep 17 00:00:00 2001 From: sno Date: Mon, 23 Feb 2026 10:35:19 +0900 Subject: [PATCH] Add CI validation for OSS assets (fonts and licenses) (#8828) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Adds CI workflow to validate OSS build compliance by checking for proprietary fonts and non-approved dependency licenses. ## Context - Part of comprehensive OSS compliance effort (split from closed PR #6777) - Uses simple bash/grep approach following proven #8623 pattern - Complements telemetry checking in PR #8826 and existing #8354 ## Implementation ### Font Validation - Scans dist/ for proprietary ABCROM fonts (.woff, .woff2, .ttf, .otf) - Fails if any ABCROM fonts found in OSS builds - Provides clear fix instructions ### License Validation - Uses `license-checker` npm package - Validates all production dependencies - Only allows OSI-approved licenses: - MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC - 0BSD, BlueOak-1.0.0, Python-2.0, CC0-1.0 - Unlicense, CC-BY-4.0, CC-BY-3.0 - Common dual-license combinations ### Workflow Details - Two separate jobs for parallel execution - Runs on PRs and pushes to main/dev - Builds with `DISTRIBUTION=localhost` for OSS mode - Clear error messages with remediation steps ## Testing - [ ] Font check passes on current main (no ABCROM fonts in dist) - [ ] License check passes on current main (all approved licenses) - [ ] Intentional violation testing ## Related - Supersedes remaining parts of closed PR #6777 - Complements PR #8826 (Mixpanel telemetry) - Follows pattern from PR #8623 (simple bash/grep) Co-Authored-By: Claude Sonnet 4.5 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8828-Add-CI-validation-for-OSS-assets-fonts-and-licenses-3056d73d3650812390d5d91ca2f319fc) by [Unito](https://www.unito.io) --------- Co-authored-by: Claude Sonnet 4.5 Co-authored-by: bymyself --- .../workflows/ci-oss-assets-validation.yaml | 118 ++++++++++++++++++ .gitignore | 1 + knip.config.ts | 4 +- src/router.ts | 6 +- vite.config.mts | 14 +++ 5 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/ci-oss-assets-validation.yaml diff --git a/.github/workflows/ci-oss-assets-validation.yaml b/.github/workflows/ci-oss-assets-validation.yaml new file mode 100644 index 0000000000..8b38b229bd --- /dev/null +++ b/.github/workflows/ci-oss-assets-validation.yaml @@ -0,0 +1,118 @@ +name: 'CI: OSS Assets Validation' + +on: + pull_request: + branches-ignore: [wip/*, draft/*, temp/*] + push: + branches: [main, dev*] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + validate-fonts: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + + - name: Install pnpm + uses: pnpm/action-setup@9fd676a19091d4595eefd76e4bd31c97133911f1 # v4.2.0 + with: + version: 10 + + - name: Use Node.js + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + with: + node-version: 'lts/*' + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build project + run: pnpm build + env: + DISTRIBUTION: localhost + + - name: Check for proprietary fonts in dist + run: | + set -euo pipefail + echo 'πŸ” Checking dist for proprietary ABCROM fonts...' + + if [ ! -d "dist" ] || [ -z "$(ls -A dist)" ]; then + echo '❌ ERROR: dist/ directory missing or empty!' + exit 1 + fi + + # Check for ABCROM font files + if find dist/ -type f -iname '*abcrom*' \ + \( -name '*.woff' -o -name '*.woff2' -o -name '*.ttf' -o -name '*.otf' \) \ + -print -quit | grep -q .; then + echo '' + echo '❌ ERROR: Found proprietary ABCROM font files in dist!' + echo '' + find dist/ -type f -iname '*abcrom*' \ + \( -name '*.woff' -o -name '*.woff2' -o -name '*.ttf' -o -name '*.otf' \) + echo '' + echo 'ABCROM fonts are proprietary and should not ship to OSS builds.' + echo '' + echo 'To fix this:' + echo '1. Use conditional font loading based on isCloud' + echo '2. Ensure fonts are dynamically imported, not bundled' + echo '3. Check vite config for font handling' + exit 1 + fi + + echo 'βœ… No proprietary fonts found in dist' + + validate-licenses: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + + - name: Install pnpm + uses: pnpm/action-setup@9fd676a19091d4595eefd76e4bd31c97133911f1 # v4.2.0 + with: + version: 10 + + - name: Use Node.js + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + with: + node-version: 'lts/*' + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Validate production dependency licenses + run: | + set -euo pipefail + echo 'πŸ” Checking production dependency licenses...' + + # Use license-checker-rseidelsohn (actively maintained fork, handles monorepos) + # Exclude internal @comfyorg packages from license check + # Run in if condition to capture exit code + if npx license-checker-rseidelsohn@4 \ + --production \ + --summary \ + --excludePackages '@comfyorg/comfyui-frontend;@comfyorg/design-system;@comfyorg/registry-types;@comfyorg/shared-frontend-utils;@comfyorg/tailwind-utils;@comfyorg/comfyui-electron-types' \ + --onlyAllow 'MIT;MIT*;Apache-2.0;BSD-2-Clause;BSD-3-Clause;ISC;0BSD;BlueOak-1.0.0;Python-2.0;CC0-1.0;Unlicense;(MIT OR Apache-2.0);(MIT OR GPL-3.0);(Apache-2.0 OR MIT);(MPL-2.0 OR Apache-2.0);CC-BY-4.0;CC-BY-3.0;GPL-3.0-only'; then + echo '' + echo 'βœ… All production dependency licenses are approved!' + else + echo '' + echo '❌ ERROR: Found dependencies with non-approved licenses!' + echo '' + echo 'To fix this:' + echo '1. Check the license of the problematic package' + echo '2. Find an alternative package with an approved license' + echo '3. If the license is safe and OSI-approved, add it to the --onlyAllow list' + echo '' + echo 'For more info on OSI-approved licenses:' + echo 'https://opensource.org/licenses' + exit 1 + fi diff --git a/.gitignore b/.gitignore index 6eddbcb531..2b4a362d69 100644 --- a/.gitignore +++ b/.gitignore @@ -64,6 +64,7 @@ browser_tests/local/ dist.zip /temp/ +/tmp/ # Generated JSON Schemas /schemas/ diff --git a/knip.config.ts b/knip.config.ts index a9f6310f76..fc8afcfe12 100644 --- a/knip.config.ts +++ b/knip.config.ts @@ -39,7 +39,9 @@ const config: KnipConfig = { 'src/workbench/extensions/manager/types/generatedManagerTypes.ts', 'packages/registry-types/src/comfyRegistryTypes.ts', // Used by a custom node (that should move off of this) - 'src/scripts/ui/components/splitButton.ts' + 'src/scripts/ui/components/splitButton.ts', + // Workflow files contain license names that knip misinterprets as binaries + '.github/workflows/ci-oss-assets-validation.yaml' ], compilers: { // https://github.com/webpro-nl/knip/issues/1008#issuecomment-3207756199 diff --git a/src/router.ts b/src/router.ts index ea60b69cb5..22378d813a 100644 --- a/src/router.ts +++ b/src/router.ts @@ -17,7 +17,11 @@ import LayoutDefault from '@/views/layouts/LayoutDefault.vue' import { installPreservedQueryTracker } from '@/platform/navigation/preservedQueryTracker' import { PRESERVED_QUERY_NAMESPACES } from '@/platform/navigation/preservedQueryNamespaces' -import { cloudOnboardingRoutes } from './platform/cloud/onboarding/onboardingCloudRoutes' + +const cloudOnboardingRoutes = isCloud + ? (await import('./platform/cloud/onboarding/onboardingCloudRoutes')) + .cloudOnboardingRoutes + : [] const isFileProtocol = window.location.protocol === 'file:' diff --git a/vite.config.mts b/vite.config.mts index bf5ed3b5cc..834f6d6794 100644 --- a/vite.config.mts +++ b/vite.config.mts @@ -242,6 +242,20 @@ export default defineConfig({ tailwindcss(), typegpuPlugin({}), comfyAPIPlugin(IS_DEV), + // Exclude proprietary ABCROM fonts from non-cloud builds + { + name: 'exclude-proprietary-fonts', + generateBundle(_options, bundle) { + if (DISTRIBUTION !== 'cloud') { + // Remove ABCROM font files from bundle + for (const [fileName] of Object.entries(bundle)) { + if (/ABCROM.*\.(woff2?|ttf|otf)$/i.test(fileName)) { + delete bundle[fileName] + } + } + } + } + }, // Inject legacy user stylesheet links for desktop/localhost only { name: 'inject-user-stylesheet-links',