Jira7 ScriptRunner code to set Resolution

Marc Minten _EVS_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 28, 2016

In order to set the Resolution field (to "Fixed" during a transition (scriptrunner code in a script listener), in Jira6 I did

...
IssueService issueService = ComponentAccessor.getIssueService();
IssueInputParameters issueInputParameters = issueService.newIssueInputParameters();
ConstantsManager constantsManager = ComponentAccessor.getConstantsManager();
IssueConstant issueResolutionConstant = constantsManager.getIssueConstantByName(ConstantsManager.RESOLUTION_CONSTANT_TYPE, "Fixed");
issueInputParameters.setResolutionId(issueResolutionConstant.getId());
...

but scriptrunner gives me a warning (correctly) that this code is depreciated:

Script630.groovy:175
Use ConstantsManager.CONSTANT_TYPE.RESOLUTION @ line 175, column 101.

How should I write this in Jira7 ?

I tried

...
IssueService issueService = ComponentAccessor.getIssueService();
IssueInputParameters issueInputParameters = issueService.newIssueInputParameters();
ConstantsManager constantsManager = ComponentAccessor.getConstantsManager();
IssueConstant issueResolutionConstant = ConstantsManager.getIssueConstantByName(ConstantsManager.CONSTANT_TYPE.RESOLUTION, "Fixed");
issueInputParameters.setResolutionId(issueResolutionConstant.getId());
...

but then I get an error

Script631.groovy:175
[Static type checking] - Cannot find matching method 
com.atlassian.jira.config.ConstantsManager#getIssueConstantByName(com.atlassian.jira.config.ConstantsManager$CONSTANT_TYPE,
 java.lang.String). Please check if the declared type is right and if 
the method exists.
 @ line 175, column 61.

The JIRA7 API documentation doesn't help me very much neither.

What is the correct syntax ?

3 answers

1 accepted

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

3 votes
Answer accepted
Petar Petrov (Appfire)
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 29, 2016

You code does not compile because the variable case on this line is wrong:

IssueConstant issueResolutionConstant = ConstantsManager.getIssueConstantByName(ConstantsManager.CONSTANT_TYPE.RESOLUTION, "Fixed");

should be:

IssueConstant issueResolutionConstant = constantsManager.getIssueConstantByName(ConstantsManager.CONSTANT_TYPE.RESOLUTION.getType(), "Fixed");

case of constantsManager is wrong and getType() must be invoked on CONSTANT_TYPE as it is an enum.

 

Marc Minten _EVS_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 29, 2016

Yes! That's it!

Thanks a lot for your help smile

0 votes
StephenG December 5, 2016

A more complete example as per https://developer.atlassian.com/jiradev/jira-platform/guides/issues/guide-performing-issue-operations

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.bc.issue.IssueService.IssueResult
import com.atlassian.jira.bc.issue.IssueService.CreateValidationResult
import com.atlassian.jira.bc.issue.IssueService.UpdateValidationResult
import org.apache.log4j.Category

Category log = Category.getInstance("com.glintech.SetResolution")
log.setLevel(org.apache.log4j.Level.DEBUG)

def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser

IssueService issueService = ComponentAccessor.issueService 
MutableIssue issue = issueService.getIssue(user, "ADMIN-212").issue

if (!issue) {
    log.error("Could not locate issue")
    return   // Or could throw an exception
}

IssueInputParameters issueInputParameters = issueService.newIssueInputParameters();
issueInputParameters.setResolutionId("10100")  // Get from links on /secure/admin/ViewResolutions.jspa
issueInputParameters.setSkipScreenCheck(true);  // Required if the resolution field is not on the screen

UpdateValidationResult updateValidationResult = issueService.validateUpdate(user, issue.id, issueInputParameters);

if (updateValidationResult.isValid())
{
    IssueResult updateResult = issueService.update(user, updateValidationResult);
    if (updateResult.isValid()) {
        log.info("Successfully set resolution on ${issue.key}.")
    } else {
        log.error("Could not set resolution on issue: ${updateResult.errorCollection}")
    }
} else {
    log.error("Could not set resolution on issue: ${updateValidationResult.errorCollection}")
}
Deleted user October 23, 2017

