Come for the products,
stay for the community

The Atlassian Community can help you and your team get more value out of Atlassian products and practices.

Atlassian Community about banner
4,363,484
Community Members
 
Community Events
168
Community Groups

transition issue after transition post-function

On a workflow transition, I run a ScriptRunner script. On a certain condition within this script, I want to transition this issue once again.

This is what I have:

ApplicationUser currentUser = ComponentAccessor.getJiraAuthenticationContext().loggedInUser
IssueService issueService = ComponentAccessor.getIssueService()
def transitionValidationResult = issueService.validateTransition(currentUser, issue.id, transitionId, new IssueInputParametersImpl())
def transitionResult = issueService.transition(currentUser, transitionValidationResult)

 I get no error.

And when I have a look into my issue, I see in the Issue History an entry which says the transition happened - but actually the issue is still in the "old" status.

 

I run this on a Service Desk project.

3 answers

1 accepted

0 votes
Answer accepted
Antoine Berry Community Leader Jan 24, 2020

Hi @Steffen Becker ,

That is the code I am using to transition issues : 

import com.atlassian.jira.workflow.WorkflowTransitionUtil
import com.atlassian.jira.util.JiraUtils

WorkflowTransitionUtil workflowTransitionUtil = ( WorkflowTransitionUtil ) JiraUtils.loadComponent( WorkflowTransitionUtilImpl.class );
workflowTransitionUtil.setIssue(issue);


workflowTransitionUtil.setUserkey("user_key")
def transitionId = 11

workflowTransitionUtil.setAction(transitionId);
workflowTransitionUtil.progress();

Maybe that will help.

Thank you it works!

Even though it prints me a warning message: "use ComponentManager.loadComponent"

Antoine Berry Community Leader Jan 24, 2020

Maybe this snippet is a bit outdated, but I cannot find the loadComponent method in the javadoc, and jiraUtils' one is not deprecated in the javadoc. Maybe something to keep in mind for future versions though.

If you are satisfied with the answer please mark it as accepted so it can help others too. 

Hello @Antoine Berry 

I try to do the same thing, a post function that clones the issue (Scriptrunner PF) and that will transition the cloned issue, but this snippet does not work for me.

Any idea please ?


java.lang.NullPointerException: Cannot get property 'class' on null object
at Script306.run(Script306.groovy:11)

line 11 is :

WorkflowTransitionUtil workflowTransitionUtil = ( WorkflowTransitionUtil ) JiraUtils.loadComponent(WorkflowTransitionUtilImpl.class);

Like Antoine Berry likes this

I found another snippet here : https://community.atlassian.com/t5/Jira-questions/How-to-transition-an-issue-from-a-groovy-script-in-JIRA/qaq-p/917751

I adapted to my environment :

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.bc.issue.IssueService;
import com.atlassian.jira.issue.IssueInputParametersImpl;
import org.apache.log4j.Logger;
import org.apache.log4j.Level;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.event.issue.IssueEventBundle;
import com.atlassian.jira.event.issue.IssueEventManager;
import com.atlassian.jira.event.issue.IssueEventBundleFactory;
import com.atlassian.jira.event.issue.IssueEvent;
import com.opensymphony.workflow.WorkflowContext
import com.atlassian.jira.workflow.WorkflowTransitionUtil;
import com.atlassian.jira.workflow.WorkflowTransitionUtilImpl;
import com.atlassian.jira.util.JiraUtils;
import com.opensymphony.workflow.loader.StepDescriptor;
import com.atlassian.jira.*;
import com.atlassian.jira.workflow.WorkflowManager;
import com.atlassian.jira.workflow.JiraWorkflow;
import com.opensymphony.workflow.loader.ActionDescriptor;
import com.atlassian.jira.issue.MutableIssue


import com.atlassian.jira.workflow.WorkflowTransitionUtil
import com.atlassian.jira.util.JiraUtils


def customFieldManagerT = ComponentAccessor.getCustomFieldManager();


def issueEventManager = ComponentAccessor.getIssueEventManager();
int EVENT_ID = 711
def issueManager = ComponentAccessor.getIssueManager()


WorkflowTransitionUtil workflowTransitionUtil = ( WorkflowTransitionUtil ) JiraUtils.loadComponent( WorkflowTransitionUtilImpl.class );
MutableIssue mi = issueManager.getIssueObject(issue.getKey());
workflowTransitionUtil.setIssue(mi);
workflowTransitionUtil.setAction(EVENT_ID);
//workflowTransitionUtil.validate(); i had to comment out these 2 last lines because I had errors and the clone was not created
//workflowTransitionUtil.progress();

 

Even if this time, the post function is executed without errors and does create the clone for the 1st time, the transition of the cloned issue did not change ...

 

Any idea ?

Antoine Berry Community Leader Jul 19, 2021

Hi @oneagain ,

I have found a snippet, I think it is worth a try :

import com.atlassian.jira.workflow.WorkflowTransitionUtil
import com.atlassian.jira.workflow.WorkflowTransitionUtilFactory
import com.atlassian.jira.component.ComponentAccessor

