Updating assignee field using Groovy script Postfunction is not persisted during state transition


   I have a requirement that i need to automatically assign new issues to users from a particular group in Round robin fashion. I have written a script for this. When i run this script using Script runner console, the field gets updated but it is not persisted in the DB despite calling mutableIssue.store. 
And when this script runs as a post function nothing happens though, in logs i see that the script successfully executed.

This is what im doing 
results holds a Jql query results 

MutableIssue mutableIssue = issueManager.getIssueObject(results.issues.get(0).id)


Screenshot of my post-functions for this transition

Screen Shot 2016-09-11 at 12.32.25 AM.png

Im stuck at this issue since a day and badly need help... 
Kindly help



2 answers

0 votes

Could you give us the  script?

I fetch the latest unassigned issue and fetch an assignee from a specific group in a round-robin like fashion.

I maintain a priority queue , prioritising assignees based on their current load , last assigned time and pick the root of the queue as my new assignee

This is my script

class Agent {
    ApplicationUser user;
    int issueCount;
    long lastAssignedTime;

def groups = ComponentAccessor.getGroupManager()  as GroupManager
def agents = groups.getUsersInGroup("Test")

def userManager = ComponentAccessor.getUserManager() as UserManager
def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class)

def PriorityQueue<Agent> agentPQ = new PriorityQueue<>(agents.size(), new Comparator<Agent>() {
    int compare(Agent o1, Agent o2) {
        if(o1.issueCount == o2.issueCount){
            if(o2.lastAssignedTime == o1.lastAssignedTime){
                return o1.user.name.compareTo(o2.user.name)
                return o1.lastAssignedTime.compareTo(o2.lastAssignedTime)
            return  o1.issueCount - o2.issueCount

def jqlQuery = "status != Closed and assignee=null ORDER BY created DESC"
def query = jqlQueryParser.parseQuery(jqlQuery)
def results = searchProvider.search(query, user, PagerFilter.getUnlimitedFilter())

assignAgent(user,results, agents, jqlQueryParser, searchProvider,agentPQ)

def assignAgent(ApplicationUser admin,SearchResults results ,Collection<ApplicationUser> agents, JqlQueryParser jqlQueryParser, SearchProvider searchProvider, PriorityQueue<Agent> agentPQ){
    def issueManager = ComponentAccessor.issueManager
    MutableIssue mutableIssue = issueManager.getIssueObject(results.issues.get(0).id)
    agents.forEach{agent ->
        log.debug("agent = " + agent)
        Agent a = new Agent()

        def count = getIssueCountForAgent(agent, jqlQueryParser , searchProvider)
        if(count > 0){
            a.lastAssignedTime = getLastAssignedTimeForAgent(agent, jqlQueryParser , searchProvider)
            log.debug("Last assigned time for agent " + agent + "= " + a.lastAssignedTime)
            a.issueCount = count

            a.lastAssignedTime = 0
            a.issueCount = 0
        a.user = agent

    log.debug("Assigning for issue = " + mutableIssue.key + " Desc = " + mutableIssue.description)

    issueManager.updateIssue(admin, mutableIssue, createIssueUpdateRequest())*/
   /* def issueService = ComponentAccessor.getIssueService()
    IssueInputParameters params = ComponentAccessor.issueService.newIssueInputParameters()
    params.assigneeId = agentPQ.peek().user.id
    def validateUpdateResult = issueService.validateUpdate(admin,mutableIssue.id,params)

        log.debug("Assignee validated = " +  validateUpdateResult.fieldValuesHolder.get("assigneeId"))
        IssueService.IssueResult serviceResult=issueService.update(admin,validateUpdateResult)
        log.debug validateUpdateResult.errorCollection.errorMessages.toString()

    def issueService = ComponentAccessor.getIssueService()
    def validateAssignResult = issueService.validateAssign(admin, mutableIssue.id, agentPQ.peek().user.name)
        log.debug("Validation failed" + validateAssignResult.errorCollection.getErrorMessages())
        log.debug("Assignee validated = " +  validateAssignResult.assigneeId)
        IssueService.IssueResult issueResult = issueService.assign(admin, validateAssignResult)


//Code to get time when the last issue was assigned to an user
def getLastAssignedTimeForAgent(ApplicationUser agent, JqlQueryParser jqlQueryParser, SearchProvider searchProvider ){
    def jqlQuery = "assignee=\""+ agent.name + "\" and status!=Closed "+  " ORDER BY created DESC"
    def query = jqlQueryParser.parseQuery(jqlQuery)
    log.debug("JQL Query = " + jqlQuery)
    def results = searchProvider.search(query, agent, PagerFilter.getUnlimitedFilter())
    if(results.issues.size() == 0)
        return 0;
        def changeLogManager = ComponentAccessor.changeHistoryManager
        def assignedAt = changeLogManager.getChangeItemsForField(results.issues.get(0),"assignee").find {
            it.toString == agent.name
        }?.getCreated() as Timestamp
            Date d = new Date(assignedAt.getTime())
            return  d.getTime()
            return  0

//Code to get issue count
def getIssueCountForAgent(ApplicationUser agent ,JqlQueryParser jqlQueryParser, SearchProvider searchProvider ){
    def jqlQuery = "assignee=\""+ agent.name + "\" and status!=Closed "+  " ORDER BY created DESC"
    def query = jqlQueryParser.parseQuery(jqlQuery)
    def results = searchProvider.search(query, agent, PagerFilter.getUnlimitedFilter())
    return results.total



Move the post-function up the list, before the system functions to save and reindex the issue

I have already experimented by placing my post function at various positions in the list . I had gathered from the api doc that the "issueService.assign" does save and re-index the issue . This was the reason i had placed my post-function at the top of the list, as you can notice that in the attachment.

After using issueService to assign, the changes do persist and user is also assigned if i run the script from the script console. But when it runs as post-function, the history and activity tabs show the assigment but the "assignee" field still shows as unassigned.. My curl call to the rest api for the issue with "expand=changelog" also has the assignment item.

So, now the only problem is that the changes made by the script running as post-function is not reflecting in the assignee field.


In your question you mentioned nothing about issueService... 

So, it turns out you are not updating the current issue, but some other issue right? In which case, yes, your code in your question is not sufficient. Using issueService.assign should be fine.

If you are actually updating the current issue just use the provided issue variable, do not redefine it or get it from the results of a query.

Have you check your atlassian-JIRA log?

Yes, sorry , i found out about the issue service after i posted my question.   
BTW , could you please review my script pasted in my comment to Nic Brough earlier

Suggest an answer

Log in or Sign up to answer
Community showcase
Published Mar 13, 2019 in Marketplace Apps

Marketplace Spotlight: Marketing apps for Confluence to keep your teams working on the same page


251 views 0 6
Read article

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