Hi All,

I'm facing same kind of issue. need to update a Resolution system by moving the another issue transition. 

Example :

Issue type : Story - Resolution to be "No Fix"

Issue type : If all the liked bugs in the below Resolution field.

a.Bug A is Need More Info

b.Bug A is Cannot Reproduce, Bug B Is Won’t Fix, and Bug C is Unaffected

c.Bug A is Won’t Fix, Bug B is Won’t Fix

So far i have build the below, please add your inputs on this.

Note : Please look into below for your reference. 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue
import java.lang.String

log.setLevel(org.apache.log4j.Level.DEBUG)
import org.apache.log4j.Level
import org.apache.log4j.Logger
Logger.getLogger("com.onresolve").setLevel(Level.DEBUG)

//Define necessary managers/components
def currentUser = ComponentAccessor.getJiraAuthenticationContext().loggedInUser
def issueManager = ComponentAccessor.issueManager
def issueService = ComponentAccessor.issueService
def linkManager = ComponentAccessor.issueLinkManager
def changeHolder = new DefaultIssueChangeHolder();

//Get MutableIssue of issue in event
//def issue = issueManager.getIssueByCurrentKey(event.issue.key)

def issueInputParameters = issueService.newIssueInputParameters()
// 121 for intest to closed
def actionId = 121 // change this to the step that you want the issue to be transitioned to
// 191 for inprogress
//def inprogress_actionId = 191

def transitionValidationResult
def transitionResult
log.warn("The issue type is: " + issue.getIssueType().name)


//check that issue is a bug
if (issue.getIssueType().name == "Bug") {

//Get outward links and check for link type Blocks
linkManager.getOutwardLinks(issue.id).each{
//log.warn("Link Type: "+it.issueLinkType.name)
if(it.issueLinkType.name == "Blocks")
{
//Check that blocked issue is a Story and has a specific status
def blockedIssue = it.destinationObject

if(blockedIssue.issueType.name == "Story" && blockedIssue.status.name in ["In Test","Scanning","In Progress","In Validation"])
{
log.warn("story Resolution field value: " + blockedIssue.resolution.name)
String res = "Resolution"
log.warn("====story resolution field value === : " + blockedIssue.getFieldByName(res))
//Get the Story's linked bugs
def storyBugs = linkManager.getInwardLinks(blockedIssue.id).findAll{it.sourceObject.issueType.name == "Bug"}
def canTransition_to_closed = true
def canTransition_to_inprogress = false
def canTransition_scanning_to_intest = false

//Check that all bugs are in the status "Closed"
for(link in storyBugs)
{
if(link.issueLinkType.name == "Blocks")
{
def linkedBug = link.sourceObject
//If one of the bugs is not "In Test" then set canTransition to false and break from loop
if(!(linkedBug.status.name in ["Closed"]))
{
canTransition_to_closed = false
break
}

}
}

def canSetStoryField = false
//set story resolution field as Fixed.
for(link in storyBugs)
{
if(link.issueLinkType.name == "Blocks")
{
log.warn("Issue resolution: " + issue.resolution.name)
def linkedBug1 = link.sourceObject
//If one of the bugs is not "In Test" then set canTransition to false and break from loop
if(linkedBug1.issue.resolution.name in ["Need More Info", "Unaffected", "Cannot Reproduce", "Won't Fix"])
{
canSetStoryField = true
break
}

}
}
log.warn("Can Set Story field: " + canSetStoryField)

if(canSetStoryField){
def option = ComponentAccessor.optionsManager.getOptions(fieldConfig)?.find {it.toString() == "No Fix"}
//blockedIssue.resolution.updateValue(null, blockedissue, new ModifiedValue(blockedIssue.resolution, option),changeHolder);
//IssueConstant issueResolutionConstant = constantsManager.getIssueConstantByName(ConstantsManager.CONSTANT_TYPE.RESOLUTION.getType(), "No Fix");
}

if(!(canTransition_to_closed)){
// ================
//Check that all bugs are in the status "In Progress"
for(link in storyBugs)
{

if(link.issueLinkType.name == "Blocks")
{
def linkedBug = link.sourceObject
//If one of the bugs is not "In Validation," then set canTransition true and break from loop
if(linkedBug.status.name in ["In Test", "Pending Release", "Hotfix", "Closed", "In Progress"])
{
canTransition_to_inprogress = true 
}
else
{ 
canTransition_to_inprogress = false
break
}

}
}
// =================

//scanning to intest
for(link in storyBugs)
{
if(link.issueLinkType.name == "Blocks")
{
def linkedBug = link.sourceObject
//If one of the bugs is not "In Validation," then set canTransition true and break from loop
if(!(linkedBug.status.name in ["In Progress"]))
{
canTransition_scanning_to_intest = true 
}
else
{ 
canTransition_scanning_to_intest = false
break
}

}
}
// =================


}

//Will transition if ALL bugs were in status "Closed"
if(canTransition_to_closed || canTransition_to_inprogress)
{
if(canTransition_to_closed){
actionId = 121
log.debug("==canTransition_to_closed==")
}
if(canTransition_to_inprogress){
actionId = 191
log.debug("==canTransition_to_inprogress==")
}
if(canTransition_scanning_to_intest){
log.debug("==canTransition_scanning_to_intest==")
actionId = 211
}
//log.warn("Attmepting Transition")
//Validate the issue transition
transitionValidationResult = issueService.validateTransition(currentUser, blockedIssue.id, actionId, issueInputParameters)

if (transitionValidationResult.isValid()) {
//Attempt to transition the issue
transitionResult = issueService.transition(currentUser, transitionValidationResult)
if (transitionResult.isValid())
{ log.debug("Transitioned issue $blockedIssue.key through action $actionId") }
else
{
log.debug("Transition result is not valid")
log.debug("ErrorCollection: "+transitionValidationResult.errorCollection)
}
}
else {
log.debug("The transitionValidation is not valid")
log.debug("ErrorCollection: "+transitionValidationResult.errorCollection)
}
}// if statement closed
}
}
}
}

