Commit 5f26ba4d authored by Rafael Monnerat's avatar Rafael Monnerat

slapos_pdm: Implement upgrade_slap_interface_workflow

parent 94317550
Pipeline #19301 failed with stage
in 0 seconds
......@@ -5,6 +5,6 @@
</chain>
<chain>
<type>Upgrade Decision</type>
<workflow>edit_workflow, ticket_interaction_workflow, upgrade_decision_workflow</workflow>
<workflow>edit_workflow, ticket_interaction_workflow, upgrade_decision_workflow, upgrade_slap_interface_workflow</workflow>
</chain>
</workflow_chain>
\ No newline at end of file
......@@ -41,22 +41,17 @@ for software_release in software_release_list:
# If exist upgrade decision in progress try to cancel it
decision_in_progress = newer_release.\
SoftwareRelease_getUpgradeDecisionInProgress(compute_node.getUid())
if decision_in_progress and \
not decision_in_progress.UpgradeDecision_tryToCancel(
newer_release.getUrlString()):
continue
if decision_in_progress:
decision_in_progress.reviewRegistration(
software_release_url=newer_release.getUrlString())
if decision_in_progress.getSimulationState() != "cancelled":
continue
upgrade_decision = newer_release.SoftwareRelease_createUpgradeDecision(
source_url=compute_node.getRelativeUrl(),
title=title)
if context.getUpgradeScope() == "auto":
upgrade_decision.start()
elif context.getUpgradeScope("ask_confirmation") == "ask_confirmation" \
and upgrade_decision.getSimulationState() != "planned":
upgrade_decision.plan()
upgrade_decision.setStartDate(DateTime())
upgrade_decision.approveRegistration(upgrade_scope=compute_node.getUpgradeScope("ask_confirmation"))
upgrade_decision_list.append(upgrade_decision)
return upgrade_decision_list
......@@ -52,22 +52,16 @@ if newer_release is None:
decision_in_progress = newer_release.\
SoftwareRelease_getUpgradeDecisionInProgress(instance_tree.getUid())
if decision_in_progress and \
not decision_in_progress.UpgradeDecision_tryToCancel(
newer_release.getUrlString()):
return
if decision_in_progress:
decision_in_progress.reviewRegistration(
software_release_url=newer_release.getUrlString())
if decision_in_progress.getSimulationState() != "cancelled":
return
upgrade_decision = newer_release.SoftwareRelease_createUpgradeDecision(
source_url=instance_tree.getRelativeUrl(),
title=decision_title
)
with upgrade_decision.defaultActivateParameterDict(activate_kw):
upgrade_decision.plan()
upgrade_decision.setStartDate(DateTime())
if upgrade_scope == "auto":
upgrade_decision.start()
# Prevent concurrent transaction to create 2 upgrade decision for the same instance_tree
instance_tree.serialize()
upgrade_decision.approveRegistration()
return upgrade_decision
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_count</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_mt_index</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>_tree</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>source/portal_workflow/upgrade_slap_interface_workflow/state_draft</string>
</tuple>
</value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>person_slap_interface_workflow</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>upgrade_slap_interface_workflow</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>manager_bypass</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow</string> </value>
</item>
<item>
<key> <string>state_variable</string> </key>
<value> <string>slap_state</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Upgrade Slap Interface Workflow</string> </value>
</item>
<item>
<key> <string>workflow_managed_permission</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Length" module="BTrees.Length"/>
</pickle>
<pickle> <int>0</int> </pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
</ZopeData>
upgrade_decision = state_change["object"]
from DateTime import DateTime
portal = context.getPortalObject()
document = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
if document is None:
document = upgrade_decision.UpgradeDecision_getAggregateValue("Compute Node")
# Get required arguments
kwargs = state_change.kwargs
# Required args
# Raise TypeError if all parameters are not provided
try:
upgrade_scope = kwargs['upgrade_scope']
except KeyError:
raise TypeError("UpgradeDecision_reviewRegistration takes exactly 1 arguments")
tag = "%s_requestUpgradeDecisionCreation_inProgress" % document.getUid()
activate_kw = {'tag': tag}
if portal.portal_activities.countMessageWithTag(tag) > 0:
# nothing to do
return
with upgrade_decision.defaultActivateParameterDict(activate_kw):
if upgrade_decision.getSimulationState() != "planned":
upgrade_decision.plan()
upgrade_decision.setStartDate(DateTime())
if upgrade_scope == "auto":
upgrade_decision.start()
# Prevent concurrent transaction to create 2 upgrade decision for the same instance_tree
instance_tree.serialize()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_UpgradeDecision_approveRegistration</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>UpgradeDecision_approveRegistration</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -2,7 +2,7 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
<global name="Workflow Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
......@@ -50,11 +50,27 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>new_url_string</string> </value>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>UpgradeDecision_tryToCancel</string> </value>
<value> <string>script_UpgradeDecision_checkConsistency</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
......
upgrade_decision = context
upgrade_decision = state_change["object"]
from DateTime import DateTime
portal = context.getPortalObject()
cancellable_state_list = ['confirmed', 'planned']
require_state_list = ['rejected', 'confirmed', 'planned']
simulation_state = upgrade_decision.getSimulationState()
# Get required arguments
kwargs = state_change.kwargs
# Required args
# Raise TypeError if all parameters are not provided
try:
software_release_url = kwargs['software_release_url']
except KeyError:
raise TypeError("UpgradeDecision_reviewRegistration takes exactly 1 arguments")
if simulation_state in require_state_list:
current_release = upgrade_decision.UpgradeDecision_getSoftwareRelease()
if not current_release:
# This upgrade decision is not valid
return False
return
instance_tree = context.UpgradeDecision_getAggregateValue("Instance Tree")
if instance_tree is not None:
current_instance_tree_release = instance_tree.getUrlString()
if current_instance_tree_release == new_url_string:
if current_instance_tree_release == software_release_url:
if simulation_state in cancellable_state_list:
upgrade_decision.cancel()
return True
return
if current_release.getUrlString() == new_url_string:
if current_release.getUrlString() == software_release_url:
# Cannot cancel because the software releases are the same
return False
if simulation_state in cancellable_state_list:
upgrade_decision.cancel()
return True
else:
return False
return
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_UpgradeDecision_reviewRegistration</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>UpgradeDecision_reviewRegistration</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow State" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>acquire_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>destination/portal_workflow/upgrade_slap_interface_workflow/transition_approve_registration</string>
<string>destination/portal_workflow/upgrade_slap_interface_workflow/transition_review_registration</string>
</tuple>
</value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>state_draft</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow State</string> </value>
</item>
<item>
<key> <string>state_permission_role_list_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>state_type</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Draft</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Transition" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency</string>
<string>after_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_approveRegistration</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_approve_registration</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Approve Registration</string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Transition" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency</string>
<string>after_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_reviewRegistration</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Cancel if the upgrade is outdated </string> </value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_review_registration</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Review Registration</string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>The last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_action</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>transition/getReference|nothing</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>The name of the user who performed the last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_actor</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>user/getUserName</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Comments about the last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_comment</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>python:state_change.kwargs.get(\'comment\', \'\')</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Error message if validation failed</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_error_message</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Provides access to workflow history</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_history</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>state_change/getHistory</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>portal type (use as filter for worklists)</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_portal_type</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Variable" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>automatic_update</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Time of the last transition</string> </value>
</item>
<item>
<key> <string>for_catalog</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variable_time</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Variable</string> </value>
</item>
<item>
<key> <string>status_included</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>variable_default_expression</string> </key>
<value> <string>state_change/getDateTime</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -2,4 +2,5 @@ Software Product | -validation_workflow
Software Product | commerce_validation_workflow
Upgrade Decision | edit_workflow
Upgrade Decision | ticket_interaction_workflow
Upgrade Decision | upgrade_decision_workflow
\ No newline at end of file
Upgrade Decision | upgrade_decision_workflow
Upgrade Decision | upgrade_slap_interface_workflow
\ No newline at end of file
upgrade_decision_workflow
\ No newline at end of file
upgrade_decision_workflow
upgrade_slap_interface_workflow
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment