How to transition an issue when a label is added? Edited

Hello, 

I have been searching the internet for a solution to a problem I am trying to tackle. I have come across a lot of different sites and input but nothing seems to really help me.

First, let me explain my problem at a high level. I have a team of developers that prefer to use GitLab to manage issues but I have a team of testers and product managers that prefer to manage issues in JIRA. I like to believe in win-win scenarios so I said "Why not both?" 

I found a tool from unito.io that will sync issues between Gitlab and JIRA but the problem I am facing is that Gitlab doesn't have a concept of a workflow or statuses other than open/close. Gitlab primarily uses labels. What I am thinking about doing is: If a JIRA issue has been updated with a label==foo then transition JIRA issue from phase 1 to phase 2.

I have found that my JIRA instance (it is the enterprise edition that my company maintains, not the cloud edition) has the Script Runner plug in enabled. Based on documentation I have found on the web I believe it is possible to create my own groovy class as a custom listener and configure it to happen on issueUpdate in my specific project. This is perfect. I can write some code that will check to see what the update was and what phase it is in. If it was a label that was added I can check to see if it is the label I am interested in and if it is and the issue is in the correct phase I can issue a command to transition the issue to the correct phase.

The problem is the documentation is really hard for a newbie like me to understand. I am trying to read enough of https://scriptrunner.adaptavist.com to understand what to do but I am not finding what I need. The docs at https://docs.atlassian.com/software/jira/docs/api/7.3.7/ are massive and a newbie has no way to know what to look for. This site: http://igorpopov.io/2014/11/24/rocking-with-jira-script-runner/ makes it seem like I have to do a lot of stuff just to write this small script (it makes me think I have to compile the JIRA code? Woah!)

I am look for a simple class that I can add to my custom script listener, then I edit a bug, I check to see if my script made the changes I thought it would based on my code and if it works I add more code and if it doesn't I troubleshoot my code. Repeat.

I wrote a tome here. I am really hopeful that someone will read this question and

a) help me out with some sample code

b) explain that what I want to do is not possible and tell me why

c) offer up some alternative solutions to my problem.

 

Thank you Atlassian Community, you are great!

3 answers

1 accepted

This widget could not be displayed.
Gaston Valente Community Champion Dec 13, 2017

Troy,

You can achieve this with an script listener:

  1. You need to create an script listener to capture the ISSUE_UPDATED event
  2. In the code you check for a label placed by your other app
  3. You execute the transition using this code sample:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.jql.builder.JqlQueryBuilder
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.search.SearchProvider
import com.atlassian.jira.issue.search.SearchResults
import com.atlassian.query.Query
import com.atlassian.query.order.SortOrder
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.config.SubTaskManager
import com.atlassian.jira.issue.index.IssueIndexingService
import com.atlassian.jira.util.ImportUtils
import org.apache.log4j.Logger
import org.apache.log4j.Level

def issueService = ComponentAccessor.getIssueService()
def issueInputParameters = issueService.newIssueInputParameters()


def transitionValidationResult = issueService.validateTransition("user", issue.getId(), "transitionId", issueInputParameters);
if (!transitionValidationResult.isValid())
{
String result = transitionValidationResult.getErrorCollection()
throw new Exception(result);
}

def transitionResult = issueService.transition(runAs, transitionValidationResult)

if (!transitionResult.isValid())
{
String result = transitionResult.getErrorCollection()
throw new Exception(result)
}

4. If everything is ok you need to clean the label field to prevent a loop

OMG, @Gaston Valente thanks for the response!! I am going to try this today and see if I can get it to work.

@Gaston Valente, I copied and pasted your code into my script console and I get some errors.

For this line of code:

def transitionValidationResult = issueService.validateTransition("user", issue.getId(), "transitionId", issueInputParameters);

I get the following errors from the static type checking inside the browser:

The variable [issue] is undeclared.

Since I am so new to this groovy programming I am not sure how this is supposed to be but I don't see

