Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

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
Community showcase
Published in Apps & Integrations

🍻🍂Apptoberfest Update: Upcoming Virtual Events 🎉

Hello Community! I hope you've been enjoying the 🍂Apptoberfestivities🍂 (I know I have!) The event is heating up next week with a series of virtual events that we're calling the 🍻🍂Partner App ...

392 views 3 17
Read article

Community Events

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

Find an event

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

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you