mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-15 22:05:53 +08:00
fix: cannot delete workflow version if other version is published as a tool (#18486)
Signed-off-by: -LAN- <laipz8200@outlook.com>
This commit is contained in:
parent
3136eb8e4b
commit
2543162dec
@ -245,6 +245,13 @@ class Workflow(Base):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def tool_published(self) -> bool:
|
def tool_published(self) -> bool:
|
||||||
|
"""
|
||||||
|
DEPRECATED: This property is not accurate for determining if a workflow is published as a tool.
|
||||||
|
It only checks if there's a WorkflowToolProvider for the app, not if this specific workflow version
|
||||||
|
is the one being used by the tool.
|
||||||
|
|
||||||
|
For accurate checking, use a direct query with tenant_id, app_id, and version.
|
||||||
|
"""
|
||||||
from models.tools import WorkflowToolProvider
|
from models.tools import WorkflowToolProvider
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -28,6 +28,7 @@ from extensions.ext_database import db
|
|||||||
from models.account import Account
|
from models.account import Account
|
||||||
from models.enums import CreatedByRole
|
from models.enums import CreatedByRole
|
||||||
from models.model import App, AppMode
|
from models.model import App, AppMode
|
||||||
|
from models.tools import WorkflowToolProvider
|
||||||
from models.workflow import (
|
from models.workflow import (
|
||||||
Workflow,
|
Workflow,
|
||||||
WorkflowNodeExecution,
|
WorkflowNodeExecution,
|
||||||
@ -523,8 +524,19 @@ class WorkflowService:
|
|||||||
# Cannot delete a workflow that's currently in use by an app
|
# Cannot delete a workflow that's currently in use by an app
|
||||||
raise WorkflowInUseError(f"Cannot delete workflow that is currently in use by app '{app.name}'")
|
raise WorkflowInUseError(f"Cannot delete workflow that is currently in use by app '{app.name}'")
|
||||||
|
|
||||||
# Check if this workflow is published as a tool
|
# Don't use workflow.tool_published as it's not accurate for specific workflow versions
|
||||||
if workflow.tool_published:
|
# Check if there's a tool provider using this specific workflow version
|
||||||
|
tool_provider = (
|
||||||
|
session.query(WorkflowToolProvider)
|
||||||
|
.filter(
|
||||||
|
WorkflowToolProvider.tenant_id == workflow.tenant_id,
|
||||||
|
WorkflowToolProvider.app_id == workflow.app_id,
|
||||||
|
WorkflowToolProvider.version == workflow.version,
|
||||||
|
)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
|
||||||
|
if tool_provider:
|
||||||
# Cannot delete a workflow that's published as a tool
|
# Cannot delete a workflow that's published as a tool
|
||||||
raise WorkflowInUseError("Cannot delete workflow that is published as a tool")
|
raise WorkflowInUseError("Cannot delete workflow that is published as a tool")
|
||||||
|
|
||||||
|
@ -40,6 +40,10 @@ def workflow_setup():
|
|||||||
|
|
||||||
def test_delete_workflow_success(workflow_setup):
|
def test_delete_workflow_success(workflow_setup):
|
||||||
# Setup mocks
|
# Setup mocks
|
||||||
|
|
||||||
|
# Mock the tool provider query to return None (not published as a tool)
|
||||||
|
workflow_setup["session"].query.return_value.filter.return_value.first.return_value = None
|
||||||
|
|
||||||
workflow_setup["session"].scalar = MagicMock(
|
workflow_setup["session"].scalar = MagicMock(
|
||||||
side_effect=[workflow_setup["workflow"], None]
|
side_effect=[workflow_setup["workflow"], None]
|
||||||
) # Return workflow first, then None for app
|
) # Return workflow first, then None for app
|
||||||
@ -97,7 +101,12 @@ def test_delete_workflow_in_use_by_app_error(workflow_setup):
|
|||||||
|
|
||||||
def test_delete_workflow_published_as_tool_error(workflow_setup):
|
def test_delete_workflow_published_as_tool_error(workflow_setup):
|
||||||
# Setup mocks
|
# Setup mocks
|
||||||
workflow_setup["workflow"].tool_published = True
|
from models.tools import WorkflowToolProvider
|
||||||
|
|
||||||
|
# Mock the tool provider query
|
||||||
|
mock_tool_provider = MagicMock(spec=WorkflowToolProvider)
|
||||||
|
workflow_setup["session"].query.return_value.filter.return_value.first.return_value = mock_tool_provider
|
||||||
|
|
||||||
workflow_setup["session"].scalar = MagicMock(
|
workflow_setup["session"].scalar = MagicMock(
|
||||||
side_effect=[workflow_setup["workflow"], None]
|
side_effect=[workflow_setup["workflow"], None]
|
||||||
) # Return workflow first, then None for app
|
) # Return workflow first, then None for app
|
||||||
|
Loading…
x
Reference in New Issue
Block a user