diff --git a/src/prefect/cli/deployment.py b/src/prefect/cli/deployment.py
index 129b25aa3a1c..398fd457653a 100644
--- a/src/prefect/cli/deployment.py
+++ b/src/prefect/cli/deployment.py
@@ -6,7 +6,7 @@
 import sys
 import textwrap
 import warnings
-from datetime import datetime, timedelta, timezone
+from datetime import datetime, timezone
 from pathlib import Path
 from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
 from uuid import UUID
@@ -41,13 +41,9 @@
     exception_traceback,
 )
 from prefect.flow_runs import wait_for_flow_run
-from prefect.flows import load_flow_from_entrypoint
 from prefect.settings import PREFECT_UI_URL
 from prefect.states import Scheduled
-from prefect.utilities.asyncutils import run_sync_in_worker_thread
 from prefect.utilities.collections import listrepr
-from prefect.utilities.dispatch import get_registry_for_type
-from prefect.utilities.filesystem import create_default_ignore_file

 if TYPE_CHECKING:
     from prefect.client.orchestration import PrefectClient
@@ -1272,436 +1268,6 @@ async def delete(
             exit_with_error("Must provide a deployment name or id")

-builtin_infrastructure_types = [
-    slug
-    for slug, block in get_registry_for_type(Block).items()
-    if "run-infrastructure" in block.get_block_capabilities()
-]
-
-
-@deployment_app.command(
-    deprecated=True,
-    deprecated_start_date="Mar 2024",
-    deprecated_name="deployment build",
-    deprecated_help="Use 'prefect deploy' to deploy flows via YAML instead.",
-)
-async def build(
-    entrypoint: str = typer.Argument(
-        ...,
-        help=(
-            "The path to a flow entrypoint, in the form of"
-            " `./path/to/file.py:flow_func_name`"
-        ),
-    ),
-    name: str = typer.Option(
-        None, "--name", "-n", help="The name to give the deployment."
-    ),
-    description: str = typer.Option(
-        None,
-        "--description",
-        "-d",
-        help=(
-            "The description to give the deployment. If not provided, the description"
-            " will be populated from the flow's description."
-        ),
-    ),
-    version: str = typer.Option(
-        None, "--version", "-v", help="A version to give the deployment."
-    ),
-    tags: List[str] = typer.Option(
-        None,
-        "-t",
-        "--tag",
-        help=(
-            "One or more optional tags to apply to the deployment. Note: tags are used"
-            " only for organizational purposes. For delegating work to agents, use the"
-            " --work-queue flag."
-        ),
-    ),
-    work_queue_name: str = typer.Option(
-        None,
-        "-q",
-        "--work-queue",
-        help=(
-            "The work queue that will handle this deployment's runs. "
-            "It will be created if it doesn't already exist. Defaults to `None`. "
-            "Note that if a work queue is not set, work will not be scheduled."
-        ),
-    ),
-    work_pool_name: str = typer.Option(
-        None,
-        "-p",
-        "--pool",
-        help="The work pool that will handle this deployment's runs.",
-    ),
-    work_queue_concurrency: int = typer.Option(
-        None,
-        "--limit",
-        "-l",
-        help=(
-            "Sets the concurrency limit on the work queue that handles this"
-            " deployment's runs"
-        ),
-    ),
-    infra_type: str = typer.Option(
-        None,
-        "--infra",
-        "-i",
-        help="The infrastructure type to use, prepopulated with defaults. For example: "
-        + listrepr(builtin_infrastructure_types, sep=", "),
-    ),
-    infra_block: str = typer.Option(
-        None,
-        "--infra-block",
-        "-ib",
-        help="The slug of the infrastructure block to use as a template.",
-    ),
-    overrides: List[str] = typer.Option(
-        None,
-        "--override",
-        help=(
-            "One or more optional infrastructure overrides provided as a dot delimited"
-            " path, e.g., `env.env_key=env_value`"
-        ),
-    ),
-    storage_block: str = typer.Option(
-        None,
-        "--storage-block",
-        "-sb",
-        help=(
-            "The slug of a remote storage block. Use the syntax:"
-            " 'block_type/block_name', where block_type is one of 'github', 's3',"
-            " 'gcs', 'azure', 'smb', or a registered block from a library that"
-            " implements the WritableDeploymentStorage interface such as"
-            " 'gitlab-repository', 'bitbucket-repository', 's3-bucket',"
-            " 'gcs-bucket'"
-        ),
-    ),
-    skip_upload: bool = typer.Option(
-        False,
-        "--skip-upload",
-        help=(
-            "A flag that, when provided, skips uploading this deployment's files to"
-            " remote storage."
-        ),
-    ),
-    cron: str = typer.Option(
-        None,
-        "--cron",
-        help="A cron string that will be used to set a CronSchedule on the deployment.",
-    ),
-    interval: int = typer.Option(
-        None,
-        "--interval",
-        help=(
-            "An integer specifying an interval (in seconds) that will be used to set an"
-            " IntervalSchedule on the deployment."
-        ),
-    ),
-    interval_anchor: Optional[str] = typer.Option(
-        None, "--anchor-date", help="The anchor date for an interval schedule"
-    ),
-    rrule: str = typer.Option(
-        None,
-        "--rrule",
-        help="An RRule that will be used to set an RRuleSchedule on the deployment.",
-    ),
-    timezone: str = typer.Option(
-        None,
-        "--timezone",
-        help="Deployment schedule timezone string e.g. 'America/New_York'",
-    ),
-    path: str = typer.Option(
-        None,
-        "--path",
-        help=(
-            "An optional path to specify a subdirectory of remote storage to upload to,"
-            " or to point to a subdirectory of a locally stored flow."
-        ),
-    ),
-    output: str = typer.Option(
-        None,
-        "--output",
-        "-o",
-        help="An optional filename to write the deployment file to.",
-    ),
-    _apply: bool = typer.Option(
-        False,
-        "--apply",
-        "-a",
-        help=(
-            "An optional flag to automatically register the resulting deployment with"
-            " the API."
-        ),
-    ),
-    param: List[str] = typer.Option(
-        None,
-        "--param",
-        help=(
-            "An optional parameter override, values are parsed as JSON strings e.g."
-            " --param question=ultimate --param answer=42"
-        ),
-    ),
-    params: str = typer.Option(
-        None,
-        "--params",
-        help=(
-            "An optional parameter override in a JSON string format e.g."
-            ' --params=\'{"question": "ultimate", "answer": 42}\''
-        ),
-    ),
-    no_schedule: bool = typer.Option(
-        False,
-        "--no-schedule",
-        help="An optional flag to disable scheduling for this deployment.",
-    ),
-):
-    """
-    Generate a deployment YAML from /path/to/file.py:flow_function
-    """
-    # validate inputs
-    if not name:
-        exit_with_error(
-            "A name for this deployment must be provided with the '--name' flag."
-        )
-
-    if (
-        len([value for value in (cron, rrule, interval) if value is not None])
-        + (1 if no_schedule else 0)
-        > 1
-    ):
-        exit_with_error("Only one schedule type can be provided.")
-
-    if infra_block and infra_type:
-        exit_with_error(
-            "Only one of `infra` or `infra_block` can be provided, please choose one."
-        )
-
-    output_file = None
-    if output:
-        output_file = Path(output)
-        if output_file.suffix and output_file.suffix != ".yaml":
-            exit_with_error("Output file must be a '.yaml' file.")
-        else:
-            output_file = output_file.with_suffix(".yaml")
-
-    # validate flow
-    try:
-        fpath, obj_name = entrypoint.rsplit(":", 1)
-    except ValueError as exc:
-        if str(exc) == "not enough values to unpack (expected 2, got 1)":
-            missing_flow_name_msg = (
-                "Your flow entrypoint must include the name of the function that is"
-                f" the entrypoint to your flow.\nTry {entrypoint}:<flow_name>"
-            )
-            exit_with_error(missing_flow_name_msg)
-        else:
-            raise exc
-    try:
-        flow = await run_sync_in_worker_thread(load_flow_from_entrypoint, entrypoint)
-    except Exception as exc:
-        exit_with_error(exc)
-    app.console.print(f"Found flow {flow.name!r}", style="green")
-    job_variables = {}
-    for override in overrides or []:
-        key, value = override.split("=", 1)
-        job_variables[key] = value
-
-    if infra_block:
-        infrastructure = await Block.load(infra_block)
-    elif infra_type:
-        # Create an instance of the given type
-        infrastructure = Block.get_block_class_from_key(infra_type)()
-    else:
-        # will reset to a default of Process is no infra is present on the
-        # server-side definition of this deployment
-        infrastructure = None
-
-    if interval_anchor and not interval:
-        exit_with_error("An anchor date can only be provided with an interval schedule")
-
-    schedule = None
-    if cron:
-        cron_kwargs = {"cron": cron, "timezone": timezone}
-        schedule = CronSchedule(
-            **{k: v for k, v in cron_kwargs.items() if v is not None}
-        )
-    elif interval:
-        interval_kwargs = {
-            "interval": timedelta(seconds=interval),
-            "anchor_date": interval_anchor,
-            "timezone": timezone,
-        }
-        schedule = IntervalSchedule(
-            **{k: v for k, v in interval_kwargs.items() if v is not None}
-        )
-    elif rrule:
-        try:
-            schedule = RRuleSchedule(**json.loads(rrule))
-            if timezone:
-                # override timezone if specified via CLI argument
-                schedule.timezone = timezone
-        except json.JSONDecodeError:
-            schedule = RRuleSchedule(rrule=rrule, timezone=timezone)
-
-    # parse storage_block
-    if storage_block:
-        block_type, block_name, *block_path = storage_block.split("/")
-        if block_path and path:
-            exit_with_error(
-                "Must provide a `path` explicitly or provide one on the storage block"
-                " specification, but not both."
-            )
-        elif not path:
-            path = "/".join(block_path)
-        storage_block = f"{block_type}/{block_name}"
-        storage = await Block.load(storage_block)
-    else:
-        storage = None
-
-    if create_default_ignore_file(path="."):
-        app.console.print(
-            (
-                "Default '.prefectignore' file written to"
-                f" {(Path('.') / '.prefectignore').absolute()}"
-            ),
-            style="green",
-        )
-
-    if param and (params is not None):
-        exit_with_error("Can only pass one of `param` or `params` options")
-
-    parameters = dict()
-
-    if param:
-        for p in param or []:
-            k, unparsed_value = p.split("=", 1)
-            try:
-                v = json.loads(unparsed_value)
-                app.console.print(
-                    f"The parameter value {unparsed_value} is parsed as a JSON string"
-                )
-            except json.JSONDecodeError:
-                v = unparsed_value
-            parameters[k] = v
-
-    if params is not None:
-        parameters = json.loads(params)
-
-    # set up deployment object
-    entrypoint = (
-        f"{Path(fpath).absolute().relative_to(Path('.').absolute())}:{obj_name}"
-    )
-
-    init_kwargs = dict(
-        path=path,
-        entrypoint=entrypoint,
-        version=version,
-        storage=storage,
-        job_variables=job_variables or {},
-    )
-
-    if parameters:
-        init_kwargs["parameters"] = parameters
-
-    if description:
-        init_kwargs["description"] = description
-
-    # if a schedule, tags, work_queue_name, or infrastructure are not provided via CLI,
-    # we let `build_from_flow` load them from the server
-    if schedule or no_schedule:
-        init_kwargs.update(schedule=schedule)
-    if tags:
-        init_kwargs.update(tags=tags)
-    if infrastructure:
-        init_kwargs.update(infrastructure=infrastructure)
-    if work_queue_name:
-        init_kwargs.update(work_queue_name=work_queue_name)
-    if work_pool_name:
-        init_kwargs.update(work_pool_name=work_pool_name)
-
-    deployment_loc = output_file or f"{obj_name}-deployment.yaml"
-    deployment = await Deployment.build_from_flow(
-        flow=flow,
-        name=name,
-        output=deployment_loc,
-        skip_upload=skip_upload,
-        apply=False,
-        **init_kwargs,
-    )
-    app.console.print(
-        f"Deployment YAML created at '{Path(deployment_loc).absolute()!s}'.",
-        style="green",
-    )
-
-    await create_work_queue_and_set_concurrency_limit(
-        deployment.work_queue_name, deployment.work_pool_name, work_queue_concurrency
-    )
-
-    # we process these separately for informative output
-    if not skip_upload:
-        if (
-            deployment.storage
-            and "put-directory" in deployment.storage.get_block_capabilities()
-        ):
-            file_count = await deployment.upload_to_storage()
-            if file_count:
-                app.console.print(
-                    (
-                        f"Successfully uploaded {file_count} files to"
-                        f" {deployment.location}"
-                    ),
-                    style="green",
-                )
-        else:
-            app.console.print(
-                (
-                    f"Deployment storage {deployment.storage} does not have upload"
-                    " capabilities; no files uploaded.  Pass --skip-upload to suppress"
-                    " this warning."
-                ),
-                style="green",
-            )
-
-    if _apply:
-        async with get_client() as client:
-            await check_work_pool_exists(
-                work_pool_name=deployment.work_pool_name, client=client
-            )
-            deployment_id = await deployment.apply()
-            app.console.print(
-                (
-                    f"Deployment '{deployment.flow_name}/{deployment.name}'"
-                    f" successfully created with id '{deployment_id}'."
-                ),
-                style="green",
-            )
-            if deployment.work_pool_name is not None:
-                await _print_deployment_work_pool_instructions(
-                    work_pool_name=deployment.work_pool_name, client=client
-                )
-
-            elif deployment.work_queue_name is not None:
-                app.console.print(
-                    "\nTo execute flow runs from this deployment, start an agent that"
-                    f" pulls work from the {deployment.work_queue_name!r} work queue:"
-                )
-                app.console.print(
-                    f"$ prefect agent start -q {deployment.work_queue_name!r}",
-                    style="blue",
-                )
-            else:
-                app.console.print(
-                    (
-                        "\nThis deployment does not specify a work queue name, which"
-                        " means agents will not be able to pick up its runs. To add a"
-                        " work queue, edit the deployment spec and re-run this command,"
-                        " or visit the deployment in the UI."
-                    ),
-                    style="red",
-                )
-
-
 def _load_json_key_values(
     cli_input: List[str], display_name: str
 ) -> Dict[str, Union[dict, str, int]]:

diff --git a/tests/cli/deployment/test_deployment_build.py b/tests/cli/deployment/test_deployment_build.py
deleted file mode 100644
index 0ef5a829d1e7..000000000000
--- a/tests/cli/deployment/test_deployment_build.py
+++ /dev/null
@@ -1,1311 +0,0 @@
-from datetime import timedelta
-from pathlib import Path
-from textwrap import dedent
-from unittest.mock import Mock
-
-import pendulum
-import pytest
-
-import prefect.server.models as models
-import prefect.server.schemas as schemas
-from prefect import flow
-from prefect.deployments import Deployment
-from prefect.filesystems import LocalFileSystem
-from prefect.infrastructure import Process
-from prefect.testing.cli import invoke_and_assert
-from prefect.testing.utilities import AsyncMock
-from prefect.utilities.asyncutils import run_sync_in_worker_thread
-
-
-@pytest.fixture
-def patch_import(monkeypatch):
-    @flow(description="Need a non-trivial description here.", version="A")
-    def fn():
-        pass
-
-    monkeypatch.setattr(
-        "prefect.cli.deployment.load_flow_from_entrypoint", lambda path: fn
-    )
-    return fn
-
-
-@pytest.fixture
-def dep_path():
-    return "./dog.py"
-
-
-@pytest.fixture
-def built_deployment_with_queue_and_limit_overrides(patch_import, tmp_path):
-    d = Deployment(
-        name="TEST",
-        flow_name="fn",
-    )
-    d.apply()
-
-    invoke_and_assert(
-        [
-            "deployment",
-            "build",
-            "fake-path.py:fn",
-            "-n",
-            "TEST",
-            "-o",
-            str(tmp_path / "test.yaml"),
-            "-q",
-            "the-queue-to-end-all-queues",
-            "--limit",
-            "424242",
-        ],
-        expected_code=0,
-        temp_dir=tmp_path,
-    )
-
-
-@pytest.fixture
-def applied_deployment_with_queue_and_limit_overrides(patch_import, tmp_path):
-    d = Deployment(
-        name="TEST",
-        flow_name="fn",
-    )
-    d.apply()
-
-    invoke_and_assert(
-        [
-            "deployment",
-            "build",
-            "fake-path.py:fn",
-            "-n",
-            "TEST",
-            "-o",
-            str(tmp_path / "test.yaml"),
-            "-q",
-            "the-mother-of-all-queues",
-        ],
-        expected_code=0,
-        temp_dir=tmp_path,
-    )
-    invoke_and_assert(
-        [
-            "deployment",
-            "apply",
-            str(tmp_path / "test.yaml"),
-            "-l",
-            "4242",
-        ],
-        expected_code=0,
-        temp_dir=tmp_path,
-    )
-
-
-@pytest.fixture
-def storage_block(tmp_path):
-    storage = LocalFileSystem(basepath=tmp_path / "storage")
-    storage.save(name="test-storage-block")
-    return storage
-
-
-@pytest.fixture
-def infra_block(tmp_path):
-    infra = Process()
-    infra.save(name="test-infra-block")
-    return infra
-
-
-@pytest.fixture
-def mock_build_from_flow(monkeypatch):
-    mock_build_from_flow = AsyncMock()
-
-    # needed to handle `if deployment.storage` check
-    ret = Mock()
-    ret.storage = None
-    mock_build_from_flow.return_value = ret
-
-    monkeypatch.setattr(
-        "prefect.cli.deployment.Deployment.build_from_flow", mock_build_from_flow
-    )
-
-    # not needed for test
-    monkeypatch.setattr(
-        "prefect.cli.deployment.create_work_queue_and_set_concurrency_limit",
-        AsyncMock(),
-    )
-
-    return mock_build_from_flow
-
-
-@pytest.fixture(autouse=True)
-def mock_create_default_ignore_file(monkeypatch):
-    mock_create_default_ignore_file = Mock(return_value=True)
-
-    monkeypatch.setattr(
-        "prefect.cli.deployment.create_default_ignore_file",
-        mock_create_default_ignore_file,
-    )
-
-    return mock_create_default_ignore_file
-
-
-@pytest.fixture(autouse=True)
-async def ensure_default_agent_pool_exists(session):
-    # The default agent work pool is created by a migration, but is cleared on
-    # consecutive test runs. This fixture ensures that the default agent work
-    # pool exists before each test.
-    default_work_pool = await models.workers.read_work_pool_by_name(
-        session=session, work_pool_name=models.workers.DEFAULT_AGENT_WORK_POOL_NAME
-    )
-    if default_work_pool is None:
-        default_work_pool = await models.workers.create_work_pool(
-            session=session,
-            work_pool=schemas.actions.WorkPoolCreate(
-                name=models.workers.DEFAULT_AGENT_WORK_POOL_NAME, type="prefect-agent"
-            ),
-        )
-        await session.commit()
-    assert default_work_pool is not None
-
-
-def test_deployment_build_prints_deprecation_warning(tmp_path, patch_import):
-    invoke_and_assert(
-        [
-            "deployment",
-            "build",
-            "fake-path.py:fn",
-            "-n",
-            "TEST",
-            "-o",
-            str(tmp_path / "test.yaml"),
-            "--no-schedule",
-        ],
-        temp_dir=tmp_path,
-        expected_output_contains=(
-            "WARNING: The 'deployment build' command has been deprecated.",
-            "It will not be available after Sep 2024.",
-            "Use 'prefect deploy' to deploy flows via YAML instead.",
-        ),
-    )
-
-
-class TestSchedules:
-    def test_passing_no_schedule_and_cron_schedules_to_build_exits_with_error(
-        self, patch_import, tmp_path
-    ):
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-                "--no-schedule",
-                "--cron",
-                "0 4 * * *",
-                "--timezone",
-                "Europe/Berlin",
-            ],
-            expected_code=1,
-            expected_output_contains="Only one schedule type can be provided.",
-            temp_dir=tmp_path,
-        )
-
-    def test_passing_no_schedule_to_build(self, patch_import, tmp_path):
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-                "--no-schedule",
-            ],
-            expected_code=0,
-            temp_dir=tmp_path,
-        )
-
-        deployment = Deployment.load_from_yaml(tmp_path / "test.yaml")
-        assert deployment.schedules == []
-
-    def test_passing_cron_schedules_to_build(self, patch_import, tmp_path):
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-                "--cron",
-                "0 4 * * *",
-                "--timezone",
-                "Europe/Berlin",
-            ],
-            expected_code=0,
-            temp_dir=tmp_path,
-        )
-
-        deployment = Deployment.load_from_yaml(tmp_path / "test.yaml")
-        schedule = deployment.schedules[0].schedule
-        assert schedule.cron == "0 4 * * *"
-        assert schedule.timezone == "Europe/Berlin"
-
-    def test_passing_interval_schedules_to_build(self, patch_import, tmp_path):
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-                "--interval",
-                "42",
-                "--anchor-date",
-                "2040-02-02",
-                "--timezone",
-                "America/New_York",
-            ],
-            expected_code=0,
-            temp_dir=tmp_path,
-        )
-
-        deployment = Deployment.load_from_yaml(tmp_path / "test.yaml")
-        schedule = deployment.schedules[0].schedule
-        assert schedule.interval == timedelta(seconds=42)
-        assert schedule.anchor_date == pendulum.parse("2040-02-02")
-        assert schedule.timezone == "America/New_York"
-
-    def test_passing_anchor_without_interval_exits(self, patch_import, tmp_path):
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-                "--anchor-date",
-                "2018-02-02",
-            ],
-            expected_code=1,
-            temp_dir=tmp_path,
-            expected_output_contains=(
-                "An anchor date can only be provided with an interval schedule"
-            ),
-        )
-
-    def test_parsing_rrule_schedule_string_literal(self, patch_import, tmp_path):
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-                "--rrule",
-                "DTSTART:20220910T110000\nRRULE:FREQ=HOURLY;BYDAY=MO,TU,WE,TH,FR,SA;BYHOUR=9,10,11,12,13,14,15,16,17",
-            ],
-            expected_code=0,
-            temp_dir=tmp_path,
-        )
-
-        deployment = Deployment.load_from_yaml(tmp_path / "test.yaml")
-        schedule = deployment.schedules[0].schedule
-        assert (
-            schedule.rrule
-            == "DTSTART:20220910T110000\nRRULE:FREQ=HOURLY;BYDAY=MO,TU,WE,TH,FR,SA;BYHOUR=9,10,11,12,13,14,15,16,17"
-        )
-
-    def test_parsing_rrule_schedule_json(self, patch_import, tmp_path):
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-                "--rrule",
-                (
-                    '{"rrule":'
-                    ' "DTSTART:20220910T110000\\nRRULE:FREQ=HOURLY;BYDAY=MO,TU,WE,TH,FR,SA;BYHOUR=9,10,11,12,13,14,15,16,17",'
-                    ' "timezone": "America/New_York"}'
-                ),
-            ],
-            expected_code=0,
-            temp_dir=tmp_path,
-        )
-
-        deployment = Deployment.load_from_yaml(tmp_path / "test.yaml")
-        schedule = deployment.schedules[0].schedule
-        assert (
-            schedule.rrule
-            == "DTSTART:20220910T110000\nRRULE:FREQ=HOURLY;BYDAY=MO,TU,WE,TH,FR,SA;BYHOUR=9,10,11,12,13,14,15,16,17"
-        )
-        assert schedule.timezone == "America/New_York"
-
-    def test_parsing_rrule_timezone_overrides_if_passed_explicitly(
-        self, patch_import, tmp_path
-    ):
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-                "--rrule",
-                (
-                    '{"rrule":'
-                    ' "DTSTART:20220910T110000\\nRRULE:FREQ=HOURLY;BYDAY=MO,TU,WE,TH,FR,SA;BYHOUR=9,10,11,12,13,14,15,16,17",'
-                    ' "timezone": "America/New_York"}'
-                ),
-                "--timezone",
-                "Europe/Berlin",
-            ],
-            expected_code=0,
-            temp_dir=tmp_path,
-        )
-
-        deployment = Deployment.load_from_yaml(tmp_path / "test.yaml")
-        schedule = deployment.schedules[0].schedule
-        assert (
-            schedule.rrule
-            == "DTSTART:20220910T110000\nRRULE:FREQ=HOURLY;BYDAY=MO,TU,WE,TH,FR,SA;BYHOUR=9,10,11,12,13,14,15,16,17"
-        )
-        assert schedule.timezone == "Europe/Berlin"
-
-    @pytest.mark.parametrize(
-        "schedules",
-        [
-            ["--cron", "cron-str", "--interval", 42],
-            ["--rrule", "rrule-str", "--interval", 42],
-            ["--rrule", "rrule-str", "--cron", "cron-str"],
-            ["--rrule", "rrule-str", "--cron", "cron-str", "--interval", 42],
-        ],
-    )
-    def test_providing_multiple_schedules_exits_with_error(
-        self, patch_import, tmp_path, schedules
-    ):
-        name = "TEST"
-        output_path = str(tmp_path / "test.yaml")
-        entrypoint = "fake-path.py:fn"
-        cmd = [
-            "deployment",
-            "build",
-            entrypoint,
-            "-n",
-            name,
-            "-o",
-            output_path,
-        ]
-        cmd += schedules
-
-        invoke_and_assert(
-            cmd,
-            expected_code=1,
-            expected_output_contains="Only one schedule type can be provided.",
-        )
-
-
-class TestParameterOverrides:
-    def test_param_overrides(self, patch_import, tmp_path):
-        d = Deployment(
-            name="TEST",
-            flow_name="fn",
-        )
-        d.apply()
-
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-                "--param",
-                "foo=bar",
-                "--param",
-                'greenman_says={"parsed as json": "I am"}',
-            ],
-            expected_code=0,
-            temp_dir=tmp_path,
-        )
-
-        deployment = Deployment.load_from_yaml(tmp_path / "test.yaml")
-        assert deployment.parameters["foo"] == "bar"
-        assert deployment.parameters["greenman_says"] == {"parsed as json": "I am"}
-
-    def test_parameters_override(self, patch_import, tmp_path):
-        d = Deployment(
-            name="TEST",
-            flow_name="fn",
-        )
-        d.apply()
-
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-                "--params",
-                '{"greenman_says": {"parsed as json": "I am"}}',
-            ],
-            expected_code=0,
-            temp_dir=tmp_path,
-        )
-
-        deployment = Deployment.load_from_yaml(tmp_path / "test.yaml")
-        assert deployment.parameters["greenman_says"] == {"parsed as json": "I am"}
-
-    def test_mixing_parameter_overrides(self, patch_import, tmp_path):
-        d = Deployment(
-            name="TEST",
-            flow_name="fn",
-        )
-        d.apply()
-
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-                "--params",
-                '{"which": "parameter"}',
-                "--param",
-                "should-be:used",
-            ],
-            expected_code=1,
-            temp_dir=tmp_path,
-        )
-
-
-class TestFlowName:
-    @pytest.mark.filterwarnings("ignore:does not have upload capabilities")
-    def test_flow_name_called_correctly(
-        self, patch_import, tmp_path, mock_build_from_flow
-    ):
-        name = "TEST"
-        output_path = str(tmp_path / "test.yaml")
-        entrypoint = "fake-path.py:fn"
-        cmd = [
-            "deployment",
-            "build",
-            entrypoint,
-            "-n",
-            name,
-            "-o",
-            output_path,
-        ]
-
-        invoke_and_assert(
-            cmd,
-            expected_code=0,
-        )
-
-        build_kwargs = mock_build_from_flow.call_args.kwargs
-        assert build_kwargs["name"] == name
-
-    def test_not_providing_name_exits_with_error(self, patch_import, tmp_path):
-        output_path = str(tmp_path / "test.yaml")
-        entrypoint = "fake-path.py:fn"
-        cmd = [
-            "deployment",
-            "build",
-            entrypoint,
-            "-o",
-            output_path,
-        ]
-
-        invoke_and_assert(
-            cmd,
-            expected_code=1,
-            expected_output_contains=(
-                "A name for this deployment must be provided with the '--name' flag.\n"
-            ),
-        )
-
-    def test_name_must_be_provided_by_default(self, dep_path):
-        invoke_and_assert(
-            ["deployment", "build", dep_path],
-            expected_output_contains=["A name for this deployment must be provided"],
-            expected_code=1,
-        )
-
-
-class TestDescription:
-    @pytest.mark.filterwarnings("ignore:does not have upload capabilities")
-    def test_description_set_correctly(
-        self, patch_import, tmp_path, mock_build_from_flow
-    ):
-        deployment_description = "TEST DEPLOYMENT"
-        output_path = str(tmp_path / "test.yaml")
-        entrypoint = "fake-path.py:fn"
-        cmd = [
-            "deployment",
-            "build",
-            entrypoint,
-            "-n",
-            "TEST",
-            "--description",
-            deployment_description,
-            "-o",
-            output_path,
-        ]
-
-        invoke_and_assert(
-            cmd,
-            expected_code=0,
-        )
-
-        build_kwargs = mock_build_from_flow.call_args.kwargs
-        assert build_kwargs["description"] == deployment_description
-
-
-class TestEntrypoint:
-    def test_entrypoint_is_saved_as_relative_path(self, patch_import, tmp_path):
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-            ],
-            expected_code=0,
-            temp_dir=tmp_path,
-        )
-
-        deployment = Deployment.load_from_yaml(tmp_path / "test.yaml")
-        assert deployment.entrypoint == "fake-path.py:fn"
-
-    def test_poorly_formed_entrypoint_raises_correct_error(
-        self, patch_import, tmp_path
-    ):
-        name = "TEST"
-        file_name = "test_no_suffix"
-        str(tmp_path / file_name)
-        entrypoint = "fake-path.py"
-        cmd = ["deployment", "build", "-n", name]
-        cmd += [entrypoint]
-
-        invoke_and_assert(
-            cmd,
-            expected_code=1,
-            expected_output_contains=(
-                "Your flow entrypoint must include the name of the function that is"
-                f" the entrypoint to your flow.\nTry {entrypoint}:<flow_name>"
-            ),
-        )
-
-    def test_entrypoint_that_does_not_point_to_flow_raises_error(self, tmp_path):
-        code = """
-        def fn():
-            pass
-        """
-        fpath = tmp_path / "dog.py"
-        fpath.write_text(dedent(code))
-
-        name = "TEST"
-        entrypoint = f"{fpath}:fn"
-        cmd = ["deployment", "build", "-n", name]
-        cmd += [entrypoint]
-
-        invoke_and_assert(
-            cmd,
-            expected_code=1,
-            expected_output_contains=(
-                "Function with name 'fn' is not a flow. Make sure that it is decorated"
-                " with '@flow'"
-            ),
-        )
-
-    def test_entrypoint_that_points_to_wrong_flow_raises_error(self, tmp_path):
-        code = """
-        from prefect import flow
-
-        @flow
-        def cat():
-            pass
-        """
-        fpath = tmp_path / "dog.py"
-        fpath.write_text(dedent(code))
-
-        name = "TEST"
-        entrypoint = f"{fpath}:fn"
-        cmd = ["deployment", "build", "-n", name]
-        cmd += [entrypoint]
-
-        invoke_and_assert(
-            cmd,
-            expected_code=1,
-            expected_output_contains=(
-                f"Flow function with name 'fn' not found in {str(fpath)!r}"
-            ),
-        )
-
-    def test_entrypoint_that_does_not_point_to_python_file_raises_error(self, tmp_path):
-        code = """
-        def fn():
-            pass
-        """
-        fpath = tmp_path / "dog.cake"
-        fpath.write_text(dedent(code))
-
-        name = "TEST"
-        entrypoint = f"{fpath}:fn"
-        cmd = ["deployment", "build", "-n", name]
-        cmd += [entrypoint]
-
-        invoke_and_assert(
-            cmd,
-            expected_code=1,
-            expected_output_contains="No module named ",
-        )
-
-    def test_entrypoint_works_with_flow_with_custom_name(self, tmp_path, monkeypatch):
-        flow_code = """
-        from prefect import flow
-
-        @flow(name="SoMe CrAz_y N@me")
-        def dog():
-            pass
-        """
-        monkeypatch.chdir(tmp_path)
-        file_name = "f.py"
-        file_path = Path(tmp_path) / Path(file_name)
-        file_path.write_text(dedent(flow_code))
-
-        dep_name = "TEST"
-        entrypoint = f"{file_path.absolute()}:dog"
-        cmd = ["deployment", "build", "-n", dep_name]
-        cmd += [entrypoint]
-
-        invoke_and_assert(
-            cmd,
-            expected_code=0,
-        )
-
-    def test_entrypoint_works_with_flow_func_with_underscores(
-        self, tmp_path, monkeypatch
-    ):
-        flow_code = """
-        from prefect import flow
-
-        @flow
-        def dog_flow_func():
-            pass
-        """
-        monkeypatch.chdir(tmp_path)
-        file_name = "f.py"
-        file_path = Path(tmp_path) / Path(file_name)
-        file_path.write_text(dedent(flow_code))
-
-        dep_name = "TEST"
-        entrypoint = f"{file_path.absolute()}:dog_flow_func"
-        cmd = ["deployment", "build", "-n", dep_name]
-        cmd += [entrypoint]
-
-        invoke_and_assert(
-            cmd,
-            expected_code=0,
-        )
-
-
-class TestWorkQueue:
-    def test_work_queue_name_is_populated_as_default(self, patch_import, tmp_path):
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-            ],
-            expected_code=0,
-            temp_dir=tmp_path,
-        )
-
-        deployment = Deployment.load_from_yaml(tmp_path / "test.yaml")
-        assert deployment.work_queue_name == "default"
-
-    def test_success_message_with_work_queue_name(self, patch_import, tmp_path):
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-            ],
-            expected_code=0,
-            temp_dir=tmp_path,
-        )
-        invoke_and_assert(
-            [
-                "deployment",
-                "apply",
-                str(tmp_path / "test.yaml"),
-            ],
-            expected_output_contains=[
-                (
-                    "To execute flow runs from this deployment, start an agent "
-                    "that pulls work from the 'default' work queue:"
-                ),
-                "$ prefect agent start -q 'default'",
-            ],
-        )
-
-
-class TestWorkPool:
-    async def test_creates_work_queue_in_work_pool(
-        self,
-        patch_import,
-        tmp_path,
-        work_pool,
-        session,
-    ):
-        await run_sync_in_worker_thread(
-            invoke_and_assert,
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-p",
-                work_pool.name,
-                "-q",
-                "new-queue",
-                "-o",
-                str(tmp_path / "test.yaml"),
-                "--apply",
-            ],
-            expected_code=0,
-            temp_dir=tmp_path,
-        )
-
-        deployment = await Deployment.load_from_yaml(tmp_path / "test.yaml")
-        assert deployment.work_pool_name == work_pool.name
-        assert deployment.work_queue_name == "new-queue"
-
-        work_queue = await models.workers.read_work_queue_by_name(
-            session=session, work_pool_name=work_pool.name, work_queue_name="new-queue"
-        )
-        assert work_queue is not None
-
-
-class TestAutoApply:
-    def test_auto_apply_flag(self, patch_import, tmp_path):
-        d = Deployment(
-            name="TEST",
-            flow_name="fn",
-        )
-        deployment_id = d.apply()
-
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-                "--apply",
-            ],
-            expected_code=0,
-            expected_output_contains=[
-                f"Deployment '{d.flow_name}/{d.name}' successfully created with id"
-                f" '{deployment_id}'."
-            ],
-            temp_dir=tmp_path,
-        )
-
-    def test_auto_apply_work_pool_does_not_exist(
-        self,
-        patch_import,
-        tmp_path,
-    ):
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-                "-p",
-                "gibberish",
-                "--apply",
-            ],
-            expected_code=1,
-            expected_output_contains=(
-                [
-                    (
-                        "This deployment specifies a work pool name of 'gibberish', but"
-                        " no such work pool exists."
-                    ),
-                    "To create a work pool via the CLI:",
-                    "$ prefect work-pool create 'gibberish'",
-                ]
-            ),
-            temp_dir=tmp_path,
-        )
-
-    def test_message_with_prefect_agent_work_pool(
-        self, patch_import, tmp_path, prefect_agent_work_pool
-    ):
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-                "-p",
-                prefect_agent_work_pool.name,
-                "--apply",
-            ],
-            expected_output_contains=[
-                (
-                    "To execute flow runs from this deployment, start an agent that"
-                    f" pulls work from the {prefect_agent_work_pool.name!r} work pool:"
-                ),
-                f"$ prefect agent start -p {prefect_agent_work_pool.name!r}",
-            ],
-            temp_dir=tmp_path,
-        )
-
-    def test_message_with_process_work_pool(
-        self, patch_import, tmp_path, process_work_pool, enable_workers
-    ):
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-                "-p",
-                process_work_pool.name,
-                "--apply",
-            ],
-            expected_output_contains=[
-                (
-                    "To execute flow runs from this deployment, start a worker "
-                    f"that pulls work from the {process_work_pool.name!r} work pool:"
-                ),
-                f"$ prefect worker start -p {process_work_pool.name!r}",
-            ],
-            temp_dir=tmp_path,
-        )
-
-    def test_message_with_process_work_pool_without_workers_enabled(
-        self, patch_import, tmp_path, process_work_pool, disable_workers
-    ):
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-                "-p",
-                process_work_pool.name,
-                "--apply",
-            ],
-            expected_output_contains=[
-                (
-                    "\nTo execute flow runs from this deployment, please enable "
-                    "the workers CLI and start a worker that pulls work from the "
-                    f"{process_work_pool.name!r} work pool:"
-                ),
-                (
-                    "$ prefect config set PREFECT_EXPERIMENTAL_ENABLE_WORKERS=True\n"
-                    f"$ prefect worker start -p {process_work_pool.name!r}"
-                ),
-            ],
-            temp_dir=tmp_path,
-        )
-
-
-class TestWorkQueueConcurrency:
-    async def test_setting_work_queue_concurrency_limits_with_build(
-        self, built_deployment_with_queue_and_limit_overrides, prefect_client
-    ):
-        queue = await prefect_client.read_work_queue_by_name(
-            "the-queue-to-end-all-queues"
-        )
-        assert queue.concurrency_limit == 424242
-
-    async def test_setting_work_queue_concurrency_limits_with_apply(
-        self, applied_deployment_with_queue_and_limit_overrides, prefect_client
-    ):
-        queue = await prefect_client.read_work_queue_by_name("the-mother-of-all-queues")
-        assert queue.concurrency_limit == 4242
-
-
-class TestVersionFlag:
-    def test_version_flag_takes_precedence(self, patch_import, tmp_path):
-        d = Deployment(
-            name="TEST",
-            flow_name="fn",
-            version="server",
-        )
-        assert d.apply()
-
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-                "-v",
-                "CLI-version",
-            ],
-            expected_code=0,
-            temp_dir=tmp_path,
-        )
-
-        deployment = Deployment.load_from_yaml(tmp_path / "test.yaml")
-        assert deployment.version == "CLI-version"
-
-
-class TestLoadingSettings:
-    def test_server_side_settings_are_used_if_present(self, patch_import, tmp_path):
-        """
-        This only applies to tags, work queue name, description, schedules and default parameter values
-        """
-        d = Deployment(
-            name="TEST",
-            flow_name="fn",
-            description="server-side value",
-            version="server",
-            parameters={"key": "server"},
-            tags=["server-tag"],
-            work_queue_name="dev",
-        )
-        assert d.apply()
-
-        invoke_and_assert(
-            [
-                "deployment",
-                "build",
-                "fake-path.py:fn",
-                "-n",
-                "TEST",
-                "-o",
-                str(tmp_path / "test.yaml"),
-            ],
-            expected_code=0,
-            temp_dir=tmp_path,
-        )
-
-        deployment = Deployment.load_from_yaml(tmp_path / "test.yaml")
-        assert deployment.description == "server-side value"
-        assert deployment.tags == ["server-tag"]
-        assert deployment.parameters == dict(key="server")
-        assert deployment.work_queue_name == "dev"
-
-
-class TestSkipUpload:
-    @pytest.mark.filterwarnings("ignore:does not have upload capabilities")
-    @pytest.mark.parametrize("skip_upload", ["--skip-upload", None])
-    def test_skip_upload_called_correctly(
-        self, patch_import, tmp_path, skip_upload, mock_build_from_flow
-    ):
-        name = "TEST"
-        output_path = str(tmp_path / "test.yaml")
-        entrypoint = "fake-path.py:fn"
-        cmd = [
-            "deployment",
-            "build",
-            entrypoint,
-            "-n",
-            name,
-            "-o",
-            output_path,
-        ]
-
-        if skip_upload:
-            cmd.append(skip_upload)
-
-        invoke_and_assert(
-            cmd,
-            expected_code=0,
-        )
-
-        build_kwargs = mock_build_from_flow.call_args.kwargs
-
-        if skip_upload:
-            assert build_kwargs["skip_upload"] is True
-        else:
-            assert build_kwargs["skip_upload"] is False
-
-
-class TestInfraAndInfraBlock:
-    def test_providing_infra_block_and_infra_type_exits_with_error(
-        self, patch_import, tmp_path
-    ):
-        name = "TEST"
-        output_path = str(tmp_path / "test.yaml")
-        entrypoint = "fake-path.py:fn"
-        cmd = [
-            "deployment",
-            "build",
-            entrypoint,
-            "-n",
-            name,
-            "-o",
-            output_path,
-        ]
-        cmd += ["-i", "process", "-ib", "my-block"]
-
-        invoke_and_assert(
-            cmd,
-            expected_code=1,
-            expected_output_contains=(
-                "Only one of `infra` or `infra_block` can be provided, please choose"
-                " one."
-            ),
-        )
-
-    @pytest.mark.filterwarnings("ignore:does not have upload capabilities")
-    def test_infra_block_called_correctly(
-        self, patch_import, tmp_path, infra_block, mock_build_from_flow
-    ):
-        name = "TEST"
-        output_path = str(tmp_path / "test.yaml")
-        entrypoint = "fake-path.py:fn"
-        cmd = [
-            "deployment",
-            "build",
-            entrypoint,
-            "-n",
-            name,
-            "-o",
-            output_path,
-        ]
-        cmd += ["-ib", "process/test-infra-block"]
-
-        invoke_and_assert(
-            cmd,
-            expected_code=0,
-        )
-
-        build_kwargs = mock_build_from_flow.call_args.kwargs
-        assert build_kwargs["infrastructure"] == infra_block
-
-    @pytest.mark.filterwarnings("ignore:does not have upload capabilities")
-    def test_infra_type_specifies_infra_block_on_deployment(
-        self, patch_import, tmp_path, mock_build_from_flow
-    ):
-        name = "TEST"
-        output_path = str(tmp_path / "test.yaml")
-        entrypoint = "fake-path.py:fn"
-        cmd = [
-            "deployment",
-            "build",
-            entrypoint,
-            "-n",
-            name,
-            "-o",
-            output_path,
-        ]
-        cmd += ["-i", "docker-container"]
-
-        invoke_and_assert(
-            cmd,
-            expected_code=0,
-        )
-
-        build_kwargs = mock_build_from_flow.call_args.kwargs
-        infra = build_kwargs["infrastructure"]
-        assert infra.type == "docker-container"
-
-
-class TestInfraOverrides:
-    @pytest.mark.filterwarnings("ignore:does not have upload capabilities")
-    def test_overrides_called_correctly(
-        self, patch_import, tmp_path, mock_build_from_flow
-    ):
-        name = "TEST"
-        output_path = str(tmp_path / "test.yaml")
-        entrypoint = "fake-path.py:fn"
-        overrides = ["my.dog=1", "your.cat=test"]
-        cmd = [
-            "deployment",
-            "build",
-            entrypoint,
-            "-n",
-            name,
-            "-o",
-            output_path,
-        ]
-        for override in overrides:
-            cmd += ["--override", override]
-        invoke_and_assert(
-            cmd,
-            expected_code=0,
-        )
-
-        build_kwargs = mock_build_from_flow.call_args.kwargs
-        assert build_kwargs["job_variables"] == {"my.dog": "1", "your.cat": "test"}
-
-    @pytest.mark.filterwarnings("ignore:does not have upload capabilities")
-    def test_overrides_default_is_empty(
-        self, patch_import, tmp_path, mock_build_from_flow
-    ):
-        name = "TEST"
-        output_path = str(tmp_path / "test.yaml")
-        entrypoint = "fake-path.py:fn"
-        cmd = [
-            "deployment",
-            "build",
-            entrypoint,
-            "-n",
-            name,
-            "-o",
-            output_path,
-        ]
-        invoke_and_assert(
-            cmd,
-            expected_code=0,
-        )
-
-        build_kwargs = mock_build_from_flow.call_args.kwargs
-        assert build_kwargs["job_variables"] == {}
-
-
-class TestStorageBlock:
-    @pytest.mark.filterwarnings("ignore:does not have upload capabilities")
-    def test_storage_block_called_correctly(
-        self, patch_import, tmp_path, storage_block, mock_build_from_flow
-    ):
-        name = "TEST"
-        output_path = str(tmp_path / "test.yaml")
-        entrypoint = "fake-path.py:fn"
-        cmd = [
-            "deployment",
-            "build",
-            entrypoint,
-            "-n",
-            name,
-            "-o",
-            output_path,
-        ]
-        cmd += ["-sb", "local-file-system/test-storage-block"]
-
-        invoke_and_assert(
-            cmd,
-            expected_code=0,
-        )
-
-        build_kwargs = mock_build_from_flow.call_args.kwargs
-        assert build_kwargs["storage"] == storage_block
-
-
-class TestOutputFlag:
-    def test_output_file_with_wrong_suffix_exits_with_error(
-        self, patch_import, tmp_path
-    ):
-        name = "TEST"
-        file_name = "test.not_yaml"
-        output_path = str(tmp_path / file_name)
-        entrypoint = "fake-path.py:fn"
-        cmd = [
-            "deployment",
-            "build",
-            entrypoint,
-            "-n",
-            name,
-        ]
-        cmd += ["-o", output_path]
-
-        invoke_and_assert(
-            cmd,
-            expected_code=1,
-            expected_output_contains="Output file must be a '.yaml' file.",
-        )
-
-    @pytest.mark.filterwarnings("ignore:does not have upload capabilities")
-    def test_yaml_appended_to_out_file_without_suffix(
-        self, monkeypatch, patch_import, tmp_path, mock_build_from_flow
-    ):
-        name = "TEST"
-        file_name = "test_no_suffix"
-        output_path = str(tmp_path / file_name)
-        entrypoint = "fake-path.py:fn"
-        cmd = [
-            "deployment",
-            "build",
-            entrypoint,
-            "-n",
-            name,
-        ]
-        cmd += ["-o", output_path]
-
-        invoke_and_assert(
-            cmd,
-            expected_code=0,
-        )
-
-        build_kwargs = mock_build_from_flow.call_args.kwargs
-        assert build_kwargs["output"] == Path(output_path + ".yaml")
-
-
-class TestOtherStuff:
-    @pytest.mark.filterwarnings("ignore:does not have upload capabilities")
-    def test_correct_flow_passed_to_deployment_object(
-        self, patch_import, tmp_path, mock_build_from_flow
-    ):
-        name = "TEST"
-        file_name = "test_no_suffix"
-        output_path = str(tmp_path / file_name)
-        entrypoint = "fake-path.py:fn"
-        cmd = ["deployment", "build", entrypoint, "-n", name, "-o", output_path]
-
-        invoke_and_assert(
-            cmd,
-            expected_code=0,
-        )
-
-        build_kwargs = mock_build_from_flow.call_args.kwargs
-        assert build_kwargs["flow"] == patch_import

