= WorkFlow Examples = == Original Trac 0.10 Workflow ([source:trunk/trac/ticket/workflows/original-workflow.ini original-workflow.ini]) == As described in TracWorkflow with all its known quirks: {{{#!Workflow [ticket-workflow] ; original-workflow.ini ; create the ticket: -> New, owner set to component default or "somebody" ; New: ; leave as new ; accept ticket -> assigned state, owner set to self, shows up as accepted. ; resolve as: -> closed, resolution_set ; reassign to: ; ; Assigned: ; leave as assigned ; resolve as: ; reassign to: -> new state, not accepted ; ; Closed: ; leave as closed ; reopen ticket -> reopened, resolution_del ; ; Reopened: ; leave as reopened ; resolve as: ; reassign to: -> new, owner_set ; This is action-centric leave = * -> * leave.operations = leave_status leave.default = 1 accept = new -> assigned accept.permissions = TICKET_MODIFY accept.operations = set_owner_to_self resolve = new,assigned,reopened -> closed resolve.permissions = TICKET_MODIFY resolve.operations = set_resolution reassign = new,assigned,reopened -> new reassign.permissions = TICKET_MODIFY reassign.operations = set_owner reopen = closed -> reopened reopen.permissions = TICKET_CREATE reopen.operations = del_resolution }}} == Basic ([source:trunk/trac/ticket/workflows/basic-workflow.ini basic-workflow.ini]) == This is an improved version of the original workflow: {{{#!Workflow [ticket-workflow] ; basic-workflow.ini ; ; This workflow is intended to be a "fixed" version of the original workflow. ; ; If you adopt it for an existing Trac environment, don't forget to convert ; the status of your existing tickets. ; ; Both the setup of the new [ticket-workflow] and the migration can be achieved ; by using the following script: ; ; contrib/workflow/migrate_original_to_basic.py leave = * -> * leave.operations = leave_status leave.default = 1 create = -> new create.default = 1 create_and_assign = -> assigned create_and_assign.label = assign create_and_assign.permissions = TICKET_MODIFY create_and_assign.operations = may_set_owner accept = new,assigned,accepted,reopened -> accepted accept.permissions = TICKET_MODIFY accept.operations = set_owner_to_self resolve = new,assigned,accepted,reopened -> closed resolve.permissions = TICKET_MODIFY resolve.operations = set_resolution reassign = new,assigned,accepted,reopened -> assigned reassign.permissions = TICKET_MODIFY reassign.operations = set_owner reopen = closed -> reopened reopen.permissions = TICKET_CREATE reopen.operations = del_resolution [milestone-groups] closed = closed closed.order = 0 closed.query_args = group=resolution closed.overall_completion = true active = * active.order = 1 active.css_class = open new = new,reopened new.order = 2 }}} What it means for a ticket to be "accepted" is left open for interpretation. == Simple ([source:trunk/contrib/workflow/simple-workflow.ini simple-workflow.ini]) == Very simple workflow, suitable for single user Trac environments: {{{#!Workflow [ticket-workflow] ; simple-workflow.ini ; This is action-centric leave = * -> * leave.operations = leave_status leave.default = 1 create = -> new resolve_new = new -> closed resolve_new.label = resolve resolve_new.permissions = TICKET_MODIFY resolve_new.operations = set_owner_to_self,set_resolution accept = new,accepted -> accepted accept.permissions = TICKET_MODIFY accept.operations = set_owner_to_self resolve_accepted = accepted -> closed resolve_accepted.label = resolve resolve_accepted.permissions = TICKET_MODIFY resolve_accepted.operations = set_resolution unaccept = accepted -> new unaccept.permissions = TICKET_MODIFY unaccept.operations = del_owner reopen = closed -> new reopen.permissions = TICKET_CREATE reopen.operations = del_resolution }}} == Trivial ([source:trunk/contrib/workflow/trivial-workflow.ini trivial-workflow.in]) == A very simple workflow, for illustration purposes only: {{{#!Workflow [ticket-workflow] ; trivial-workflow.ini create = -> new resolve = new -> closed resolve.permissions = TICKET_MODIFY resolve.operations = set_resolution reopen = closed -> new reopen.permissions = TICKET_CREATE reopen.operations = del_resolution leave = * -> * leave.operations = leave_status leave.default = 1 }}} == !OpenSource ([source:trunk/contrib/workflow/opensource-workflow.ini opensource-workflow.ini]) == Comprehensive workflow which is adapted to the way we work with tickets in the Trac project: {{{#!Workflow [ticket-workflow] ; opensource-workflow.ini ; create action create = -> new ; accept action ; When you accept a ticket, you get ownership of it. (You can't accept a ; ticket on someone else's behalf.) accept = new,assigned,accepted,started -> accepted accept.operations = set_owner_to_self accept.permissions = TICKET_MODIFY ; assign, reassign, unassign actions assign = new -> assigned assign.operations = set_owner assign.permissions = TICKET_MODIFY reassign = assigned,accepted,started -> assigned reassign.operations = set_owner reassign.permissions = TICKET_MODIFY ; Allow correcting the ownership of a closed ticket. change_owner = closed -> closed change_owner.label = change ownership change_owner.operations = set_owner change_owner.permissions = TICKET_MODIFY unassign = assigned,accepted,started -> new unassign.operations = del_owner unassign.permissions = TICKET_MODIFY ; leave actions leave = * -> * leave.operations = leave_status leave.default = 1 ; resolve actions resolve = new,assigned,accepted,started -> closed resolve.operations = set_resolution resolve.permissions = TICKET_MODIFY ; start/stop actions start = accepted,assigned -> started start.operations = set_owner_to_self start.permissions = TICKET_MODIFY stop = started -> assigned stop.permissions = TICKET_MODIFY ; reopen actions reopen = closed -> new reopen.operations = del_resolution reopen.permissions = TICKET_CREATE ; request info actions ; For tickets with an owner, they go back to assigned request_info = assigned,accepted,started -> infoneeded request_info.permissions = TICKET_MODIFY provide_info = infoneeded -> assigned provide_info.permissions = TICKET_MODIFY provide_info.default = 2 ; But tickets without an owner go back to new. request_info_new = new -> infoneeded_new request_info_new.label = request info request_info_new.permissions = TICKET_MODIFY provide_info_new = infoneeded_new -> new provide_info_new.label = provide info provide_info_new.permissions = TICKET_MODIFY provide_info_new.default = 2 }}} Probably suitable for other open source projects as well, where work must be coordinated between loosely coupled developers. == Enterprise ([source:trunk/contrib/workflow/enterprise-workflow.ini enterprise-workflow.ini]) == Comprehensive workflow with a QA (Quality Assurance) stage: {{{#!Workflow [ticket-workflow] ; enterprise-workflow.ini ; create actions create = -> new create.default = 1 create_and_assign = -> assigned create_and_assign.label = assign create_and_assign.operations = may_set_owner create_and_assign.permissions = TICKET_MODIFY ; assign, reassign, unassign actions assign = new -> assigned assign.operations = set_owner assign.permissions = TICKET_MODIFY reassign = assigned,in_work -> assigned reassign.operations = set_owner reassign.permissions = TICKET_MODIFY reassign_closed = closed -> closed reassign_closed.label = reassign reassign_closed.operations = set_owner reassign_closed.permissions = TICKET_MODIFY unassign = assigned,in_work -> new unassign.operations = del_owner unassign.permissions = TICKET_MODIFY ; leave actions leave = * -> * leave.operations = leave_status leave.default = 1 ; test actions test = new,assigned,in_work -> in_QA test.permissions = TICKET_MODIFY ; resolve actions resolve = in_QA -> closed resolve.operations = set_resolution resolve.permissions = TICKET_MODIFY fail = in_QA -> assigned fail.permissions = TICKET_MODIFY ; start/stop actions start = assigned -> in_work start.operations = set_owner_to_self start.permissions = TICKET_MODIFY stop = in_work -> assigned stop.permissions = TICKET_MODIFY ; reopen actions reopen = closed -> new reopen.operations = del_resolution reopen.permissions = TICKET_CREATE ; request info actions ; For tickets with an owner, they go back to assigned request_info = assigned,in_work,in_QA -> infoneeded request_info.permissions = TICKET_MODIFY provide_info = infoneeded -> assigned provide_info.permissions = TICKET_MODIFY provide_info.default = 2 ; But tickets without an owner go back to new. request_info_new = new -> infoneeded_new request_info_new.label = request info request_info_new.permissions = TICKET_MODIFY provide_info_new = infoneeded_new -> new provide_info_new.label = provide info provide_info_new.permissions = TICKET_MODIFY provide_info_new.default = 2 }}}