You're on your way to the next level! Join the Kudos program to earn points and save your progress.
Level 1: Seed
25 / 150 points
Next: Root
1 badge earned
Challenges come and go, but your rewards stay with you. Do more to earn more!
What goes around comes around! Share the love by gifting kudos to your peers.
Keep earning points to reach the top of the leaderboard. It resets every quarter so you always have a chance!
Join now to unlock these features and more
The Atlassian Community can help you and your team get more value out of Atlassian products and practices.
Hello community!
I try to make transition in scriptrunner custom listener, but I have
It seems that you have tried to perform a workflow operation (251) that is not valid for the current state of this issue (XXXXXX). The likely cause is that somebody has changed the issue recently, please look at the issue history for details.
Event is Issue Created
I check workflow and there is a transition with id 251 (which i need)
My custom listener
if (summary.contains("Invalid item requisites")){
IssueService issueService = ComponentAccessor.getIssueService()
def issueInputParameters = issueService.newIssueInputParameters()
def user = ComponentAccessor.getUserManager().getUserByName('admin')
def transitionValidationResult = issueService.validateTransition(user, issue.id, 251, issueInputParameters)
if (transitionValidationResult.isValid()) {
def transitionResult = issueService.transition(user, transitionValidationResult)
if (transitionResult.isValid()){
log.warn("Transitioned issue ${event.issue.key}")
} else {
log.warn("Transition result is not valid")
log.warn(transitionResult.errorCollection)
}
} else {
log.warn("The transitionValidation is not valid")
log.warn(transitionValidationResult.errorCollection)
}
}
But when I try to make that transition like that
Everything works fine.
Why I can't make transition in custom listener?
I've found solution. Like @Alexey Matveev _Appfire_ answered here I've made different thread to move the issue to a different status and it works, but I really don't understand why I need another one thread
A post-function script:
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueInputParameters
import org.apache.log4j.Logger
def user = ComponentAccessor.getUserManager().getUserByName('admin')
Thread newThread = new Thread(new MyThread(user, issue, transitionId, log))
newThread.start()
public class MyThread implements Runnable{
private Logger logger
private ApplicationUser threadUser
private Issue issue
private int transitionId
public MyThread(final ApplicationUser user,
final Issue issue, int transitionId, Logger logger){
this.threadUser = user
this.issue = issue
this.transitionId = transitionId
this.logger = logger
}
public void run(){
logger.info("Run method in MyThread")
MyThread.sleep(500) // delay for indexing
IssueService issueService = ComponentAccessor.getIssueService()
MutableIssue currentIssue = ComponentAccessor.getIssueManager().getIssueObject(issue.getId())
IssueInputParameters issueInputParameters = issueService.newIssueInputParameters()
issueInputParameters.setSkipScreenCheck(true)
def transitionValidationResult = issueService.validateTransition(this.threadUser, currentIssue.getId(), this.transitionId, issueInputParameters)
if (transitionValidationResult.isValid()) {
logger.info("transitionValidationResult is valid")
def transitionResult = issueService.transition(this.threadUser, transitionValidationResult)
if (transitionResult.isValid()){
logger.info("Transitioned issue ${issue.key} through action ${transitionId}")
} else {
logger.warn("Transition result is not valid")
logger.warn("${transitionResult.errorCollection}")
}
} else {
logger.warn("The transitionValidation is not valid")
logger.warn("${transitionValidationResult.errorCollection}")
}
}
}
Hi @aas ,
your code seems correct! Two simple questions :
Hope this helps,
Fabio
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Fabio Racobaldo _Herzum_ ,
1. Do you mean that I need perform a reindexing somewhere in script listener? Smth like this?
boolean wasIndexing = ImportUtils.isIndexIssues()
ImportUtils.setIndexIssues(true)
ComponentAccessor.getComponent(IssueIndexingService.class).reIndex(issue)
ImportUtils.setIndexIssues(wasIndexing)
I've tried to add this code in custom listener before making transition but no luck.
2. User has all permissions. I can make transition in created issue manually via web interface.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @aas ,
1. Please complete a manual reindex at project administartion level in order to be sure that issue is in the correct status.
2. Please check if that transition has some conditions that impact your code.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Fabio Racobaldo _Herzum_ ,
1. When you tell about manuall reindex you mean that?
I've done it, nothing has changed (
2. There're no any conditions that impact my code.
The only way my code works is using post-function. I've added another one transition
And added Custom script post-function there. In that way script works and issue makes transition.
May be there no any available transition while issue creation so it tells that transition is not valid? I suppose issue must be created and only after that we can make transition or the logic is wrong? But how works fast-track transitions?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Please could you share your workflow in text view?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.issue.customfields.option.Option
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.workflow.WorkflowManager
import com.atlassian.jira.workflow.JiraWorkflow
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.index.IssueIndexingService
import com.atlassian.jira.util.ImportUtils
def eventTypeManager = ComponentAccessor.getEventTypeManager()
def eventTypeName = eventTypeManager.getEventType(event.eventTypeId).getName()
log.warn("Event " + eventTypeName)
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
log.warn("User " + user.name)
def issueManager = ComponentAccessor.issueManager
def issue = issueManager.getIssueObject(event.issue.key)
log.warn("Issue " + issue.key)
def summary = issue.getSummary()
if (summary.contains("Somr string")){
def cf= ComponentAccessor.getCustomFieldManager().getCustomFieldObject("customfield_33320")
// find 1 level option
def fieldConfig = marsrut.getRelevantConfig(issue)
def op_1 = ComponentAccessor.optionsManager.getOptions(fieldConfig)?.find { it.toString() == "Option name"}
// find 2 level option
def op_2 = op_1.getChildOptions().find{it.value == "Option name"}
List<Option> list = new ArrayList()
list.add(op_1)
list.add(op_2)
cf.updateValue(null, event.issue, new ModifiedValue(null, list), new DefaultIssueChangeHolder())
reIndexIssue(issue)
validateAndTransition(251, issue)
} else {
log.warn("summary not contains \"Invalid item requisites\"")
}
def reIndexIssue(Issue issue){
//Re-index the issue after update
log.warn("Try index issue...")
boolean wasIndexing = ImportUtils.isIndexIssues()
log.warn("wasIndexing " + wasIndexing)
ImportUtils.setIndexIssues(true)
ComponentAccessor.getComponent(IssueIndexingService.class).reIndex(issue)
ImportUtils.setIndexIssues(wasIndexing)
}
def validateAndTransition(int transitionId, Issue issue){
IssueService issueService = ComponentAccessor.getIssueService()
def issueInputParameters = issueService.newIssueInputParameters()
def user = ComponentAccessor.getUserManager().getUserByName('username')
def transitionValidationResult = issueService.validateTransition(user, issue.id as long, transitionId, issueInputParameters)
if (transitionValidationResult.isValid()) {
log.warn("transitionValidationResult is valid")
def transitionResult = issueService.transition(event.user, transitionValidationResult)
if (transitionResult.isValid()){
log.warn("Transitioned issue ${event.issue.key} through action ${transitionId}")
} else {
log.warn("Transition result is not valid")
log.warn(transitionResult.errorCollection)
}
} else {
log.warn("The transitionValidation is not valid")
log.warn(transitionValidationResult.errorCollection)
log.warn(transitionValidationResult.toString())
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @aas ,
I don't understand the following portion of code
cf.updateValue(null, event.issue, new ModifiedValue(null, list), new DefaultIssueChangeHolder())
If you want to update some cf within your issue you should use the updateIssue method provided by IssueManager https://docs.atlassian.com/software/jira/docs/api/8.19.0/com/atlassian/jira/issue/IssueManager.html#updateIssue-com.atlassian.jira.user.ApplicationUser-com.atlassian.jira.issue.MutableIssue-com.atlassian.jira.issue.UpdateIssueRequest-
Could you try to test your listener without the following lines?
def cf= ComponentAccessor.getCustomFieldManager().getCustomFieldObject("customfield_33320")
// find 1 level option
def fieldConfig = marsrut.getRelevantConfig(issue)
def op_1 = ComponentAccessor.optionsManager.getOptions(fieldConfig)?.find { it.toString() == "Option name"}
// find 2 level option
def op_2 = op_1.getChildOptions().find{it.value == "Option name"}
List<Option> list = new ArrayList()
list.add(op_1)
list.add(op_2)
cf.updateValue(null, event.issue, new ModifiedValue(null, list), new DefaultIssueChangeHolder())
reIndexIssue(issue)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Fabio Racobaldo _Herzum_ ,
What's wrong with that code? It's simple update of custom field
cf.updateValue(null, event.issue, new ModifiedValue(null, list), new DefaultIssueChangeHolder())
There're many examples of using it:
https://library.adaptavist.com/entity/update-the-value-of-a-custom-field-using-a-listener
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Yes, I've tried, has the same error
It seems that you have tried to perform a workflow operation (Assigned to FD) that is not valid for the current state of this issue (**-*****). The likely cause is that somebody has changed the issue recently, please look at the issue history for details.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Could you try to update the step name from "New issue" to "Created" so it matches the associated status?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @Fabio Racobaldo _Herzum_
Changing step name hasn't helped, unfortunately.
I supoose there are no transition with id 251 in the moment of issue craeation
Fast Track Transition, I think, firstly create issue and only after that (when issue in Created status) try to make transition
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @aas ,
I don't figure out the reason. Listener works after creation because it start after that create event is fired as last post function in creation. Based on that, when listener works, issue should be created and in correct status.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.