WorkflowTransitionUtil workflowTransitionUtil = ComponentAccessor.getComponent(WorkflowTransitionUtilFactory.class).create()
workflowTransitionUtil.setIssue(issue);
workflowTransitionUtil.setUserkey("user_key")

def transitionId = 11
workflowTransitionUtil.setAction(transitionId);
workflowTransitionUtil.progress();

Hello @Antoine Berry 

Thank you but just tested in the postfunction : ko

 

java.lang.IllegalArgumentException: User null doesn't have permission transition for issue null. at com.atlassian.jira.workflow.WorkflowTransitionUtilImpl.retrieveActionDescriptorWithPermissionCheck(WorkflowTransitionUtilImpl.java:142) at com.atlassian.jira.workflow.WorkflowTransitionUtilImpl.getActionDescriptor(WorkflowTransitionUtilImpl.java:133) at com.atlassian.jira.workflow.WorkflowTransitionUtilImpl.hasScreen(WorkflowTransitionUtilImpl.java:361) at com.atlassian.jira.workflow.WorkflowTransitionUtilImpl.progress(WorkflowTransitionUtilImpl.java:338) at com.atlassian.jira.workflow.WorkflowTransitionUtil$progress$2.call(Unknown Source) at Script153.run(Script153.groovy:11)

 

Fyi, the post function is the "Clones an issue, and links [ScriptRunner]" and in the additional action I added a small snippet to empty a specific field, which works, but not the part that should transition the newly cloned/created issue.

 

Based on this last error, it seems it is not able to transition a null issue, so it does not exist at this time. But how is he able to empty the field I asked ?

Like Antoine Berry likes this

I also tried this script from adaptavist : https://library.adaptavist.com/entity/transition-an-issue-using-issue-input-parameters

And it is dedicated for post function so I thought it would work.

So I removed the non necessary part to go like this :

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.ApplicationUser


final actionName = 'Done'


def issueService = ComponentAccessor.issueService

def workflowManager = ComponentAccessor.workflowManager


def workflowActionId = workflowManager.getWorkflow(issue).allActions.findByName(actionName)?.id

def issueInputParameters = issueService.newIssueInputParameters()


def transitionValidationResult = issueService.validateTransition(currentUser, issue.id, workflowActionId, issueInputParameters)
assert transitionValidationResult.valid: transitionValidationResult.errorCollection

def transitionResult = issueService.transition(currentUser, transitionValidationResult)
assert transitionResult.valid: transitionResult.errorCollection

But it failed, also with error like "null issue" :

 

java.lang.AssertionError: Errors: {}
Error Messages: [You can not transition a null issue.]. Expression: transitionValidationResult.valid
at Script189.run(Script189.groovy:19)
at com.onresolve.scriptrunner.runner.AbstractScriptRunner.runScriptAndGetContext(AbstractScriptRunner.groovy:174)
at com.onresolve.scriptrunner.runner.AbstractScriptRunner$runScriptAndGetContext$3.callCurrent(Unknown Source)
at com.onresolve.scriptrunner.runner.AbstractScriptRunner.runScriptAndGetContext(AbstractScriptRunner.groovy:293)
at com.onresolve.scriptrunner.runner.ScriptRunner$runScriptAndGetContext$9.call(Unknown Source)
at com.onresolve.scriptrunner.canned.jira.utils.ConditionUtils.doAdditional(ConditionUtils.groovy:112)
at com.onresolve.scriptrunner.canned.jira.utils.ConditionUtils$doAdditional.call(Unknown Source)
at com.onresolve.scriptrunner.workflow.DefaultWorkflowScriptExecutor.doAdditional(DefaultWorkflowScriptExecutor.groovy:29)
at com.onresolve.scriptrunner.workflow.WorkflowScriptExecutor$doAdditional$0.call(Unknown Source)
at com.onresolve.scriptrunner.canned.jira.utils.AbstractCloneIssue.cloneIssue(AbstractCloneIssue.groovy:270)
at com.onresolve.scriptrunner.canned.jira.utils.AbstractCloneIssue.execute(AbstractCloneIssue.groovy:184)
at com.onresolve.scriptrunner.canned.jira.utils.CopyIssueWithAttachments.super$4$execute(CopyIssueWithAttachments.groovy)
at com.onresolve.scriptrunner.canned.jira.utils.CopyIssueWithAttachments.execute(CopyIssueWithAttachments.groovy:29)
at com.onresolve.scriptrunner.canned.jira.workflow.postfunctions.CloneIssue.super$5$execute(CloneIssue.groovy)
at com.onresolve.scriptrunner.canned.jira.workflow.postfunctions.CloneIssue.execute(CloneIssue.groovy:158)
at com.onresolve.scriptrunner.canned.jira.workflow.postfunctions.CloneIssue$execute$0.callCurrent(Unknown Source)
at com.onresolve.scriptrunner.canned.jira.workflow.AbstractWorkflowCannedScript.execute(AbstractWorkflowCannedScript.groovy:23)
at com.onresolve.scriptrunner.canned.jira.workflow.AbstractWorkflowCannedScript$execute$2.call(Unknown Source)
at com.onresolve.scriptrunner.jira.workflow.AbstractScriptWorkflowFunction$_run_closure2.doCall(AbstractScriptWorkflowFunction.groovy:89)
at com.onresolve.scriptrunner.jira.workflow.AbstractScriptWorkflowFunction$_run_closure2.doCall(AbstractScriptWorkflowFunction.groovy)
at com.onresolve.scriptrunner.runner.diag.DiagnosticsManagerImpl$DiagnosticsExecutionHandlerImpl$_execute_closure1.doCall(DiagnosticsManagerImpl.groovy:359)
at com.onresolve.scriptrunner.runner.diag.DiagnosticsManagerImpl$DiagnosticsExecutionHandlerImpl$_execute_closure1.doCall(DiagnosticsManagerImpl.groovy)
at com.onresolve.scriptrunner.runner.ScriptExecutionRecorder.withRecording(ScriptExecutionRecorder.groovy:13)
at com.onresolve.scriptrunner.runner.ScriptExecutionRecorder$withRecording.call(Unknown Source)
at com.onresolve.scriptrunner.runner.diag.DiagnosticsManagerImpl$DiagnosticsExecutionHandlerImpl.execute(DiagnosticsManagerImpl.groovy:357)
at com.onresolve.scriptrunner.runner.diag.DiagnosticsExecutionHandler$execute$2.call(Unknown Source)
at com.onresolve.scriptrunner.jira.workflow.AbstractScriptWorkflowFunction.run(AbstractScriptWorkflowFunction.groovy:82)
Like Antoine Berry likes this

