From 8d62ebade2ccc07ee3e3a319fe216334108c18b4 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Wed, 27 Mar 2024 16:39:19 +0100 Subject: [PATCH 1/5] Fix toolform not updating for version changes in wf editor This only happens for non-ts tools which don't have the version in their tool id. --- client/src/components/Workflow/Editor/Forms/FormTool.vue | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/src/components/Workflow/Editor/Forms/FormTool.vue b/client/src/components/Workflow/Editor/Forms/FormTool.vue index 0a10578d2e8d..5ea1f49bbcf9 100644 --- a/client/src/components/Workflow/Editor/Forms/FormTool.vue +++ b/client/src/components/Workflow/Editor/Forms/FormTool.vue @@ -116,7 +116,10 @@ export default { }, computed: { id() { - return `${this.stepId}:${this.configForm.id}`; + // Make sure we compute a unique id. Local tools don't include the version in the id, + // but updating tool form when switching tool versions requires that the id changes. + // (see https://github.com/galaxyproject/galaxy/blob/f5e07b11f0996e75b2b6f27896b2301d8fa8717d/client/src/components/Form/FormDisplay.vue#L108) + return `${this.stepId}:${this.configForm.id}/${this.configForm.version}`; }, toolCardId() { return `${this.stepId}`; From b3217607eacacf4abe1a248d57c42c4eacf44644 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Wed, 27 Mar 2024 16:42:59 +0100 Subject: [PATCH 2/5] Fix version switching error in workflow editor --- lib/galaxy/webapps/galaxy/api/workflows.py | 6 ++++-- test/functional/tools/multiple_versions_changes_v01.xml | 5 +++++ test/functional/tools/multiple_versions_changes_v02.xml | 9 +++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/webapps/galaxy/api/workflows.py b/lib/galaxy/webapps/galaxy/api/workflows.py index 686980264f81..853cad1ccc96 100644 --- a/lib/galaxy/webapps/galaxy/api/workflows.py +++ b/lib/galaxy/webapps/galaxy/api/workflows.py @@ -541,15 +541,17 @@ def build_module(self, trans: GalaxyWebTransaction, payload=None): module = module_factory.from_dict(trans, payload, from_tool_form=True) if "tool_state" not in payload: module_state: Dict[str, Any] = {} - populate_state(trans, module.get_inputs(), inputs, module_state, check=False) + errors = {} + populate_state(trans, module.get_inputs(), inputs, module_state, errors=errors, check=True) module.recover_state(module_state, from_tool_form=True) step_dict = { "name": module.get_name(), - "tool_state": module.get_state(), + "tool_state": module_state, "content_id": module.get_content_id(), "inputs": module.get_all_inputs(connectable_only=True), "outputs": module.get_all_outputs(), "config_form": module.get_config_form(), + "errors": errors or None, } if payload["type"] == "tool": step_dict["tool_version"] = module.get_version() diff --git a/test/functional/tools/multiple_versions_changes_v01.xml b/test/functional/tools/multiple_versions_changes_v01.xml index b7b58ed3c65f..da49bbcda794 100644 --- a/test/functional/tools/multiple_versions_changes_v01.xml +++ b/test/functional/tools/multiple_versions_changes_v01.xml @@ -4,6 +4,11 @@ + + + + + diff --git a/test/functional/tools/multiple_versions_changes_v02.xml b/test/functional/tools/multiple_versions_changes_v02.xml index e10c84b87922..14ef9dafeebc 100644 --- a/test/functional/tools/multiple_versions_changes_v02.xml +++ b/test/functional/tools/multiple_versions_changes_v02.xml @@ -5,6 +5,15 @@ + + + + + + + + + From 8e8d7fa0f9b5e84da9b3020d09d5563ddf16f1e4 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Mon, 8 Apr 2024 20:04:33 +0200 Subject: [PATCH 3/5] Fix tool state in build_module and refactor action that can result form upgrading tools. --- lib/galaxy/managers/workflows.py | 4 ++- lib/galaxy/webapps/galaxy/api/workflows.py | 3 ++- lib/galaxy_test/api/test_workflows.py | 30 ++++++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/lib/galaxy/managers/workflows.py b/lib/galaxy/managers/workflows.py index fd955910be3d..79cadc38f36b 100644 --- a/lib/galaxy/managers/workflows.py +++ b/lib/galaxy/managers/workflows.py @@ -1461,6 +1461,8 @@ def _workflow_to_dict_export(self, trans, stored=None, workflow=None, internal=F if not annotation_str and annotation_owner: annotation_str = self.get_item_annotation_str(trans.sa_session, annotation_owner, step) or "" content_id = module.get_content_id() if allow_upgrade else step.content_id + # Fix state if necessary + errors = module.check_and_update_state() # Export differences for backward compatibility tool_state = module.get_export_state() # Step info @@ -1472,7 +1474,7 @@ def _workflow_to_dict_export(self, trans, stored=None, workflow=None, internal=F "tool_version": module.get_version() if allow_upgrade else step.tool_version, "name": module.get_name(), "tool_state": json.dumps(tool_state), - "errors": module.get_errors(), + "errors": errors, "uuid": str(step.uuid), "label": step.label or None, "annotation": annotation_str, diff --git a/lib/galaxy/webapps/galaxy/api/workflows.py b/lib/galaxy/webapps/galaxy/api/workflows.py index 853cad1ccc96..54386e7596c6 100644 --- a/lib/galaxy/webapps/galaxy/api/workflows.py +++ b/lib/galaxy/webapps/galaxy/api/workflows.py @@ -541,9 +541,10 @@ def build_module(self, trans: GalaxyWebTransaction, payload=None): module = module_factory.from_dict(trans, payload, from_tool_form=True) if "tool_state" not in payload: module_state: Dict[str, Any] = {} - errors = {} + errors: Dict[str, str] = {} populate_state(trans, module.get_inputs(), inputs, module_state, errors=errors, check=True) module.recover_state(module_state, from_tool_form=True) + module.check_and_update_state() step_dict = { "name": module.get_name(), "tool_state": module_state, diff --git a/lib/galaxy_test/api/test_workflows.py b/lib/galaxy_test/api/test_workflows.py index a5b884ec3b8a..8ff66bf90e5e 100644 --- a/lib/galaxy_test/api/test_workflows.py +++ b/lib/galaxy_test/api/test_workflows.py @@ -970,6 +970,36 @@ def test_refactor(self): workflow_dict = self.workflow_populator.download_workflow(workflow_id) assert workflow_dict["steps"]["0"]["label"] == "new_label" + def test_refactor_tool_state_upgrade(self): + workflow_id = self.workflow_populator.upload_yaml_workflow( + """ +class: GalaxyWorkflow +inputs: {} +steps: + multiple_versions_changes: + tool_id: multiple_versions_changes + tool_version: "0.1" + state: + inttest: 1 + cond: + bool_to_select: false +""" + ) + actions = [{"action_type": "upgrade_all_steps"}] + refactor_response = self.workflow_populator.refactor_workflow(workflow_id, actions, dry_run=True) + refactor_response.raise_for_status() + refactor_result = refactor_response.json() + upgrade_result = refactor_result["action_executions"][0] + assert upgrade_result["action"]["action_type"] == "upgrade_all_steps" + message_one, message_two = upgrade_result["messages"] + assert message_one["message"] == "No value found for 'floattest'. Using default: '1.0'." + assert message_one["input_name"] == "floattest" + assert message_two["message"] == "The selected case is unavailable/invalid. Using default: 'b'." + assert message_two["input_name"] == "cond|bool_to_select" + + refactor_response = self.workflow_populator.refactor_workflow(workflow_id, actions, dry_run=False) + refactor_response.raise_for_status() + def test_update_no_tool_id(self): workflow_object = self.workflow_populator.load_workflow(name="test_import") upload_response = self.__test_upload(workflow=workflow_object) From d0c2b502d2f8227d7a101db05b7794fbe07ff388 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Mon, 8 Apr 2024 22:07:42 +0200 Subject: [PATCH 4/5] Only run check_and_update_state when current state fails --- lib/galaxy/managers/workflows.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/galaxy/managers/workflows.py b/lib/galaxy/managers/workflows.py index 79cadc38f36b..89cc96698b83 100644 --- a/lib/galaxy/managers/workflows.py +++ b/lib/galaxy/managers/workflows.py @@ -1461,10 +1461,14 @@ def _workflow_to_dict_export(self, trans, stored=None, workflow=None, internal=F if not annotation_str and annotation_owner: annotation_str = self.get_item_annotation_str(trans.sa_session, annotation_owner, step) or "" content_id = module.get_content_id() if allow_upgrade else step.content_id - # Fix state if necessary - errors = module.check_and_update_state() - # Export differences for backward compatibility - tool_state = module.get_export_state() + errors = {} + try: + tool_state = module.get_export_state() + except ValueError: + # Fix state if necessary + errors = module.check_and_update_state() + tool_state = module.get_export_state() + # Step info step_dict = { "id": step.order_index, @@ -1474,7 +1478,7 @@ def _workflow_to_dict_export(self, trans, stored=None, workflow=None, internal=F "tool_version": module.get_version() if allow_upgrade else step.tool_version, "name": module.get_name(), "tool_state": json.dumps(tool_state), - "errors": errors, + "errors": errors or module.get_errors(), "uuid": str(step.uuid), "label": step.label or None, "annotation": annotation_str, From e3b56f13f40ba8ef790281a930ff69c4205fe637 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Tue, 9 Apr 2024 11:50:52 +0200 Subject: [PATCH 5/5] Adjust integration test for additional conditional --- test/integration/test_workflow_refactoring.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/test_workflow_refactoring.py b/test/integration/test_workflow_refactoring.py index 4fd5a2d712ce..6a03d818ce31 100644 --- a/test/integration/test_workflow_refactoring.py +++ b/test/integration/test_workflow_refactoring.py @@ -559,7 +559,7 @@ def test_tool_version_upgrade_state_added(self): assert len(action_executions) == 1 messages = action_executions[0].messages - assert len(messages) == 1 + assert len(messages) == 2 message = messages[0] assert message.message_type == RefactorActionExecutionMessageTypeEnum.tool_state_adjustment assert message.order_index == 0