Optimize your JIRA approval process with ScriptRunner and Groovy scripting.

Introduction
Are you considering using JIRA to support an approval process, but you’re not sure how to tackle it?  This page details an implementation we made for one of our customers using a bit of groovy scripting and the unbelievable essential ScriptRunner from Adaptavist.

The environment
This customer is one of these robust financial organizations where every project needs to be documented in full before implementation starts.  They have on average 2 releases per year and this approach proved to be very trustworthy and stable.  The team was looking for a way to formally approve these documents instead of managing these approvals in a manual way.

We proposed to use JIRA, enhanced with the ScriptRunner,  as it contains all functionality to implement the requirements
The customer document approval process has mainly 3 stages:

  • Drafting stage
    During the drafting stage, an author redacts the content of a document and once ready publish it on JIRA.
  • Level 1 approval stage
    All documents need to be approved by a number of stakeholders in the IT department. Next, to the approvers, a number of people need to be kept up to date when new versions of the document are published.

    • Each approver can either approve or reject a document.  This individual action needs to be logged.
    • The project manager can decide to either push the document back into review (because some comments need to be addressed) or approve the document and trump any people who have been rejecting the content.
    • It must be easy for the stakeholders to express their opinion.  As most of them live their professional life in their email box, all interactions should be email-based.
  • Level 2 approval stage
    Once the level 1 approval has been reached, the document is promoted to the level 2 approval stage where the project management board decides on the final faith of the document.  Either it is approved, pushed back into a review or rejected.

The solution
We decided to use a practical approach to solving this requirement. After a team brainstorm, we came up with the following approach:

The user picker custom fields
The user picker (multiple users) is a standard custom field part of JIRA.

Jira Field type
This is a really nice control as it allows collecting multiple users into a single custom field

To support the approval workflow, we created 4 different user pickers.

  • Approvers
    This list contains all users who must provide their approval for a document.
  • Has accepted
    Will list all users who approved a document.
  • Has declined
    These are the ones that asked to modify the document.
  • Readers
    Are the people that need to be kept up to date.
  • To Approve
    Are the people who still need to provide their opinion.

The workflow
The complete approval workflow can now be implemented by using a script that moves users from one user list to another.

  • When a user approves the document, his/her userid will be moved from ‘To Approve’ to ‘Has Accepted’
  • When a user refuses the document, his/her userid is moved from ‘To Approve’ to ‘Has Declined’
  • When a document is submitted for review, the ‘To Approve’ list is initialized from the ‘Approvers’ List

Jira workflow

Submitting a document.

The status ‘open’ denotes the drafting stage, and it is the first status in the workflow. Once the author of the document considers the content fit for review, s/he will progress the document issue to the ‘SENT’ status.

Jira sent status
The author can still add/remove users from the approvers/readers list and press send.
Jira approvers/readers list
The groovy script copies all the users listed in the ‘Approvers’ list to the ‘To Approve’ custom field. The workflow triggers a custom event ‘Document Sent’ which is translated into a notification for all users in the ‘To Approve’ custom field.

To approve or to reject – that’s the question:

The workflow has 2 transitions in status ‘Sent’ – Approve or Reject
Jira workflow transition status
These transitions are only accessible for the users which are in the ‘to approve’ list. Depending on the chosen transition, the userid will be copied from the ‘to approve’ list to either the ‘has approved’ or ‘has declined’ list. A notification is sent to the project manager.

Auto transitioning issues

One of the requirements of the customer was that once all approvers approved the document, it would go automatically to the status ‘Approved’. To implement this requirement, we used the ScriptRunner escalation service. This service runs every couple of minutes, triggering an ‘autoApprove’ transition on every issue which matches the following jql.

issuetype = Document and 'To approve' is empty and 'Has declined' is empty and 'Has accepted' is not empty and status = sent

Jira approval issuetype
Sending notifications:

Given the email orientation of the users, we decided to enhance the notifications such that

  • The notification message contains all attachments related to the document issue.
  • The message contains a link to trigger approval and a trigger to reject the document
    The advantage is that the user now can read the document and click one or both links.

Keeping track of the approval history
One of the requirements was to ensure that the complete approval history would be tracked. Given that comments are also used for providing feedback on the document, we decided to create a custom field ‘Approval Comment’ which is used to collect the history.

Wrapping up
Using the ScriptRunner from Adaptavist, it is possible to create, in a simple way, pretty advanced customizations.
The system is in use by more than 500 users, for a couple of years now. The ROI of the solution was a couple of weeks.

The code behind it all
The whole solution is groovy-based. Check out the following links for some examples of how the logic has been constructed.

  • setApprovers.groovy
    The setApprovers.groovy is a simple script that copies the content of the approvers and readers’ project role to the corresponding approvers and readers’ user list. This way, one can define on a project level the approvers and readers of any document created in the context of that project.
  • ApprovalLogic.groovy
    The approval logic is all contained in a single class.  It contains methods for the different use cases, such as:

    • doAccept – used when the current user accepts a document
    • doDecline – used when the current user declines the document
    • delegateTo – the workflow allows a user to delegate the approval to a colleague.  This method will then rearrange the content of the different user lists.
    • changeApprovers – used when the approver’s list changes, taking into account the past history of approvals.
  • SendCustomEmailWithUniqueAttachments.groovy
    This class is an enhanced ‘SendCustomEmail’ script listener, which will filter out duplicate attachments.  The issue is that users tend to upload multiple versions of the same attachment, and you want to send only the latest version.
    You need to add it to the right path (ie under your script root …/com/onresolve/scriptrunner/canned/jira/workflow/postfunctions) and restart ScriptRunner. It will be picked up automatically and be available as one of the options on the script listeners.

 

Script Plugin

To simplify the deployment of this code, we opted to create a script plugin – which is actually like a JIRA add-on, but then use the groovy classes as resources. It is straightforward to do and well described on the documentation site here.

Are you still using multiple-issue trackers?

Check out exalate https://www.exalate.com – Exalate is an advanced issue synchronization solution that supports cross-organization issue tracking.

Its flexibility comes from the built-in groovy scripting capability, allowing it to implement of almost any type of integration.
Exalate

Do you now need support?

You can always contact us to help out with the implementation of your use cases, just contact us.

Outline

Subscribe to our newsletter to receive monday.com insights & events

    Related Articles