Missed Team ’24? Catch up on announcements here.

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

Groovy Post function on Create transition can't set custom field

Jon Sword
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.
October 4, 2011

Hi,

I have written a post function groovy script that I use to populate a custom field with the issue.getId() and it works quite nicely on "normal" transitions.

I now need to populate the custom field on issue creation and have added it to the "Create" transition. If my script is run before the "Creates the issue originally" post function issue.getId() is not yet populated and therefore successfully populates the custom field with "null". If I run my post function after the "Creates the issue originally" post function I can see that the issue.getId() value is determined via the catalina.out logs - but the change never appears in the custom field.

I suspect this has to do with storing the changes to the custom field (ie the database) but I am running out of ideas. Please let me know if there is any further information I can provide. The script is below:

import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.ComponentManager
import org.apache.log4j.Category
 
log = Category.getInstance("com.onresolve.jira.groovy.PRID")
log.setLevel(org.apache.log4j.Level.DEBUG)
 
CustomFieldManager customFieldManager = componentManager.getCustomFieldManager()
Issue issue  = issue
 
def cfPrId = customFieldManager.getCustomFieldObjects(issue).find {it.name == 'PR ID'}
if ( !issue.getCustomFieldValue(cfPrId) ) {
   log.debug "PR ID not set for "+issue.getKey()+" setting it to: "+issue.getId()
   issue.setCustomFieldValue(cfPrId, issue.getId().toString())
   log.debug "PR ID now set to: " +issue.getCustomFieldValue(cfPrId)
} else {
   log.debug "PR ID is already set for "+issue.getKey()+": "+issue.getCustomFieldValue(cfPrId)
}
I added the two Post Functions below in italics from the list of available Post Functions - but they appear to have had no impact (and they can not be removed once added). My current list of post functions is below:

Creates the issue originally.
— THEN
Script /localdisk/jira/current/atlassian-jira/WEB-INF/lib/PR_ID.groovy will be run.
— THEN
Stores updates to an issue (no change history is created).
— THEN
Re-index an issue to keep indexes in sync with the database.
— THEN
Fire a Issue Created event that can be processed by the listeners.

4 answers

1 accepted

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

4 votes
Answer accepted
JamieA
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.
October 5, 2011

So the problem here is that, in your post-function on the create step, you need to do two things - 1) read a CF value from the issue and 2) update a different CF value.

If you were just updating a value, you could put your function before "create the issue originally" and use:

issue.setCustomFieldValue(tgtCustomField, "some value")
But the problem then is you can't do 1).
So to do both put the function as below, and update your custom field like this:
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.util.IssueChangeHolder
... 
IssueChangeHolder changeHolder = new DefaultIssueChangeHolder();
tgtField.updateValue(null, issue, new ModifiedValue("", "some new value"), changeHolder);

The correct order for the functions is:

Creates the issue originally.
— THEN
Script /some/script.groovy will be run.
— THEN
Re-index an issue to keep indexes in sync with the database.
— THEN
Fire a Issue Created event that can be processed by the listeners.

Luis Mayora
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.
October 5, 2011

Interesting. Think groovy is saving the day for inline scripts for now!.

Jon Sword
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.
October 5, 2011

Jamie,

Thanks again! I don't know if I ever would have ever found this solution without your help.To get it working I had to add 'import com.atlassian.jira.issue.ModifiedValue'.
For anyone interested - here is the full code based on the example given in the question with Jamie's solution incorporated:

import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.util.IssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue
import org.apache.log4j.Category
  
log = Category.getInstance("com.onresolve.jira.groovy.PRID")
log.setLevel(org.apache.log4j.Level.DEBUG)
  
CustomFieldManager customFieldManager = componentManager.getCustomFieldManager()
IssueChangeHolder changeHolder = new DefaultIssueChangeHolder();
Issue issue  = issue
  
def cfPrId = customFieldManager.getCustomFieldObjects(issue).find {it.name == 'PR ID'}
if ( !issue.getCustomFieldValue(cfPrId) ) {
   log.debug "PR ID not set for "+issue.getKey()+" setting it to: "+issue.getId()
   cfPrId.updateValue(null, issue, new ModifiedValue("", issue.getId().toString()), changeHolder);
   log.debug "PR ID now set to: " +issue.getCustomFieldValue(cfPrId)
} else {
   log.debug "PR ID is already set for "+issue.getKey()+": "+issue.getCustomFieldValue(cfPrId)
}

JamieA
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.
October 5, 2011

No problem. Yep sorry, missed that import.

Sebastian Lüdtke September 10, 2013

Nice, that is working under JIRA 5.2 too. Big thx Jamie!

Linus Lindroth November 3, 2014

Hi, thanks for the examples. I need to do almost the same thing but it doen't work. The following code works fine as a custom field (if I try it on an issue) but when I try the same code as a post function it does not update the field, why? import com.atlassian.jira.issue.Issue import com.atlassian.jira.issue.fields.CustomField import com.atlassian.jira.issue.CustomFieldManager import com.atlassian.jira.ComponentManager import com.atlassian.jira.issue.util.DefaultIssueChangeHolder import com.atlassian.jira.issue.util.IssueChangeHolder import com.atlassian.jira.issue.ModifiedValue CustomFieldManager customFieldManager = componentManager.getCustomFieldManager() CustomField cf = customFieldManager.getCustomFieldObjectByName("CQ Timestamp") IssueChangeHolder changeHolder = new DefaultIssueChangeHolder(); Issue issue = issue if (issue.issueTypeObject.name == 'Epic') { cf.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(cf), ""), changeHolder); }

