name: litegraph-parity # comfy_cli/layout.py places nodes from a model of how ComfyUI_frontend's LiteGraph # renders them. That renderer lives in another repository on another release cadence, # and until this job existed nothing failed when it moved -- the symptom would surface # as overlapping nodes on an agent-built canvas, reported by a user, weeks later. # # Scheduled rather than per-PR on purpose: the input that changes is upstream, not this # repo's diff, so a PR gate would burn a network call on every push and still miss the # drift that happens between them. It also runs on PRs that touch the layout model, and # on demand. on: schedule: - cron: "0 13 * * 1" # Mondays, so a drift is found at the start of a week pull_request: paths: - "comfy_cli/layout.py" - "scripts/check_litegraph_parity.py" - ".github/workflows/litegraph-parity.yml" workflow_dispatch: inputs: ref: description: "ComfyUI_frontend ref to check against" required: false default: "main" permissions: contents: read jobs: parity: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.12" - name: Install uv uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 - name: Install Dependencies # The project's own deps, not a bare pytest: importing anything under # tests/comfy_cli/ pulls in the package, which needs `rich` among others. A # `pip install pytest` alone collects 14 errors before a single test runs. run: uv sync --extra dev --locked - name: Parser unit tests # Offline. The regex is the part most likely to break silently, and it must be # known-good before a failure of the step below can be read as real drift. run: uv run --locked --extra dev pytest tests/comfy_cli/test_litegraph_parity.py -q - name: Check constants against upstream id: check continue-on-error: true run: | set +e uv run --locked --extra dev python scripts/check_litegraph_parity.py --ref "${{ inputs.ref || 'main' }}" status=$? echo "exit_code=$status" >> "$GITHUB_OUTPUT" exit "$status" - name: Report # Exit 1 (drift) and exit 2 (could not read upstream) are different outcomes and # must not be collapsed: a moved file or a network blip is not evidence that the # constants diverged, and treating it as such trains people to ignore this job. run: | status="${{ steps.check.outputs.exit_code }}" case "$status" in 0) echo "geometry constants match upstream" >> "$GITHUB_STEP_SUMMARY" exit 0 ;; 2) { echo "## LiteGraph geometry parity could not run" echo echo "The checker could not read or parse the upstream source. This is not" echo "evidence of geometry drift. Check the upstream ref, source paths, and" echo "network access, then re-run the job." } >> "$GITHUB_STEP_SUMMARY" exit 1 ;; 1) ;; *) echo "## LiteGraph parity checker exited unexpectedly (code: $status)" >> "$GITHUB_STEP_SUMMARY" exit 1 ;; esac { echo "## LiteGraph geometry parity failed" echo echo "\`comfy_cli/layout.py\` models LiteGraph's node geometry. When the two" echo "diverge the CLI places nodes against a picture the browser no longer" echo "draws, and agent-built workflows come out overlapping." echo echo "Re-run the check locally for the detail:" echo echo '```' echo "python scripts/check_litegraph_parity.py" echo '```' echo echo "If upstream genuinely changed: update the constants, then re-baseline the" echo "layout quality metrics in \`tests/comfy_cli/test_layout.py\`." } >> "$GITHUB_STEP_SUMMARY" exit 1