def issue = [something here]

anywhere in your code where you define the variable. Does that need to be added? If so what does it need to be assigned to? If not is it supposed to be assigned automatically based on one of you imports? I see 

import com.atlassian.jira.issue.Issue

But I don't see that assigned to a variable.

and for that same line of code another error from the static type checking:

Cannot find matching method for com.atlassian.jira.bc.issue.IssueService#validateTransition...
Please check if the declared type is right and if the method exists.

I have even more error but I think they are all related.

In case it matters the version of JIRA I am on is  v7.3.7#73018-sha1:17f7a2e. Also, the version of Adaptavist ScriptRunner for JIRA is 5.1.6.

Gaston Valente Community Champion Dec 13, 2017

Troy,

You should obtain the issue from the event or by querying.

Check for the signature of the method validateTransition

you need to replace user and transitionId with the correct values:

users needs to be an instance of ApplicationUser

transitionId is an int, the id of the transition you need to execute

I figured out how to get the issue, from the event object. I am now getting the 

def transitionValidationResult = issueService.validateTransition(user, event.issue.getNumber(), transitionId, issueInputParameters)

to work. The problem is that the code throws and exception:

java.lang.Exception: Errors: {}
Error Messages: [You can not transition a null issue.]

 So this says to me that I have to do something other than create an empty issueInputParameters. I checked the documention for issueService.newIssueInputParameters() and it doesn't do a good job of explaining what I need to do. How do I init this issueInputParameters object for my needs?

Steven Behnke Community Champion Dec 14, 2017

Don't use event.issue.getNumber, use event.issue.id

This widget could not be displayed.
Gaston Valente Community Champion Dec 14, 2017

Hi, as Steve pointed out, you need to use getId

let us know if you have any another issue

sorry for the delay

Hey, that worked! I tried event.issue (without the '.id') and I was getting an error about the type not matching. 

This widget could not be displayed.

I have working code! For those of you that don't like spurious (unneeded) import statements you don't need any of the imports that Gaston has in his code. 

Here is what my code looks like:

import com.atlassian.jira.component.ComponentAccessor

// Get the instance of the IssueService because IssueService is the class
// that we use to perform "transition" operations in JIRA with Issues.
def issueService = ComponentAccessor.getIssueService()

// Initiate a new IssueInputParameters object with no initial values
def issueInputParameters = issueService.newIssueInputParameters()

// Define the user that will be making the transition
def user = ComponentAccessor.jiraAuthenticationContext.getLoggedInUser()

// This is the ID of the transition that should happen. This can be seen as the transitions (id) when you edit workflow
// 91 is the id for "Reopen" since I am testing with a closed issue
def transitionId = 91

// This is the ID of the issue that triggered the event. This is the issue we will modify if applicable.
def issueId = event.issue.id

// To see if you have valid values log it
log.debug issueId

// OK, lets see if we have valid transition info
def transitionValidationResult = issueService.validateTransition(user, issueId, transitionId, issueInputParameters)

// Throw an exception if we didn't get what we wanted
if (!transitionValidationResult.isValid())
{
String result = transitionValidationResult.getErrorCollection()
throw new Exception(result);
}

// If we made it this far then we have the right values, let's transition the issue
def transitionResult = issueService.transition(user, transitionValidationResult)

if (!transitionResult.isValid())
{
String result = transitionResult.getErrorCollection()
throw new Exception(result)
}

Suggest an answer

Log in or Sign up to answer
Atlassian Summit 2018

Meet the community IRL

Atlassian Summit is an excellent opportunity for in-person support, training, and networking.

Learn more
Community showcase
Posted Wednesday in New to Jira

Are you planning to trial, or are currently trialling Jira Software? - We want to talk to you!

Hello! I'm Rayen, a product manager at Atlassian. My team and I are working hard to improve the trial experience for Jira Software Cloud. We are interested in   talking to 20 people planning t...

131 views 2 0
Join discussion

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you