Linus Lindroth November 3, 2014

Note: I'm trying to clear the field in fact.

JamieA
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.
November 3, 2014

check your logs... any errors? What type of field is CQ Timestamp?

Linus Lindroth November 3, 2014

CQ Timestamp is a regular text field. Atlassian-jira.log show some errors from scriptrunner if I actually have written the wrong code but when I got it right (checking it in the scripted field) no entries in the log appear. Very strange, it just doesn't do anything. I installed the Jira Suite Utilities now and there it works without problems.

Shradha Singh February 1, 2015

Hi Jamie I am also new to groovy and calling groovy script as post functions. My problem is I have also tried this basic script but cant see any statement in log. I have checked catalina.out as well as atlassian-jira.log Can you please help.

Shradha Singh February 1, 2015

I mean how would I know that groovy script is being invoked.

JamieA
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.
February 2, 2015

Set your log levels by running the script here: https://jamieechlin.atlassian.net/wiki/display/GRV/Getting%20Help#GettingHelp-Supportrequests - you should then see log output.

1 vote
Luis Mayora
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.
October 4, 2011

My first guess is that since the issue object hasnt been created yet. You dont have access to that object. I had problems with this too in the past. Take a look at the following code and i hope it helps you.

import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.IssueManager
import com.opensymphony.workflow.InvalidInputException  
import groovy.time.*
import org.codehaus.groovy.runtime.TimeCategory
import com.atlassian.jira.issue.fields.layout.field.FieldLayoutItem
import static java.lang.Math.*

Issue issue  = issue
def result   = ""
def duration = ""

customFieldManager = ComponentManager.getInstance().getCustomFieldManager()
issueManager       = ComponentManager.getInstance().getIssueManager()

//Getting custom fields objects
cfStartDate        = issue.getCustomFieldValue( customFieldManager.getCustomFieldObjectByName("Start Date") )
cfEndDate          = issue.getCustomFieldValue( customFieldManager.getCustomFieldObjectByName("End Date") ) 
cfAllocation       = issue.getCustomFieldValue( customFieldManager.getCustomFieldObjectByName("Allocation") )
cfLOE              = customFieldManager.getCustomFieldObjectByName("Level Of Effort")


if ( (cfStartDate == null) || (cfEndDate == null ) || (cfAllocation == null ) || cfAllocation == "None" ) 
{
	invalidInputException = new InvalidInputException("'Start Date','End Date' and 'Allocation' fields are mandatory")  
}
else
{
	startDate   = cfStartDate.toString()
	endDate     = cfEndDate.toString() 
	allocation  = cfAllocation.toString()[0..-2] 

	dStartDate = new Date().parse("yyyy-MM-dd", startDate)
	dEndDate   = new Date().parse("yyyy-MM-dd", endDate)

	use(groovy.time.TimeCategory) 
	{
	    duration = dEndDate - dStartDate
	    result = Math.round( ((duration.days) * allocation.toInteger()*5/7)) / 100         //LOE Formula
	}

	//Assigning values
	issue.setCustomFieldValue(cfLOE,result.toString())
	issue.summary = "Resource Type - Assignee - LOE = " + result.toString() + " days"
 
	log.debug "NRECA LOE DEBUG: Days=> ${duration}"  + ",Allocation => ${allocation}, LOE=>"  + result
}

Jon Sword
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.
October 4, 2011

Hi Louis,

I think you are referring to the issue.getId() not being generated yet? This is true for the first scenario I described where the custom field is successfully populated with "null", however if I run my script after "Creates the issue originally" I can see in the logs that it is populated. The debugging statement:

log.debug "PR ID now set to: " +issue.getCustomFieldValue(cfPrId)

even shows that not only is issue.getId() working but the custom field is actually set to the right value - BUT it never gets fed back to the database or appears in the web interface.

Boil it down and your code is almost identical to mine - Do you run your script on the Create transition?

0 votes
Tom Lister January 18, 2017

Hi

Our solution...

we have created a "Set Defaults" transition on the initial status with all the field adjustment post functions - mostly build with Adaptavist ScriptRunner

At the end of the the Create post functions we use JIRA Misc. Workflow Extensions to fire the "Set Defaults" transition automatically. This now has access to all the fields and we can manipuate anything we want.

0 votes
Martin Bayreuther October 4, 2011

Another potential problem I frequently run into is the fact that fields are not editable on the corresponding screen. Due to the fact that custom fields are not on the edit screen, the setCustomFieldValue fails silently.

Best regards

Maba

Jon Sword
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.
October 4, 2011

Would the setCustomFieldValue failing not be be reflected in the output from the debugging line immediately following?

log.debug "PR ID now set to: " +issue.getCustomFieldValue(cfPrId)

JamieA
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.
October 4, 2011

I can't see that this could be the issue. Yes it's an issue when using WorkflowTransitionUtil, but not when setting a customfield value through the API. Screens just don't come in to play here.

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

TAGS
AUG Leaders

Atlassian Community Events