Extend Jira Workflows

Customize JIRA Workflows

Every Agile project has a checklist to verify when a task moves from one stage to another. In our project as well there is a checklist for developers, when they move a task from IN PROGRESS to TESTING. One of the items on the list is to raise a pull request when a ticket has been fixed. The person who picks up the ticket for testing verifies if a PR exists for the same. If not, then either she raises a PR, after consulting the concerned developer, or the task is moved to TO DO. This often creates issues for the retrospective where the two parties would discuss the same. So post one such retro, our team took the decision to enable the Pull Request check from JIRA. The check will be triggered when a task is moved to TESTING . It will validate if the PR exists, if not the task will not be moved to TESTING.

This is the sixth post of our blogger month at Xebia. Every day one of the Xebian post a new blog. You can follow the full series at http://blog.xebia.in/pages/blogger-month-2015/.

Before we could implement the same we need to understand how JIRA works and what needs to be done to reach at the above goal. JIRA has a plugin architecture but do we need a plugin for above ? No, because plugins bring in something that is completely new to JIRA like the JIRA Agile plugin or the JIRA Calendar Plugin

The above requirement is more like extending an existing plugin. The stages of TO DO, IN PROGRESS, DONE are created by the JIRA Agile plugin. A closer look tells that it is not the Agile plugin which needs to be customized but rather just a transition.

JIRA defines the lifecycle of an issue in terms of workflows. Each project has an attached workflow, which would define a sequence of steps. The Agile Plugin also creates a workflow, which is added to different project. If you are an administrator of JIRA then view the same under :
JIRA Administration > Issues > Workflows

Workflow

If we edit one such Workflow we find that it allows us to add various components like Triggers, Conditions, Validators and Post Functions.
Triggers, are the ones which automatically transfer a issue to a state.
Conditions, specify the case which will make the transition available.
Validators, perform checks just before the transition.
Post Functions, specify any custom processing after the issue have been moved.

Thus for our purpose we need to specify a Validator which can validate the existence of a Pull Request against the issue.

The above capability is exposed in JIRA by using the Workflow plugin Module. JIRA has a number of plugins and each of these contains various modules which can be used for some purpose. The complete list of default modules can be found here.

Building Validator

Now let’s first install the Atlassian SDK for development. The SDK offers a number of utilities to work with Atlassian products like Confluence, JIRA etc.

After the installation, we need to create a simple JIRA plugin. We can generate the artifact by using the atlas-create-jira-plugin command.

$ atlas-create-jira-plugin

The above command would ask for a number of parameters and would generate a simple maven based JIRA plugin.

There are a number of resources which have been generated like css, js etc which can be removed as they will not be required.

For the Validator we need to implement the com.opensymphony.workflow.Validator
which can perform the check. The class would ask to implement the validate method. We implemented the same in the following manner.

public void validate(Map transientVars, Map args, PropertySet propertySet) throws InvalidInputException, WorkflowException {
  RepositoryId repositoryId = new RepositoryId("sameer11sep", "Refactoring");
        Issue issue = (Issue) transientVars.get("issue");
        final Integer fixVersions = issue.getFixVersions().size();
        int associatedPRs=0;
        if (!issue.isSubTask()) {
            associatedPRs = getAssociatedPRs(repositoryId, issue, associatedPRs);
            if(associatedPRs == 0){
                throw new WorkflowException("There is no Pull Request Associated with this Task, please create a pull request before moving it to Test");
            }else if(associatedPRs < fixVersions){
                throw new WorkflowException("There should be at least one Pull Request for each Fix Version");
            }
        }
}

There framework also asks for an implementation of WorkflowPluginValidatorFactory, which is used to instantiate the validator by passing the required parameters. The framework enables the developer to ask these parameters from the user by using velocity templates.

We have not asked for any parameters so the WorkflowPluginValidatorFactory implementation and the velocity templates do not contain anything useful.

@Override
   protected void getVelocityParamsForInput(Map<String, Object> map) {

   }

   @Override
   protected void getVelocityParamsForEdit(Map<String, Object> map, AbstractDescriptor abstractDescriptor) {

   }

   @Override
   protected void getVelocityParamsForView(Map<String, Object> map, AbstractDescriptor abstractDescriptor) {

   }

   @Override
   public Map<String, ?> getDescriptorParams(Map<String, Object> map) {
       return new HashMap<String, Object>();
   }

The complete validator can be wired in atlassian-plugin.xml. The file contains the workflow-validator directive which is used to configure the validator.

<workflow-validator key="pullrequest-validator" name="Pull Request Validator"
                    class="com.xebialabs.PullRequestTaskValidatorFactory">
    <description>No Pull Request Workflow Validator</description>

    <validator-class>
        com.xebialabs.PullRequestTaskValidator
    </validator-class>

    <resource type="velocity" name="view"
              location="pullrequest-issue-validator.vm"/>
    <resource type="velocity" name="input-parameters"
              location="pullrequest-issue-validator.vm"/>
    <resource type="velocity" name="edit-parameters"
              location="pullrequest-issue-validator.vm"/>
</workflow-validator>

Now we have implemented the custom validator, all we are left is to import this validator in our JIRA installation.

The complete source of the plugin is available on Github

Deployment

The Atlassian SDK provides the atlas-run command which dowanload and runs a fresh installation of JIRA. The command would also import the validator, and install it. All we are left is to import the validator for a workflow. So select a transition and click Add Validator. Select the Pull Request Validator to enable it for the workflow and test it.

In-order to deploy the plugin on an external installation, build the complete plugin by using atlas-mvn clean install. This should generate the jar artifact which needs to be imported. To import the plugin go to the following location : JIRA Administration > Add-ons > Manage Add-ons > Upload Add-ons

Leave a Reply

Your email address will not be published. Required fields are marked *