mirror of
https://github.com/Comfy-Org/ComfyUI-Manager.git
synced 2026-05-11 01:22:37 +08:00
Add UnifiedDepResolver that batch-resolves all custom node pack dependencies via uv pip compile, replacing per-node pip installs. Core features: - Collect, sanitize, and compile requirements from all node packs - Input validation with regex-based sanitization and blacklist/override support - Conflict detection with per-node-pack attribution output - CollectedDeps.sources stores (pack_path, pkg_spec) tuples for attribution - Startup integration via prestartup_script.py with fallback to legacy path - --uv-compile flag on 8 CLI commands: uv-compile, install, reinstall, update, fix, restore-snapshot, restore-dependencies, install-deps Testing: - 148 unit tests (mock-based) covering all resolver logic - 12 E2E pytest tests using ltdrdata's dedicated conflict test packs - E2E environment setup scripts (setup, start, stop) - Supply-chain safety policy: only verified authors' packs in E2E Documentation: - PRD and DESIGN specs for the resolver - EN/KO cm-cli user docs updated for all new commands - Test documentation and environment setup guide Bump version to 4.1b3.
130 lines
4.1 KiB
Bash
Executable File
130 lines
4.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# start_comfyui.sh — Foreground-blocking ComfyUI launcher for E2E tests
|
|
#
|
|
# Starts ComfyUI in the background, then blocks the foreground until the server
|
|
# is ready (or timeout). This makes it safe to call from subprocess.run() or
|
|
# Claude's Bash tool — the call returns only when ComfyUI is accepting requests.
|
|
#
|
|
# Input env vars:
|
|
# E2E_ROOT — (required) path to E2E environment from setup_e2e_env.sh
|
|
# PORT — ComfyUI listen port (default: 8199)
|
|
# TIMEOUT — max seconds to wait for readiness (default: 120)
|
|
#
|
|
# Output (last line on success):
|
|
# COMFYUI_PID=<pid> PORT=<port>
|
|
#
|
|
# Exit: 0=ready, 1=timeout/failure
|
|
|
|
set -euo pipefail
|
|
|
|
# --- Defaults ---
|
|
PORT="${PORT:-8199}"
|
|
TIMEOUT="${TIMEOUT:-120}"
|
|
|
|
# --- Logging helpers ---
|
|
log() { echo "[start_comfyui] $*"; }
|
|
err() { echo "[start_comfyui] ERROR: $*" >&2; }
|
|
die() { err "$@"; exit 1; }
|
|
|
|
# --- Validate environment ---
|
|
[[ -n "${E2E_ROOT:-}" ]] || die "E2E_ROOT is not set"
|
|
[[ -d "$E2E_ROOT/comfyui" ]] || die "ComfyUI not found at $E2E_ROOT/comfyui"
|
|
[[ -x "$E2E_ROOT/venv/bin/python" ]] || die "venv python not found at $E2E_ROOT/venv/bin/python"
|
|
[[ -f "$E2E_ROOT/.e2e_setup_complete" ]] || die "Setup marker not found. Run setup_e2e_env.sh first."
|
|
|
|
PY="$E2E_ROOT/venv/bin/python"
|
|
COMFY_DIR="$E2E_ROOT/comfyui"
|
|
LOG_DIR="$E2E_ROOT/logs"
|
|
LOG_FILE="$LOG_DIR/comfyui.log"
|
|
PID_FILE="$LOG_DIR/comfyui.pid"
|
|
|
|
mkdir -p "$LOG_DIR"
|
|
|
|
# --- Check/clear port ---
|
|
if ss -tlnp 2>/dev/null | grep -q ":${PORT}\b"; then
|
|
log "Port $PORT is in use. Attempting to stop existing process..."
|
|
# Try to read existing PID file
|
|
if [[ -f "$PID_FILE" ]]; then
|
|
OLD_PID="$(cat "$PID_FILE")"
|
|
if kill -0 "$OLD_PID" 2>/dev/null; then
|
|
kill "$OLD_PID" 2>/dev/null || true
|
|
sleep 2
|
|
fi
|
|
fi
|
|
# Fallback: kill by port pattern
|
|
if ss -tlnp 2>/dev/null | grep -q ":${PORT}\b"; then
|
|
pkill -f "main\\.py.*--port $PORT" 2>/dev/null || true
|
|
sleep 2
|
|
fi
|
|
# Final check
|
|
if ss -tlnp 2>/dev/null | grep -q ":${PORT}\b"; then
|
|
die "Port $PORT is still in use after cleanup attempt"
|
|
fi
|
|
log "Port $PORT cleared."
|
|
fi
|
|
|
|
# --- Start ComfyUI ---
|
|
log "Starting ComfyUI on port $PORT..."
|
|
|
|
# Create empty log file (ensures tail -f works from the start)
|
|
: > "$LOG_FILE"
|
|
|
|
# Launch with unbuffered Python output so log lines appear immediately
|
|
PYTHONUNBUFFERED=1 \
|
|
HOME="$E2E_ROOT/home" \
|
|
nohup "$PY" "$COMFY_DIR/main.py" \
|
|
--cpu \
|
|
--enable-manager \
|
|
--port "$PORT" \
|
|
> "$LOG_FILE" 2>&1 &
|
|
COMFYUI_PID=$!
|
|
|
|
echo "$COMFYUI_PID" > "$PID_FILE"
|
|
log "ComfyUI PID=$COMFYUI_PID, log=$LOG_FILE"
|
|
|
|
# Verify process didn't crash immediately
|
|
sleep 1
|
|
if ! kill -0 "$COMFYUI_PID" 2>/dev/null; then
|
|
err "ComfyUI process died immediately. Last 30 lines of log:"
|
|
tail -n 30 "$LOG_FILE" >&2
|
|
rm -f "$PID_FILE"
|
|
exit 1
|
|
fi
|
|
|
|
# --- Block until ready ---
|
|
# tail -n +1 -f: read from file start AND follow new content (no race condition)
|
|
# grep -q -m1: exit on first match → tail gets SIGPIPE → pipeline ends
|
|
# timeout: kill the pipeline after TIMEOUT seconds
|
|
log "Waiting up to ${TIMEOUT}s for ComfyUI to become ready..."
|
|
|
|
if timeout "$TIMEOUT" bash -c \
|
|
"tail -n +1 -f '$LOG_FILE' 2>/dev/null | grep -q -m1 'To see the GUI'"; then
|
|
log "ComfyUI startup message detected."
|
|
else
|
|
err "Timeout (${TIMEOUT}s) waiting for ComfyUI. Last 30 lines of log:"
|
|
tail -n 30 "$LOG_FILE" >&2
|
|
kill "$COMFYUI_PID" 2>/dev/null || true
|
|
rm -f "$PID_FILE"
|
|
exit 1
|
|
fi
|
|
|
|
# Verify process is still alive after readiness detected
|
|
if ! kill -0 "$COMFYUI_PID" 2>/dev/null; then
|
|
err "ComfyUI process died after readiness signal. Last 30 lines:"
|
|
tail -n 30 "$LOG_FILE" >&2
|
|
rm -f "$PID_FILE"
|
|
exit 1
|
|
fi
|
|
|
|
# Optional HTTP health check
|
|
if command -v curl >/dev/null 2>&1; then
|
|
if curl -sf "http://127.0.0.1:${PORT}/system_stats" >/dev/null 2>&1; then
|
|
log "HTTP health check passed (/system_stats)"
|
|
else
|
|
log "HTTP health check skipped (endpoint not yet available, but startup message detected)"
|
|
fi
|
|
fi
|
|
|
|
log "ComfyUI is ready."
|
|
echo "COMFYUI_PID=$COMFYUI_PID PORT=$PORT"
|