Skip to content

Run template rework #3856

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 52 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
4860f58
Add some run template functionality to deployment schema
schustmi Jul 22, 2025
28b5c6b
Refactoring to allow running deployments
schustmi Jul 23, 2025
a57f9dd
Enable deployment updates
schustmi Jul 23, 2025
8583fbc
Add more params to deployment request
schustmi Jul 23, 2025
9a939b0
Fix pipeline run action
schustmi Jul 23, 2025
8d63b04
Additional deployment filters
schustmi Jul 23, 2025
70930db
Remove unused option
schustmi Jul 23, 2025
a59953c
Copy tag assignments instead of removing them from the run templates
schustmi Jul 23, 2025
fea8c2a
Docstrings
schustmi Jul 23, 2025
ff4b325
Improve DB migration
schustmi Jul 23, 2025
093dc63
More fixes
schustmi Jul 23, 2025
9c97b91
Add missing properties
schustmi Jul 23, 2025
af8451d
Fix pipeline deletion
schustmi Jul 23, 2025
03fcbbb
Implement deployment tagging and rename more stuff
schustmi Jul 23, 2025
5543821
More tagging implementations
schustmi Jul 23, 2025
80d7647
Add methods to trigger deployments
schustmi Jul 23, 2025
f1eb21b
Deprecation warnings and helper method to trigger deployments
schustmi Jul 24, 2025
e670db1
Add fetching deployments by name
schustmi Jul 24, 2025
1e419f4
Move method
schustmi Jul 24, 2025
8f8f63d
Store trigger execution
schustmi Jul 24, 2025
a21d5e9
Fix some inconsistencies
schustmi Jul 24, 2025
e79c776
Fix more inconsistencies
schustmi Jul 24, 2025
69d081d
Some more fixes
schustmi Jul 24, 2025
55e3647
Trigger execution request validation
schustmi Jul 24, 2025
36acacb
Add triggered runs to DAG
schustmi Jul 24, 2025
d86b75c
Make trigger execution project-scoped to not crash RBAC
schustmi Jul 24, 2025
45b384f
Delete unused DB migration
schustmi Jul 24, 2025
94f361e
Remove unnecessary request arg
schustmi Jul 24, 2025
1a8c6b3
Switch to deployment version
schustmi Jul 24, 2025
5fc4681
CLI command to trigger deployments
schustmi Jul 24, 2025
c417fc4
Re-add method to trigger templates
schustmi Jul 24, 2025
f2ba010
Project scoped trigger executions
schustmi Jul 25, 2025
4583958
Filter by step run trigger
schustmi Jul 25, 2025
5660e40
Latest triggered run for deployment
schustmi Jul 25, 2025
bff430f
Fix circular import
schustmi Jul 25, 2025
8a3e48a
Merge branch 'develop' into feature/run-template-improvements
schustmi Jul 28, 2025
e1bbef3
Fix alembic order
schustmi Jul 28, 2025
de01e9c
Merge branch 'develop' into feature/run-template-improvements
schustmi Jul 28, 2025
501fe10
Increase runner timeout
schustmi Aug 5, 2025
4a2c1f8
Rename directory
schustmi Aug 5, 2025
9f4dc08
Fix imports
schustmi Aug 5, 2025
0b40ed8
Prevent creating deployment versions for unsupported deployments/servers
schustmi Aug 5, 2025
1e2a965
Respect original run name template
schustmi Aug 6, 2025
5356172
Merge branch 'develop' into feature/run-template-improvements
schustmi Aug 6, 2025
cbd7d65
Fix alembic order
schustmi Aug 6, 2025
4dfb3e2
CI fixes
schustmi Aug 7, 2025
b1cb882
Add default deployment version names
schustmi Aug 7, 2025
b1153ba
More version validations
schustmi Aug 7, 2025
f81e7a8
Fix some tests
schustmi Aug 7, 2025
cfe8d65
Add missing arg to client method
schustmi Aug 7, 2025
16b9678
Formatting
schustmi Aug 8, 2025
dbb021d
Merge branch 'develop' into feature/run-template-improvements
schustmi Aug 21, 2025
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
33 changes: 18 additions & 15 deletions src/zenml/actions/pipeline_run/pipeline_run_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@
ActionRequest,
ActionResponse,
ActionUpdate,
PipelineDeploymentTriggerRequest,
TriggerExecutionResponse,
)
from zenml.models.v2.base.base import BaseResponse
from zenml.zen_server.auth import AuthContext
from zenml.zen_server.deployment_execution.utils import trigger_deployment
from zenml.zen_server.rbac.models import ResourceType
from zenml.zen_server.template_execution.utils import run_template
from zenml.zen_server.utils import server_config

