Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions .github/workflows/api-update-ingest-api-types.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Description: Receives pre-generated Ingest API types from the cloud repo and creates a PR.
# This workflow does NOT clone the cloud repo. Instead, the cloud repo pushes
# generated files here via repository_dispatch with the spec as payload.
#
# Trigger: Cloud repo runs codegen and dispatches event with generated files.
# See: Comfy-Org/cloud/.github/workflows/push-ingest-types-to-frontend.yaml
name: 'Api: Update Ingest API Types'

on:
workflow_dispatch:
inputs:
openapi_spec_url:
description: 'URL to download the OpenAPI spec (e.g., from a GitHub artifact)'
required: true
type: string
cloud_commit:
description: 'Cloud repo commit SHA (short) for reference'
required: true
type: string

repository_dispatch:
types: [ingest-api-updated]

jobs:
update-ingest-types:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Install pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0
with:
version: 10

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version-file: '.nvmrc'
cache: 'pnpm'

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Resolve inputs
id: resolve
run: |
if [ "${{ github.event_name }}" = "repository_dispatch" ]; then
echo "spec_url=${{ github.event.client_payload.openapi_spec_url }}" >> $GITHUB_OUTPUT
echo "commit=${{ github.event.client_payload.cloud_commit }}" >> $GITHUB_OUTPUT
else
echo "spec_url=${{ inputs.openapi_spec_url }}" >> $GITHUB_OUTPUT
echo "commit=${{ inputs.cloud_commit }}" >> $GITHUB_OUTPUT
fi

- name: Download OpenAPI spec
run: |
curl -fSL "${{ steps.resolve.outputs.spec_url }}" -o packages/ingest-types/openapi.yaml
echo "Downloaded OpenAPI spec from cloud@${{ steps.resolve.outputs.commit }}"

- name: Generate types and Zod schemas
run: |
cd packages/ingest-types
pnpm generate

- name: Validate generated files
run: |
for file in packages/ingest-types/src/types.gen.ts packages/ingest-types/src/zod.gen.ts; do
if [ ! -s "$file" ]; then
echo "Error: $file is missing or empty."
exit 1
fi
done
echo "Generated files validated successfully."

- name: Check for changes
id: check-changes
run: |
if [[ -z $(git status --porcelain packages/ingest-types/src/) ]]; then
echo "No changes to Ingest API types detected."
echo "changed=false" >> $GITHUB_OUTPUT
else
echo "Changes detected in Ingest API types."
echo "changed=true" >> $GITHUB_OUTPUT
fi

- name: Create Pull Request
if: steps.check-changes.outputs.changed == 'true'
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0
with:
token: ${{ secrets.PR_GH_TOKEN }}
commit-message: '[chore] Update Ingest API types from cloud@${{ steps.resolve.outputs.commit }}'
title: '[chore] Update Ingest API types from cloud@${{ steps.resolve.outputs.commit }}'
body: |
## Automated Ingest API Type Update

This PR updates the Ingest API TypeScript types and Zod schemas from the latest cloud OpenAPI specification.

- Cloud commit: ${{ steps.resolve.outputs.commit }}
- Generated using @hey-api/openapi-ts with Zod plugin

These types cover cloud-only endpoints (workspaces, billing, secrets, assets, tasks, etc.).
Overlapping endpoints shared with the local ComfyUI Python backend are excluded.
branch: update-ingest-types-${{ steps.resolve.outputs.commit }}
base: main
delete-branch: true
add-paths: |
packages/ingest-types/src/
11 changes: 9 additions & 2 deletions knip.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@ const config: KnipConfig = {
},
'packages/registry-types': {
project: ['src/**/*.{js,ts}']
},
'packages/ingest-types': {
project: ['src/**/*.{js,ts}'],
entry: ['src/index.ts']
}
},
ignoreBinaries: ['python3', 'gh'],
ignoreBinaries: ['python3', 'gh', 'generate'],
ignoreDependencies: [
// Weird importmap things
'@iconify-json/lucide',
Expand All @@ -41,9 +45,12 @@ const config: KnipConfig = {
'@iconify/utils'
],
ignore: [
// Auto generated manager types
// Auto generated API types
'src/workbench/extensions/manager/types/generatedManagerTypes.ts',
'packages/registry-types/src/comfyRegistryTypes.ts',
'packages/ingest-types/src/types.gen.ts',
'packages/ingest-types/src/zod.gen.ts',
'packages/ingest-types/openapi-ts.config.ts',
// Used by a custom node (that should move off of this)
'src/scripts/ui/components/splitButton.ts',
// Used by stacked PR (feat/glsl-live-preview)
Expand Down
4 changes: 4 additions & 0 deletions packages/ingest-types/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# OpenAPI spec is fetched from cloud repo during CI
openapi.yaml
# Crash logs
openapi-ts-error-*.log
51 changes: 51 additions & 0 deletions packages/ingest-types/openapi-ts.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { defineConfig } from '@hey-api/openapi-ts'

export default defineConfig({
input: './openapi.yaml',
output: {
path: './src',
clean: true
},
parser: {
filters: {
operations: {
// Exclude endpoints that overlap with ComfyUI Python backend.
// These are shared between local and cloud, with separate Zod
// schemas already maintained in src/schemas/apiSchema.ts.
exclude: [
'/^GET \\/api\\/prompt$/',
'/^POST \\/api\\/prompt$/',
'/^GET \\/api\\/queue$/',
'/^POST \\/api\\/queue$/',
'/^GET \\/api\\/history$/',
'/^POST \\/api\\/history$/',
'/^GET \\/api\\/history_v2/',
'/^GET \\/api\\/object_info$/',
'/^GET \\/api\\/features$/',
'/^GET \\/api\\/settings$/',
'/^POST \\/api\\/settings$/',
'/^GET \\/api\\/system_stats$/',
'/^(GET|POST) \\/api\\/interrupt$/',
'/^POST \\/api\\/upload\\//',
'/^GET \\/api\\/view$/',
'/^GET \\/api\\/jobs/',
'/\\/api\\/userdata/',
// Webhooks are server-to-server, not called by frontend
'/\\/api\\/webhooks\\//',
// Internal analytics endpoint
'/\\/api\\/internal\\//'
]
}
}
},
plugins: [
'@hey-api/typescript',
{
name: 'zod',
compatibilityVersion: 3,
definitions: true,
requests: true,
responses: true
}
]
})
26 changes: 26 additions & 0 deletions packages/ingest-types/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "@comfyorg/ingest-types",
"version": "1.0.0",
"description": "Comfy Cloud Ingest API TypeScript types and Zod schemas",
"type": "module",
"exports": {
".": "./src/index.ts",
"./zod": "./src/zod.gen.ts"
},
"scripts": {
"generate": "openapi-ts && node -e \"const fs=require('fs'); ['src/zod.gen.ts'].forEach(f => fs.writeFileSync(f, fs.readFileSync(f,'utf8').replace(\\\"from 'zod/v3'\\\", \\\"from 'zod'\\\")));\""
},
"dependencies": {
"zod": "catalog:"
},
"devDependencies": {
"@hey-api/openapi-ts": "0.93.0"
},
"packageManager": "pnpm@10.17.1",
"nx": {
"tags": [
"scope:shared",
"type:types"
]
}
}
Loading
Loading