[[PageOutline(2-5,Contents,pullout)]] = Advanced Ticket Workflow == Description This plugin provides a number of advanced operations to customise ticket workflows. They are an enhancement to the operations as part of the customizeable workflow of the Trac 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 * set_field_to_author * reset_milestone * clear_fields * run_external * triage * xref The meaning behind each of these operations is explained below. == Bugs/Feature Requests Existing bugs and feature requests for AdvancedTicketWorkflowPlugin are [report:9?COMPONENT=AdvancedTicketWorkflowPlugin here]. If you have any issues, create a [/newticket?component=AdvancedTicketWorkflowPlugin new ticket]. File requests for additional operations as enhancement tickets. [[TicketQuery(component=AdvancedTicketWorkflowPlugin&group=type,format=progress)]] == Download Download the zipped source from [export:advancedticketworkflowplugin here]. The plugin is also available on [pypi:TracAdvancedTicketWorkflow PyPI]. == Source Check out AdvancedTicketWorkflowPlugin from [/svn/advancedticketworkflowplugin here] 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: {{{#!ini [components] advancedworkflow.* = enabled }}} Add the individual controller to the workflow controller list. For example, when using the operation `set_owner_to_reporter`, the `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 parentheses after the operation name in the configuration 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 The following are examples of custom workflow operations together with their controller name: * 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 }}} * set_field_to_author (!TicketWorkflowOpFieldAuthor) Sets the value of a ticket field to the current user. {{{#!ini .operations = set_field_to_author .set_field_to_author = myfield }}} * 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 }}} * clear_field (!TicketWorkflowOpFieldsClear) Clear the value of the ticket field(s). {{{#!ini .operations = clear_fields .clear_fields = myfield_one, myfield_two }}} * 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 "closed as duplicate of [_________]" 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:'''