[[PageOutline(2-5,Contents,pullout)]] = Advanced Ticket Workflow Plugin == Description This plugin provides a number of advanced operations for customizable workflows that are similar to the operations as part of the customizeable workflow of the core system. Currently provided operations are: * set_owner_to_reporter * set_owner_to_component_owner * set_owner_to_field * set_owner_to_previous * set_status_to_previous * reset_milestone * run_external * triage * xref == Bugs/Feature Requests Existing bugs and feature requests for AdvancedTicketWorkflowPlugin are [query:status!=closed&component=AdvancedTicketWorkflowPlugin&order=priority here]. If you have any issues, create a [/newticket?component=AdvancedTicketWorkflowPlugin&owner=retracile new ticket]. File requests for additional operations as enhancement tickets. [[TicketQuery(component=AdvancedTicketWorkflowPlugin&group=type,format=progress)]] == Download Download the [download:advancedticketworkflowplugin zipped source]. == Source Check out [/svn/advancedticketworkflowplugin using Subversion], or [source:advancedticketworkflowplugin browse the source] with Trac. == Installation The plugin can be installed in the same way as other plugins. The simplest is to create an egg as follows: {{{#!sh python setup.py bdist_egg }}} and copy the `.egg` file from the `dist` directory to your Trac environment's `plugins` directory. Then enable the plugin in your `trac.ini` file with: {{{#!ini [components] advancedworkflow.* = enabled }}} Add the individual controller to the workflow controller list. For example, when using `set_owner_to_reporter`, `TicketWorkflowOpOwnerReporter` must be appended to the workflow controller list. {{{#!ini [ticket] workflow = ConfigurableTicketWorkflow,TicketWorkflowOpOwnerReporter }}} The controller name is unique for each workflow operation and they can be found listed in parenthesis after the operation name in the documentation section below. A controller must be added to the list for each workflow operation that is used. And use the operation in your custom workflow: {{{#!ini [ticket-workflow] needinfo = * -> needinfo needinfo.name = Need info needinfo.operations = set_owner_to_reporter }}} == Configuration * set_owner_to_reporter (!TicketWorkflowOpOwnerReporter) Sets the owner to the ticket reporter. {{{#!ini .operations = set_owner_to_reporter }}} * set_owner_to_component_owner (!TicketWorkflowOpOwnerComponent) Sets the owner to the ticket's component owner. {{{#!ini .operations = set_owner_to_component_owner }}} * set_owner_to_field (!TicketWorkflowOpOwnerField) Sets the owner to the value of a ticket field. {{{#!ini .operations = set_owner_to_field .set_owner_to_field = mycustomfield }}} * set_owner_to_previous (!TicketWorkflowOpOwnerPrevious) Sets the owner to the previous owner. If there is no previous owner, the owner will be deleted. {{{#!ini .operations = set_owner_to_previous }}} * set_status_to_previous (!TicketWorkflowOpStatusPrevious) Sets the status to the previous status. If there is no previous status, this is a no-op. {{{#!ini .operations = set_status_to_previous }}} * reset_milestone (!TicketWorkflowOpResetMilestone) Will reset the milestone of a ticket if the milestone has been completed. This is useful for "reopen" actions. {{{#!ini .operations = reset_milestone }}} * run_external (!TicketWorkflowOpRunExternal) Runs an external script `/hooks/` passing the ticket number and the username as parameters. '''Security warning: If you have account registration available, your hook script ''must'' treat the username as user input.''' {{{#!ini .operations = run_external .run_external = Hint to tell the user. }}} * triage (!TicketWorkflowOpTriage) Sets the next status based on mapping the value of a field to a status value. For example, this can be used for a "triage" action that splits a workflow based on the ticket type: {{{#!ini = somestatus -> * .operations = triage .triage_field = type .triage_split = defect->new_defect,task->new_task,enhancement->new_enhancement }}} The most common request is to use a different workflow based on the ticket type. Let's simplify that case slightly for the sake of this example and assume that there are only two ticket types, `defect` and `enhancement`. We'll say that `defect`s require a `qa` step, but `enhancement`s do not: {{{#!ini accept = new -> * accept.name = Accept ticket into workflow accept.operations = triage accept.triage_field = type accept.triage_split = defect->new_defect,enhancement->new_enhancement resolve_enh = new_enhancement -> closed resolve_enh.name = resolve resolve_enh.operations = set_resolution submittotest = new_defect -> qa submittotest.name = Submit to Test resolve_def = qa -> closed resolve_def.name = resolve resolve_def.operations = set_resolution }}} * xref (TicketWorkflowOpXRef) Adds a comment to the ticket specified in the text field. Enter either the bare ticket number or '#' + ticket number. The format of the comment to be added to the other ticket is given as a Python string with a single `%s` in it. That format string defaults to `'Ticket %s is related to this ticket'`. Also adds a comment to the local ticket. The format of the comment for the local ticket can be specified with `.xref_local`; it defaults to `'Ticket %s was marked as related to this ticket'`. This functionality can be disabled by setting `.xref_local` to an empty value. Note that the implementation of this operation is not robust. {{{#!ini ;displays as "close as duplicate [_________]" dup = * -> closed dup.name = close dup.operations = set_resolution,xref dup.set_resolution = duplicate dup.xref = Ticket %s has been marked as a duplicate of this ticket. dup.xref_local = Closed as duplicate of %s. }}} == Recent Changes [[ChangeLog(advancedticketworkflowplugin, 3)]] == Author/Contributors '''Author:''' [wiki:retracile] [[BR]] '''Maintainer:''' [[Maintainer]] [[BR]] '''Contributors:'''