logger = get_logger(__name__)
Expand All @@ -45,7 +46,7 @@
class PipelineRunActionConfiguration(ActionConfig):
"""Configuration class to configure a pipeline run action."""

template_id: UUID
deployment_id: UUID
run_config: Optional[PipelineRunConfiguration] = None


Expand Down Expand Up @@ -95,11 +96,13 @@ def run(

assert isinstance(config, PipelineRunActionConfiguration)

template = zen_store().get_run_template(config.template_id)
logger.debug("Running template:", template)
run_template(
template=template,
run_config=config.run_config,
deployment = zen_store().get_deployment(config.deployment_id)
logger.debug("Running deployment:", deployment)
trigger_deployment(
deployment=deployment,
trigger_request=PipelineDeploymentTriggerRequest(
run_configuration=config.run_config,
),
auth_context=auth_context,
sync=True,
)
Expand All @@ -118,10 +121,10 @@ def _validate_configuration(
zen_store = GlobalConfiguration().zen_store

try:
zen_store.get_run_template(template_id=config.template_id)
zen_store.get_deployment(deployment_id=config.deployment_id)
except KeyError:
raise ValueError(
f"No template found with id {config.template_id}."
f"No deployment found with id {config.deployment_id}."
)

def _validate_action_request(
Expand Down Expand Up @@ -185,21 +188,21 @@ def extract_resources(
zen_store = GlobalConfiguration().zen_store

try:
template = zen_store.get_run_template(
template_id=action_config.template_id, hydrate=hydrate
deployment = zen_store.get_deployment(
deployment_id=action_config.deployment_id, hydrate=hydrate
)
except KeyError:
raise ValueError(
f"No template found with id {action_config.template_id}."
f"No deployment found with id {action_config.deployment_id}."
)

resources: Dict[ResourceType, BaseResponse[Any, Any, Any]] = {
ResourceType.RUN_TEMPLATE: template
ResourceType.PIPELINE_DEPLOYMENT: deployment
}

if template.pipeline is not None:
if deployment.pipeline is not None:
pipeline = zen_store.get_pipeline(
pipeline_id=template.pipeline.id, hydrate=hydrate
pipeline_id=deployment.pipeline.id, hydrate=hydrate
)
resources[ResourceType.PIPELINE] = pipeline

Expand Down
3 changes: 3 additions & 0 deletions src/zenml/analytics/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ class AnalyticsEvent(str, Enum):
CREATED_RUN_TEMPLATE = "Run template created"
EXECUTED_RUN_TEMPLATE = "Run templated executed"

# Deployments
EXECUTED_DEPLOYMENT = "Deployment executed"

# Model Control Plane
MODEL_DEPLOYED = "Model deployed"
CREATED_MODEL = "Model created"
Expand Down
165 changes: 161 additions & 4 deletions src/zenml/cli/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@

import json
import os
from typing import Any, Dict, Optional, Union
from typing import Any, Dict, List, Optional, Union
from uuid import UUID

import click

Expand Down Expand Up @@ -335,7 +336,7 @@ def create_run_template(
config_path: Optional[str] = None,
stack_name_or_id: Optional[str] = None,
) -> None:
"""Create a run template for a pipeline.
"""DEPRECATED: Create a run template for a pipeline.

Args:
source: Importable source resolving to a pipeline instance.
Expand All @@ -344,6 +345,11 @@ def create_run_template(
stack_name_or_id: Name or ID of the stack for which the template should
be created.
"""
cli_utils.warning(
"The `zenml pipeline create-run-template` command is deprecated and "
"will be removed in a future version. Please use `zenml pipeline "
"deploy` instead."
)
if not Client().root:
cli_utils.warning(
"You're running the `zenml pipeline create-run-template` command "
Expand All @@ -364,6 +370,157 @@ def create_run_template(
cli_utils.declare(f"Created run template `{template.id}`.")


@pipeline.command("deploy", help="Deploy a pipeline.")
@click.argument("source")
@click.option(
"--version",
"-v",
type=str,
required=False,
help="The version name of the deployment. If not provided, a version "
"name will be generated automatically.",
)
@click.option(
"--description",
"-d",
type=str,
required=False,
help="The description of the deployment.",
)
@click.option(
"--tags",
"-t",
type=str,
required=False,
multiple=True,
help="The tags to add to the deployment.",
)
@click.option(
"--config",
"-c",
"config_path",
type=click.Path(exists=True, dir_okay=False),
required=False,
help="Path to configuration file for the deployment.",
)
@click.option(
"--stack",
"-s",
"stack_name_or_id",
type=str,
required=False,
help="Name or ID of the stack to use for the deployment.",
)
def deploy_pipeline(
source: str,
version: Optional[str] = None,
description: Optional[str] = None,
tags: Optional[List[str]] = None,
config_path: Optional[str] = None,
stack_name_or_id: Optional[str] = None,
) -> None:
"""Deploy a pipeline.

Args:
source: Importable source resolving to a pipeline instance.
version: Version name of the deployment.
description: Description of the deployment.
tags: Tags to add to the deployment.
config_path: Path to configuration file for the deployment.
stack_name_or_id: Name or ID of the stack for which the deployment
should be created.
"""
if not Client().root:
cli_utils.warning(
"You're running the `zenml pipeline deploy` command "
"without a ZenML repository. Your current working directory will "
"be used as the source root relative to which the registered step "
"classes will be resolved. To silence this warning, run `zenml "
"init` at your source code root."
)

with cli_utils.temporary_active_stack(stack_name_or_id=stack_name_or_id):
pipeline_instance = _import_pipeline(source=source)

pipeline_instance = pipeline_instance.with_options(
config_path=config_path
)
deployment = pipeline_instance.deploy(
version=version, description=description, tags=tags
)

cli_utils.declare(
f"Created pipeline deployment `{deployment.id}`. You can now trigger "
f"this deployment from the dashboard or by calling `zenml pipeline "
f"trigger-deployment --deployment {deployment.id}`"
)


@pipeline.command("trigger-deployment", help="Trigger a deployment.")
@click.option(
"--deployment",
"-d",
type=str,
required=False,
help="The ID of the deployment to trigger.",
)
@click.option(
"--pipeline",
"-p",
type=str,
required=False,
help="The name or ID of the pipeline to trigger.",
)
@click.option(
"--version",
"-v",
type=str,
required=False,
help="The version of the deployment to trigger.",
)
@click.option(
"--config",
"-c",
"config_path",
type=click.Path(exists=True, dir_okay=False),
required=False,
help="Path to configuration file for the run.",
)
@click.option(
"--stack",
"-s",
"stack_name_or_id",
type=str,
required=False,
help="Name or ID of the stack to use for the deployment.",
)
def trigger_deployment(
deployment_id: Optional[str] = None,
pipeline_name_or_id: Optional[str] = None,
version: Optional[str] = None,
config_path: Optional[str] = None,
stack_name_or_id: Optional[str] = None,
) -> None:
"""Trigger a deployment.

Args:
deployment_id: The ID of the deployment to trigger.
pipeline_name_or_id: The name or ID of the pipeline to trigger.
version: The version of the deployment to trigger.
config_path: Path to configuration file for the run.
stack_name_or_id: Name or ID of the stack for which the deployment
should be created.
"""
run = Client().trigger_deployment(
deployment_id=UUID(deployment_id) if deployment_id else None,
pipeline_name_or_id=pipeline_name_or_id,
version=version,
config_path=config_path,
stack_name_or_id=stack_name_or_id,
)
cli_utils.declare(f"Triggered deployment run `{run.id}`.")


@pipeline.command("list", help="List all registered pipelines.")
@list_options(PipelineFilter)
def list_pipelines(**kwargs: Any) -> None:
Expand Down Expand Up @@ -407,8 +564,8 @@ def delete_pipeline(
if not yes:
confirmation = cli_utils.confirmation(
f"Are you sure you want to delete pipeline "
f"`{pipeline_name_or_id}`? This will change all "
"existing runs of this pipeline to become unlisted."
f"`{pipeline_name_or_id}`? This will delete all "
"runs and deployments of this pipeline."
)
if not confirmation:
cli_utils.declare("Pipeline deletion canceled.")
Expand Down
Loading
Loading