Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ history.
`--json` they go to stderr so stdout stays the single envelope. The rate is
measured over the last ten seconds on a timer, so a stalled upload reports a
falling rate instead of going quiet. Schema: `build_push_event.json`.
- `comfy deploy up --watch` and `comfy deploy status` show where a deployment that
is coming up has got to: the step, and while models are copied onto its storage
the model, bytes done of the total, rate and time left ("Staging models: model 1
of 2 sd_xl_base_1.0.safetensors, 3.5 GB of 7.3 GB, 44.2 MB/s, 1m 25s left"). The
numbers are the deploy service's own `progress` object, which `status --json`
and `up --json` now carry while the status is `provisioning` or `starting` and
omit otherwise. Under `--watch`, `--json-stream` emits a `deploy_progress` event
per new sample on stdout and `--json` puts the same lines on stderr. Ctrl-C
during `--watch` stops the watching and nothing else, and prints the command
that re-attaches. A service that sends no `progress` prints what it printed
before. Schema: `deploy_progress_event.json`.
- `comfy build push` prints every warning a save returns, and `--release` cuts no
release while one says a deployment could not download a model link
(`build_release_held`); `--release-despite-warnings` cuts anyway.
Expand All @@ -50,6 +61,18 @@ history.
carries that error code and no pick is marked. The flag is off by default
because it fetches uncached template workflows and calls the local server.

### Changed

- `comfy deploy up` now follows the deployment until it settles, instead of
returning as soon as the deploy service accepts it. A script that relied on
`up` returning at once passes `--no-watch`.
- A watch (`up`, or `status --watch`) now stops at `unhealthy` instead of
waiting for `ready`: the status only ever follows `ready`, so the wait could
last as long as the endpoint stayed degraded, with nothing printed. `up` reports
an unhealthy deployment as not ok (`deploy_status_terminal`, exit 1), with
or without the watch, since it is billing without serving; `status` still
reports it as recoverable.

### Fixed

- `insert_workflow` (`comfy workflow insert-workflow`) now rebases the inserted
Expand Down
28 changes: 26 additions & 2 deletions comfy_cli/command/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from comfy_cli.command.build_spec import BuildSpecInvalidError
from comfy_cli.command.deploy_compute import prompt_gpu as _prompt_gpu
from comfy_cli.command.deploy_compute import prompt_region as _prompt_region
from comfy_cli.command.deploy_progress import DeployWatchReporter
from comfy_cli.command.deploy_resolve import DeployResolveError
from comfy_cli.command.deploy_runtime import command_clients as _command_clients
from comfy_cli.command.deploy_runtime import poll_deployment as _poll_deployment
Expand Down Expand Up @@ -202,6 +203,8 @@ def status_cmd(
typer.Argument(help="ComfyUI install directory or build spec path. Default: the current directory."),
] = None,
deployment_id: DeploymentOption = None,
# `status` answers a question and exits; watching is the caller asking to
# stay, so here it stays opt-in. `up` starts the wait, so there it is on.
watch: Annotated[bool, typer.Option("--watch", help="Poll until the deployment reaches a terminal state.")] = False,
) -> None:
_run_status(path, deployment_id=deployment_id, watch=watch)
Expand Down Expand Up @@ -234,7 +237,16 @@ def up_cmd(
] = None,
release: Annotated[str | None, typer.Option("--release", help="Deploy this release id.")] = None,
deployment_id: DeploymentOption = None,
watch: Annotated[bool, typer.Option("--watch", help="Poll until the deployment reaches a terminal state.")] = False,
# Watching is what someone who just asked for a deployment wants: the command
# that starts a several-minute wait should say how the wait is going. Ctrl-C
# and --no-watch both leave the deploy running and print how to re-attach.
watch: Annotated[
bool,
typer.Option(
"--watch/--no-watch",
help="Follow the deployment until it settles. Use --no-watch to return as soon as it is accepted.",
),
] = True,
) -> None:
renderer = get_renderer()
_require_paired_bounds(renderer, minimum, maximum)
Expand Down Expand Up @@ -270,7 +282,19 @@ def up_cmd(
)
result = reconcile_up(builder, client, replace(request, gpu=selected_gpu, region=selected_region))
if watch:
watched = _poll_deployment(client, _required_string(result.deployment, "id"), _sleep)
watched_id = _required_string(result.deployment, "id")
reporter = DeployWatchReporter(renderer, watched_id)
try:
watched = _poll_deployment(client, watched_id, _sleep, reporter.snapshot)
except KeyboardInterrupt:
# The deploy runs on the service's side and never needed this
# process: say so, report where it had got to, and leave it be.
reporter.interrupted()
if reporter.last is not None:
_render_result(renderer, replace(result, deployment=reporter.last), watch=False)
raise typer.Exit(code=130) from None
finally:
reporter.close()
result = replace(result, deployment=watched)
_render_result(renderer, result, watch=watch)
except (BuildSpecNotFoundError, BuildSpecInvalidError) as error:
Expand Down
Loading
Loading