0 votes
Deleted user July 28, 2016

May I ask why you do not use a post function to set the resolution? That would be much easier.

Marc Minten _EVS_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 28, 2016

smile this code is part of a script listener (as indicated) with some complex logic that can not be handled in a simple post function...

Benjamin Vonlanthen July 28, 2016

Something like this could work:

import com.atlassian.jira.ComponentManager
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.customfields.manager.OptionsManager

def componentManager = ComponentManager.instance
def optionsManager = componentManager.getComponentInstanceOfType(OptionsManager.class)
MutableIssue issue = (MutableIssue) event.issue;
def cf = ComponentAccessor.customFieldManager.getCustomFieldObjects(issue).find{it.name =='Resolution'}
def fieldConfig = cf.getRelevantConfig(issue)
def option = optionsManager.getOptions(fieldConfig).find {it.value == "Fixed"}
issue.setCustomFieldValue(cf, option)
Marc Minten _EVS_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 28, 2016

Hi Benjamin, thanks for your feedback, but I think there are several problems with your solution: I think in general you cannot use the code for Custom Fields (and Options) for a system field like Resolution.

But more, I do not want just to update an issue (using a mutableIssue), but I want to change the resolution while transitioning an issue (in script). So I think I have to use the issueService and IssueInputParameters and setResolutionId construction. I only do not understand the exact syntax for the getIssueConstantByName method.

By the way, it works with the ConstantsManager.RESOLUTION_CONSTANT_TYPE code, but throws warnings about depreciated code...

Like Johannes likes this
Benjamin Vonlanthen July 28, 2016

I see and understand.  Unfortunately due to missing documentation and information, I guess it will be hard to find what you are looking for. Got the same issue for some of my scripts.

TAGS
AUG Leaders

Atlassian Community Events