Hello, just to complete this thread, I finally ended with this :

(I was actually missing the part doAfterCreate = {} with the help of Adaptavist)

 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.ApplicationUser

doAfterCreate = { // the step you want sub-tasks to be transitioned tofinal actionName = 'Done' def issueService = ComponentAccessor.issueService def workflowManager = ComponentAccessor.workflowManagerdef workflowActionId = workflowManager.getWorkflow(issue).allActions.findByName(actionName)?.id def issueInputParameters = issueService.newIssueInputParameters() def transitionValidationResult = issueService.validateTransition(currentUser, issue.id, workflowActionId, issueInputParameters) assert transitionValidationResult.valid: transitionValidationResult.errorCollection def transitionResult = issueService.transition(currentUser, transitionValidationResult) assert transitionResult.valid: transitionResult.errorCollection }

Tried this also, it works from the SR console, for 1 existing issue (already created)

but not in a post function to be applied on the soon-to-be cloned issue ... :(

 

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.bc.issue.IssueService;
import com.atlassian.jira.issue.IssueInputParametersImpl;
import org.apache.log4j.Logger;
import org.apache.log4j.Level;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.event.issue.IssueEventBundle;
import com.atlassian.jira.event.issue.IssueEventManager;
import com.atlassian.jira.event.issue.IssueEventBundleFactory;
import com.atlassian.jira.event.issue.IssueEvent;
import com.opensymphony.workflow.WorkflowContext
import com.atlassian.jira.workflow.WorkflowTransitionUtil;
import com.atlassian.jira.workflow.WorkflowTransitionUtilImpl;
import com.atlassian.jira.util.JiraUtils;
import com.opensymphony.workflow.loader.StepDescriptor;
import com.atlassian.jira.*;
import com.atlassian.jira.workflow.WorkflowManager;
import com.atlassian.jira.workflow.JiraWorkflow;
import com.opensymphony.workflow.loader.ActionDescriptor;
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.workflow.WorkflowTransitionUtil
import com.atlassian.jira.util.JiraUtils
import com.atlassian.sal.api.user.UserManager
import com.atlassian.jira.user.util.UserManager
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.bc.issue.IssueService.TransitionValidationResult;
//final transitionId = 761
final id = 21
def issueId= "TEST-15"
//Issue issue = getIssueByID(issueId)
def issueManager = ComponentAccessor.getIssueManager()
def issue = issueManager.getIssueObject(issueId)
def boolean transitionIssue(Issue issue, int Id) {
boolean result = false;
IssueService issueService = ComponentAccessor.getIssueService();
IssueService.IssueResult transResult;
UserManager userManager = ComponentAccessor.getUserManager()
ApplicationUser user = userManager.getUserByName("valiantys")
TransitionValidationResult validationResult = issueService.validateTransition(user, issue.getId(), Id, issueService.newIssueInputParameters());
if (validationResult.isValid()) {
transResult = issueService.transition(user, validationResult);
log.warn("Transition has been made")
} else {
log.error("There was an issue with this transition : " + validationResult.getErrorCollection())
}
}

transitionIssue(issue,id)

Suggest an answer

Log in or Sign up to answer
TAGS

Atlassian Community Events