13 | | [[Image(htdocs:../common/guide/original-workflow.png)]] |
| 13 | {{{#!Workflow width=500 height=240 |
| 14 | leave = * -> * |
| 15 | leave.operations = leave_status |
| 16 | leave.default = 1 |
| 17 | accept = new -> assigned |
| 18 | accept.permissions = TICKET_MODIFY |
| 19 | accept.operations = set_owner_to_self |
| 20 | resolve = new,assigned,reopened -> closed |
| 21 | resolve.permissions = TICKET_MODIFY |
| 22 | resolve.operations = set_resolution |
| 23 | reassign = new,assigned,reopened -> new |
| 24 | reassign.permissions = TICKET_MODIFY |
| 25 | reassign.operations = set_owner |
| 26 | reopen = closed -> reopened |
| 27 | reopen.permissions = TICKET_CREATE |
| 28 | reopen.operations = del_resolution |
| 29 | }}} |
23 | | [[Image(htdocs:../common/guide/basic-workflow.png)]] |
| 39 | {{{#!Workflow width=700 height=300 |
| 40 | leave = * -> * |
| 41 | leave.operations = leave_status |
| 42 | leave.default = 1 |
| 43 | accept = new,assigned,accepted,reopened -> accepted |
| 44 | accept.permissions = TICKET_MODIFY |
| 45 | accept.operations = set_owner_to_self |
| 46 | resolve = new,assigned,accepted,reopened -> closed |
| 47 | resolve.permissions = TICKET_MODIFY |
| 48 | resolve.operations = set_resolution |
| 49 | reassign = new,assigned,accepted,reopened -> assigned |
| 50 | reassign.permissions = TICKET_MODIFY |
| 51 | reassign.operations = set_owner |
| 52 | reopen = closed -> reopened |
| 53 | reopen.permissions = TICKET_CREATE |
| 54 | reopen.operations = del_resolution |
| 55 | }}} |
44 | | - del_owner -- Clear the owner field. |
45 | | - set_owner -- Sets the owner to the selected or entered owner. |
46 | | - ''actionname''`.set_owner` may optionally be set to a comma delimited list or a single value. |
47 | | - set_owner_to_self -- Sets the owner to the logged in user. |
48 | | - del_resolution -- Clears the resolution field |
49 | | - set_resolution -- Sets the resolution to the selected value. |
50 | | - ''actionname''`.set_resolution` may optionally be set to a comma delimited list or a single value. |
51 | | {{{ |
52 | | Example: |
53 | | |
| 80 | - **del_owner** -- Clear the owner field. |
| 81 | - **set_owner** -- Sets the owner to the selected or entered owner. Defaults to the current user. When `[ticket] restrict_owner = true`, the select will be populated with users that have `TICKET_MODIFY` permission and an authenticated session. |
| 82 | - ''actionname''`.set_owner` may optionally be set to a comma delimited list of users that will be used to populate the select, or a single user. |
| 83 | - **set_owner_to_self** -- Sets the owner to the logged in user. |
| 84 | - **del_resolution** -- Clears the resolution field |
| 85 | - **set_resolution** -- Sets the resolution to the selected value. |
| 86 | - ''actionname''`.set_resolution` may optionally be set to a comma delimited list or a single value. Example: |
| 87 | {{{#!ini |
| 146 | === How to combine the `tracopt.ticket.commit_updater` with the testing workflow === |
| 147 | |
| 148 | The [[trac:source:trunk/tracopt/ticket/commit_updater.py|tracopt.ticket.commit_updater]] is the optional component that [[TracRepositoryAdmin#trac-post-commit-hook|replaces the old trac-post-commit-hook]], in Trac 0.12. |
| 149 | |
| 150 | By default it reacts on some keywords found in changeset message logs like ''close'', ''fix'' etc. and performs the corresponding workflow action. |
| 151 | |
| 152 | If you have a more complex workflow, like the testing stage described above and you want the ''closes'' keyword to move the ticket to the ''testing'' status instead of the ''closed'' status, you need to adapt the code a bit. |
| 153 | |
| 154 | Have a look at the [[trac:wiki:0.11/TracWorkflow#How-ToCombineSVNtrac-post-commit-hookWithTestWorkflow|Trac 0.11 recipe]] for the `trac-post-commit-hook`, this will give you some ideas about how to modify the component. |
| 155 | |
| 156 | == Example: Add simple optional generic review state == |
| 157 | |
| 158 | Sometimes Trac is used in situations where "testing" can mean different things to different people so you may want to create an optional workflow state that is between the default workflow's `assigned` and `closed` states, but does not impose implementation-specific details. The only new state you need to add for this is a `reviewing` state. A ticket may then be "submitted for review" from any state that it can be reassigned. If a review passes, you can re-use the `resolve` action to close the ticket, and if it fails you can re-use the `reassign` action to push it back into the normal workflow. |
| 159 | |
| 160 | The new `reviewing` state along with its associated `review` action looks like this: |
| 161 | |
| 162 | {{{#!ini |
| 163 | review = new,assigned,reopened -> reviewing |
| 164 | review.operations = set_owner |
| 165 | review.permissions = TICKET_MODIFY |
| 166 | }}} |
| 167 | |
| 168 | Then, to integrate this with the default Trac 0.11 workflow, you also need to add the `reviewing` state to the `accept` and `resolve` actions, like so: |
| 169 | |
| 170 | {{{#!ini |
| 171 | accept = new,reviewing -> assigned |
| 172 | […] |
| 173 | resolve = new,assigned,reopened,reviewing -> closed |
| 174 | }}} |
| 175 | |
| 176 | Optionally, you can also add a new action that allows you to change the ticket's owner without moving the ticket out of the `reviewing` state. This enables you to reassign review work without pushing the ticket back to the `new` status. |
| 177 | |
| 178 | {{{#!ini |
| 179 | reassign_reviewing = reviewing -> * |
| 180 | reassign_reviewing.name = reassign review |
| 181 | reassign_reviewing.operations = set_owner |
| 182 | reassign_reviewing.permissions = TICKET_MODIFY |
| 183 | }}} |
| 184 | |
| 185 | The full `[ticket-workflow]` configuration will thus look like this: |
| 186 | |
| 187 | {{{#!ini |
| 188 | [ticket-workflow] |
| 189 | accept = new,reviewing -> assigned |
| 190 | accept.operations = set_owner_to_self |
| 191 | accept.permissions = TICKET_MODIFY |
| 192 | leave = * -> * |
| 193 | leave.default = 1 |
| 194 | leave.operations = leave_status |
| 195 | reassign = new,assigned,accepted,reopened -> assigned |
| 196 | reassign.operations = set_owner |
| 197 | reassign.permissions = TICKET_MODIFY |
| 198 | reopen = closed -> reopened |
| 199 | reopen.operations = del_resolution |
| 200 | reopen.permissions = TICKET_CREATE |
| 201 | resolve = new,assigned,reopened,reviewing -> closed |
| 202 | resolve.operations = set_resolution |
| 203 | resolve.permissions = TICKET_MODIFY |
| 204 | review = new,assigned,reopened -> reviewing |
| 205 | review.operations = set_owner |
| 206 | review.permissions = TICKET_MODIFY |
| 207 | reassign_reviewing = reviewing -> * |
| 208 | reassign_reviewing.operations = set_owner |
| 209 | reassign_reviewing.name = reassign review |
| 210 | reassign_reviewing.permissions = TICKET_MODIFY |
| 211 | }}} |
| 212 | |
134 | | == some ideas for next steps == |
135 | | |
136 | | New enhancement ideas for the workflow system should be filed as enhancement tickets against the `ticket system` component. If desired, add a single-line link to that ticket here. |
137 | | |
138 | | If you have a response to the comments below, create an enhancement ticket, and replace the description below with a link to the ticket. |
139 | | |
140 | | * the "operation" could be on the nodes, possible operations are: |
141 | | * '''preops''': automatic, before entering the state/activity |
142 | | * '''postops''': automatic, when leaving the state/activity |
143 | | * '''actions''': can be chosen by the owner in the list at the bottom, and/or drop-down/pop-up together with the default actions of leaving the node on one of the arrows. |
144 | | This appears to add complexity without adding functionality; please provide a detailed example where these additions allow something currently impossible to implement. |
145 | | |
146 | | * operations could be anything: sum up the time used for the activity, or just write some statistical fields like |
147 | | A workflow plugin can add an arbitrary workflow operation, so this is already possible. |
148 | | |
149 | | * set_actor should be an operation allowing to set the owner, e.g. as a "preop": |
150 | | * either to a role, a person |
151 | | * entered fix at define time, or at run time, e.g. out of a field, or select. |
152 | | This is either duplicating the existing `set_owner` operation, or needs to be clarified. |
153 | | |
154 | | * Actions should be selectable based on the ticket type (different Workflows for different tickets) |
155 | | This is becoming a frequent request, with clear usecases. The closest the current implementation will allow is to have a plugin provide a `triage` action that sets the next state based on the ticket type, so a `new` ticket would move to `new_task`, `new_defect`, etc., and the workflow graph would separate at that point. |
| 235 | == Adding Workflow States to Milestone Progress Bars == |
| 236 | |
| 237 | If you add additional states to your workflow, you may want to customize your milestone progress bars as well. See [TracIni#milestone-groups-section TracIni]. |
| 238 | |
| 239 | == Ideas for next steps == |
| 240 | |
| 241 | New enhancement ideas for the workflow system should be filed as enhancement tickets against the `ticket system` component. You can also document ideas on the [trac:TracIdeas/TracWorkflow TracIdeas/TracWorkflow] page. Also look at the [http://trac-hacks.org/wiki/AdvancedTicketWorkflowPlugin AdvancedTicketWorkflowPlugin] as it provides experimental operations. |