Remove `prefect deployment build` CLI from the `main` branch
Remove the `prefect.cli.deployment.build` function and any references to it. Any private code that was used solely for that function should also be deleted. This CLI command will be included in 2.x releases, but will not be included in the 3.0 release.


diff --git a/src/prefect/client/orchestration.py b/src/prefect/client/orchestration.py
index 2e4334ba4bfe..53aa8bc5bf9a 100644
--- a/src/prefect/client/orchestration.py
+++ b/src/prefect/client/orchestration.py
@@ -1958,7 +1958,7 @@ async def update_deployment_schedule(
         kwargs = {}
         if active is not None:
             kwargs["active"] = active
-        elif schedule is not None:
+        if schedule is not None:
             kwargs["schedule"] = schedule

         deployment_schedule_update = DeploymentScheduleUpdate(**kwargs)

diff --git a/tests/client/test_prefect_client.py b/tests/client/test_prefect_client.py
index 4d13d6de0e12..203ec7a19216 100644
--- a/tests/client/test_prefect_client.py
+++ b/tests/client/test_prefect_client.py
@@ -2416,7 +2416,12 @@ async def test_read_deployment_schedules_success(self, prefect_client, deploymen
         )
         assert result[0].active is True

-    async def test_update_deployment_schedule_success(self, deployment, prefect_client):
+    async def test_update_deployment_schedule_only_active(
+        self, deployment, prefect_client
+    ):
+        result = await prefect_client.read_deployment_schedules(deployment.id)
+        assert result[0].active is True
+
         await prefect_client.update_deployment_schedule(
             deployment.id, deployment.schedules[0].id, active=False
         )
@@ -2425,6 +2430,48 @@ async def test_update_deployment_schedule_success(self, deployment, prefect_clie
         assert len(result) == 1
         assert result[0].active is False

+    async def test_update_deployment_schedule_only_schedule(
+        self, deployment, prefect_client
+    ):
+        result = await prefect_client.read_deployment_schedules(deployment.id)
+        assert result[0].schedule == IntervalSchedule(
+            interval=timedelta(days=1), anchor_date=pendulum.datetime(2020, 1, 1)
+        )
+
+        await prefect_client.update_deployment_schedule(
+            deployment.id,
+            deployment.schedules[0].id,
+            schedule=IntervalSchedule(interval=timedelta(minutes=15)),
+        )
+
+        result = await prefect_client.read_deployment_schedules(deployment.id)
+        assert len(result) == 1
+        assert result[0].schedule.interval == timedelta(minutes=15)
+
+    async def test_update_deployment_schedule_all_fields(
+        self, deployment, prefect_client
+    ):
+        """
+        A regression test for #13243
+        """
+        result = await prefect_client.read_deployment_schedules(deployment.id)
+        assert result[0].schedule == IntervalSchedule(
+            interval=timedelta(days=1), anchor_date=pendulum.datetime(2020, 1, 1)
+        )
+        assert result[0].active is True
+
+        await prefect_client.update_deployment_schedule(
+            deployment.id,
+            deployment.schedules[0].id,
+            schedule=IntervalSchedule(interval=timedelta(minutes=15)),
+            active=False,
+        )
+
+        result = await prefect_client.read_deployment_schedules(deployment.id)
+        assert len(result) == 1
+        assert result[0].schedule.interval == timedelta(minutes=15)
+        assert result[0].active is False
+
     async def test_delete_deployment_schedule_success(self, deployment, prefect_client):
         await prefect_client.delete_deployment_schedule(
             deployment.id, deployment.schedules[0].id

`client/orchestration.py/update_deployment_schedule` should be update with `active` and `schedule` at once
### First check

- [X] I added a descriptive title to this issue.
- [X] I used the GitHub search to find a similar request and didn't find it.
- [X] I searched the Prefect documentation for this feature.

### Prefect Version

2.x

### Describe the current behavior

I am trying to change the schedule of a deployment from an external service (a client service I am creating). I am trying to update the cron using this function, but the behavior is different from what I expected, so I would like to confirm.
In this function, lines 1953 to 1956 are written as follows:
https://github.com/PrefectHQ/prefect/blob/1d1499a900fb4a68029a0c206b43140b0703a1b6/src/prefect/client/orchestration.py#L1953-L1956

### Describe the proposed behavior

It's should be following:

```python
if active is not None:
    kwargs["active"] = active

if schedule is not None:
    kwargs["schedule"] = schedule
```

### Example Use

```python
import asyncio
from prefect.client.orchestration import PrefectClient
from prefect.client.schemas.schedules import construct_schedule

async def updateDeploymentSchedule():
    client = PrefectClient(api="http://127.0.0.1:4200/api")
    target_deployment = await client.read_deployment_by_name("foo/bar")
    schedule_id = target_deployment.schedules[0].id
    cron =construct_schedule(cron="0 5 * * *",timezone="Asia/Tokyo")
    _ = await client.update_deployment_schedule(deployment_id=target_deployment.id, schedule_id=schedule_id, schedule=cron, active=True)

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(updateDeploymentSchedule())
```

### Additional context

I mentioned about this issue in [slack channnel](https://prefect-community.slack.com/archives/CL09KU1K7/p1714642952657639)


diff --git a/src/prefect/cli/deploy.py b/src/prefect/cli/deploy.py
index 9e33c86cc053..28e4dc4cecb9 100644
--- a/src/prefect/cli/deploy.py
+++ b/src/prefect/cli/deploy.py
@@ -147,6 +147,12 @@ async def deploy(
         None,
         "-v",
         "--variable",
+        help=("DEPRECATED: Please use --jv/--job-variable for similar functionality "),
+    ),
+    job_variables: List[str] = typer.Option(
+        None,
+        "-jv",
+        "--job-variable",
         help=(
             "One or more job variable overrides for the work pool provided in the"
             " format of key=value string or a JSON object"
@@ -254,6 +260,25 @@ async def deploy(
             style="yellow",
         )

+    if variables is not None:
+        app.console.print(
+            generate_deprecation_message(
+                name="The `--variable` flag",
+                start_date="Mar 2024",
+                help=(
+                    "Please use the `--job-variable foo=bar` argument instead: `prefect"
+                    " deploy --job-variable`."
+                ),
+            ),
+            style="yellow",
+        )
+
+    if variables is None:
+        variables = list()
+    if job_variables is None:
+        job_variables = list()
+    job_variables.extend(variables)
+
     options = {
         "entrypoint": entrypoint,
         "flow_name": flow_name,
@@ -262,7 +287,7 @@ async def deploy(
         "tags": tags,
         "work_pool_name": work_pool_name,
         "work_queue_name": work_queue_name,
-        "variables": variables,
+        "variables": job_variables,
         "cron": cron,
         "interval": interval,
         "anchor_date": interval_anchor,

diff --git a/tests/cli/test_deploy.py b/tests/cli/test_deploy.py
index 1b5e65724c08..363cb6a90b6e 100644
--- a/tests/cli/test_deploy.py
+++ b/tests/cli/test_deploy.py
@@ -277,7 +277,7 @@ async def test_project_deploy(
             invoke_and_assert,
             command=(
                 "deploy ./flows/hello.py:my_flow -n test-name -p test-pool --version"
-                " 1.0.0 -v env=prod -t foo-bar"
+                " 1.0.0 -v env=prod -jv kind=single -t foo-bar"
             ),
             expected_code=0,
             # check for deprecation message
@@ -301,7 +301,7 @@ async def test_project_deploy(
         assert deployment.work_pool_name == "test-pool"
         assert deployment.version == "1.0.0"
         assert deployment.tags == ["foo-bar"]
-        assert deployment.infra_overrides == {"env": "prod"}
+        assert deployment.infra_overrides == {"env": "prod", "kind": "single"}

     async def test_project_deploy_with_no_deployment_file(
         self, project_dir, prefect_client

CLI: Update `prefect deploy` options to support a `--jv/job-variable` option
### First check

- [X] I am a contributor to the Prefect codebase

### Description

In https://github.com/PrefectHQ/prefect/pull/12195/ we introduced a new option to `prefect deployment run` called `--jv/--job-variable` for providing job variables. This is out of sync with the `prefect`deploy` command's `--v/--variable` flag but the new flags are clearer to use.

### Impact

If we migrate the command options on `prefect deploy` to use `--jv/--job-variable` we will remain consistent and improve the CLI interface's clarity.

### Additional context

N/A


diff --git a/src/prefect/utilities/dockerutils.py b/src/prefect/utilities/dockerutils.py
index 3c05cb7fa2f9..adbe302066de 100644
--- a/src/prefect/utilities/dockerutils.py
+++ b/src/prefect/utilities/dockerutils.py
@@ -104,13 +104,18 @@ def silence_docker_warnings() -> Generator[None, None, None]:
 @contextmanager
 def docker_client() -> Generator["DockerClient", None, None]:
     """Get the environmentally-configured Docker client"""
-    with silence_docker_warnings():
-        client = docker.DockerClient.from_env()
-
+    client = None
     try:
-        yield client
+        with silence_docker_warnings():
+            client = docker.DockerClient.from_env()
+
+            yield client
+    except docker.errors.DockerException as exc:
+        raise RuntimeError(
+            "This error is often thrown because Docker is not running. Please ensure Docker is running."
+        ) from exc
     finally:
-        client.close()
+        client is not None and client.close()

 class BuildError(Exception):

diff --git a/tests/utilities/test_importtools.py b/tests/utilities/test_importtools.py
index bb9f10f77957..7284fd1fafce 100644
--- a/tests/utilities/test_importtools.py
+++ b/tests/utilities/test_importtools.py
@@ -3,6 +3,7 @@
 import sys
 from pathlib import Path
 from types import ModuleType
+from unittest.mock import MagicMock
 from uuid import uuid4

 import pytest
@@ -71,6 +72,19 @@ def test_lazy_import():
     assert callable(docker.from_env)

+@pytest.mark.service("docker")
+def test_cant_find_docker_error(monkeypatch):
+    docker = lazy_import("docker")
+    docker.errors = lazy_import("docker.errors")
+    monkeypatch.setattr(
+        "docker.DockerClient.from_env",
+        MagicMock(side_effect=docker.errors.DockerException),
+    )
+    with pytest.raises(RuntimeError, match="Docker is not running"):
+        with docker_client() as _:
+            return None
+
+
 @pytest.mark.service("docker")
 def test_lazy_import_does_not_break_type_comparisons():
     docker = lazy_import("docker")

Improve error message when Docker is not running and Prefect tries to build a Docker image
### First check

- [X] I added a descriptive title to this issue.
- [X] I used the GitHub search to find a similar request and didn't find it.
- [X] I searched the Prefect documentation for this feature.

### Prefect Version

2.x

### Describe the current behavior

Trying to rund `flow.deploy` to build an image results in the following error if Docker is not running:

```bash
Traceback (most recent call last):
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/urllib3/connectionpool.py", line 793, in urlopen
    response = self._make_request(
               ^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/urllib3/connectionpool.py", line 496, in _make_request
    conn.request(
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/urllib3/connection.py", line 400, in request
    self.endheaders()
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/http/client.py", line 1289, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/http/client.py", line 1048, in _send_output
    self.send(msg)
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/http/client.py", line 986, in send
    self.connect()
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/docker/transport/unixconn.py", line 27, in connect
    sock.connect(self.unix_socket)
FileNotFoundError: [Errno 2] No such file or directory

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/requests/adapters.py", line 486, in send
    resp = conn.urlopen(
           ^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/urllib3/connectionpool.py", line 847, in urlopen
    retries = retries.increment(
              ^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/urllib3/util/retry.py", line 470, in increment
    raise reraise(type(error), error, _stacktrace)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/urllib3/util/util.py", line 38, in reraise
    raise value.with_traceback(tb)
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/urllib3/connectionpool.py", line 793, in urlopen
    response = self._make_request(
               ^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/urllib3/connectionpool.py", line 496, in _make_request
    conn.request(
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/urllib3/connection.py", line 400, in request
    self.endheaders()
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/http/client.py", line 1289, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/http/client.py", line 1048, in _send_output
    self.send(msg)
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/http/client.py", line 986, in send
    self.connect()
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/docker/transport/unixconn.py", line 27, in connect
    sock.connect(self.unix_socket)
urllib3.exceptions.ProtocolError: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/docker/api/client.py", line 214, in _retrieve_server_version
    return self.version(api_version=False)["ApiVersion"]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/docker/api/daemon.py", line 181, in version
    return self._result(self._get(url), json=True)
                        ^^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/docker/utils/decorators.py", line 46, in inner
    return f(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/docker/api/client.py", line 237, in _get
    return self.get(url, **self._set_request_timeout(kwargs))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/requests/sessions.py", line 602, in get
    return self.request("GET", url, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/requests/sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/requests/sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/requests/adapters.py", line 501, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/jeffhale/Desktop/prefect/demos/deploy_demo/get_weather.py", line 17, in <module>
    fetch_weather.deploy(
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/prefect/utilities/asyncutils.py", line 255, in coroutine_wrapper
    return call()
           ^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/prefect/_internal/concurrency/calls.py", line 398, in __call__
    return self.result()
           ^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/prefect/_internal/concurrency/calls.py", line 284, in result
    return self.future.result(timeout=timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/prefect/_internal/concurrency/calls.py", line 168, in result
    return self.__get_result()
           ^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/concurrent/futures/_base.py", line 401, in __get_result
    raise self._exception
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/prefect/_internal/concurrency/calls.py", line 355, in _run_async
    result = await coro
             ^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/prefect/flows.py", line 1001, in deploy
    deployment_ids = await deploy(
                     ^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/prefect/deployments/runner.py", line 831, in deploy
    image.build()
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/prefect/deployments/runner.py", line 698, in build
    build_image(**build_kwargs)
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/prefect/utilities/dockerutils.py", line 159, in build_image
    with docker_client() as client:
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/contextlib.py", line 137, in __enter__
    return next(self.gen)
           ^^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/prefect/utilities/dockerutils.py", line 108, in docker_client
    client = docker.DockerClient.from_env()
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/docker/client.py", line 96, in from_env
    return cls(
           ^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/docker/client.py", line 45, in __init__
    self.api = APIClient(*args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/docker/api/client.py", line 197, in __init__
    self._version = self._retrieve_server_version()
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Caskroom/miniforge/base/lib/python3.11/site-packages/docker/api/client.py", line 221, in _retrieve_server_version
    raise DockerException(
docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))
```

### Describe the proposed behavior

Catch the exception and return a more human-readable error that suggests the user check whether Docker is running.

### Example Use

_No response_

### Additional context

We observed several users encounter this error and get confused about its meaning at a PACC. I have also stumbled over it in the past.

Might want to do something similar for the exception discussed in [issue #9337](https://github.com/PrefectHQ/prefect/issues/9337).

@serinamarie can you assign it to me? would love to take it as a first issue.
@discdiver can you assign this issue to me?

Assigned. Thank you @eladm26! You can check out the contributor docs[ here](https://docs.prefect.io/latest/contributing/overview/). Please let us know if you encounter any issues or anything in the docs could be improved.
This is how the new error will look, I added the error:  `Docker is not running. please run docker and try again`
```
Running deployment build steps...
 > Running build_docker_image step...
Traceback (most recent call last):
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/urllib3/connectionpool.py", line 791, in urlopen
    response = self._make_request(
               ^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/urllib3/connectionpool.py", line 497, in _make_request
    conn.request(
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/urllib3/connection.py", line 395, in request
    self.endheaders()
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/lib/python3.11/http/client.py", line 1277, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/lib/python3.11/http/client.py", line 1037, in _send_output
    self.send(msg)
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/lib/python3.11/http/client.py", line 975, in send
    self.connect()
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/docker/transport/unixconn.py", line 27, in connect
    sock.connect(self.unix_socket)
ConnectionRefusedError: [Errno 61] Connection refused

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/requests/adapters.py", line 486, in send
    resp = conn.urlopen(
           ^^^^^^^^^^^^^
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/urllib3/connectionpool.py", line 845, in urlopen
    retries = retries.increment(
              ^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/urllib3/util/retry.py", line 470, in increment
    raise reraise(type(error), error, _stacktrace)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/urllib3/util/util.py", line 38, in reraise
    raise value.with_traceback(tb)
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/urllib3/connectionpool.py", line 791, in urlopen
    response = self._make_request(
               ^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/urllib3/connectionpool.py", line 497, in _make_request
    conn.request(
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/urllib3/connection.py", line 395, in request
    self.endheaders()
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/lib/python3.11/http/client.py", line 1277, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/lib/python3.11/http/client.py", line 1037, in _send_output
    self.send(msg)
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/lib/python3.11/http/client.py", line 975, in send
    self.connect()
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/docker/transport/unixconn.py", line 27, in connect
    sock.connect(self.unix_socket)
urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionRefusedError(61, 'Connection refused'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/docker/api/client.py", line 214, in _retrieve_server_version
    return self.version(api_version=False)["ApiVersion"]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/docker/api/daemon.py", line 181, in version
    return self._result(self._get(url), json=True)
                        ^^^^^^^^^^^^^^
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/docker/utils/decorators.py", line 46, in inner
    return f(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/docker/api/client.py", line 237, in _get
    return self.get(url, **self._set_request_timeout(kwargs))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/requests/sessions.py", line 602, in get
    return self.request("GET", url, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/requests/sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/requests/sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/requests/adapters.py", line 501, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionRefusedError(61, 'Connection refused'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/eladmoshe/Projects/prefect/src/prefect/utilities/dockerutils.py", line 110, in docker_client
    client = docker.DockerClient.from_env()
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/docker/client.py", line 96, in from_env
    return cls(
           ^^^^
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/docker/client.py", line 45, in __init__
    self.api = APIClient(*args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/docker/api/client.py", line 197, in __init__
    self._version = self._retrieve_server_version()
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/docker/api/client.py", line 221, in _retrieve_server_version
    raise DockerException(
docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', ConnectionRefusedError(61, 'Connection refused'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/eladmoshe/Projects/prefect/src/prefect/deployments/steps/core.py", line 154, in run_steps
    step_output = await run_step(step, upstream_outputs)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/Projects/prefect/src/prefect/deployments/steps/core.py", line 125, in run_step
    result = await from_async.call_soon_in_new_thread(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/Projects/prefect/src/prefect/_internal/concurrency/calls.py", line 294, in aresult
    return await asyncio.wrap_future(self.future)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/greenback/_impl.py", line 211, in _greenback_shim
    next_send = outcome.Value((yield next_yield))
                               ^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/Projects/prefect/src/prefect/_internal/concurrency/calls.py", line 319, in _run_sync
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/Projects/prefect/src/prefect/_internal/compatibility/deprecated.py", line 155, in wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/envs/prefect/lib/python3.11/site-packages/prefect_docker/deployments/steps.py", line 200, in build_docker_image
    with docker_client() as client:
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/lib/python3.11/contextlib.py", line 137, in __enter__
    return next(self.gen)
           ^^^^^^^^^^^^^^
  File "/Users/eladmoshe/Projects/prefect/src/prefect/utilities/dockerutils.py", line 114, in docker_client
    raise RuntimeError("Docker is not running. please run docker and try again")
**RuntimeError: Docker is not running. please run docker and try again**

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/eladmoshe/Projects/prefect/src/prefect/cli/_utilities.py", line 41, in wrapper
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/Projects/prefect/src/prefect/utilities/asyncutils.py", line 259, in coroutine_wrapper
    return call()
           ^^^^^^
  File "/Users/eladmoshe/Projects/prefect/src/prefect/_internal/concurrency/calls.py", line 407, in __call__
    return self.result()
           ^^^^^^^^^^^^^
  File "/Users/eladmoshe/Projects/prefect/src/prefect/_internal/concurrency/calls.py", line 285, in result
    return self.future.result(timeout=timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/Projects/prefect/src/prefect/_internal/concurrency/calls.py", line 169, in result
    return self.__get_result()
           ^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/.pyenv/versions/3.11.0/lib/python3.11/concurrent/futures/_base.py", line 401, in __get_result
    raise self._exception
  File "/Users/eladmoshe/Projects/prefect/src/prefect/_internal/concurrency/calls.py", line 364, in _run_async
    result = await coro
             ^^^^^^^^^^
  File "/Users/eladmoshe/Projects/prefect/src/prefect/cli/deploy.py", line 293, in deploy
    await _run_multi_deploy(
  File "/Users/eladmoshe/Projects/prefect/src/prefect/cli/deploy.py", line 800, in _run_multi_deploy
    await _run_single_deploy(
  File "/Users/eladmoshe/Projects/prefect/src/prefect/client/utilities.py", line 51, in with_injected_client
    return await fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eladmoshe/Projects/prefect/src/prefect/cli/deploy.py", line 619, in _run_single_deploy
    await run_steps(build_steps, step_outputs, print_function=app.console.print)
  File "/Users/eladmoshe/Projects/prefect/src/prefect/deployments/steps/core.py", line 182, in run_steps
    raise StepExecutionError(f"Encountered error while running {fqn}") from exc
prefect.deployments.steps.core.StepExecutionError: Encountered error while running prefect_docker.deployments.steps.build_docker_image

```