Groovy Scripted field to display result of JIRA JQL - groovy

I want to get some pointer to write a simple JIRA groovy scripted field – the input is a JQL and the result is the result of the JQL.
For example, if the JQL is "project = RS and fixVersion = 5.0", it will go ahead a list the issues returned from this JQL in the custom field display.

First I created a JIRA field called "Fixed Issues JQL", which supposed I will enter the value of "project = VOL and fixVersion = 6.0" in the JIRA.
Then I create a second JIRA custom field , a groovy scripted field called "Fixed Issues List", which contain the following code:
import com.atlassian.crowd.embedded.api.User
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.user.util.UserUtil
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.customfields.manager.OptionsManager
SearchService searchService = ComponentAccessor.getComponent(SearchService.class)
UserUtil userUtil = ComponentAccessor.getUserUtil()
User user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
IssueManager issueManager = ComponentAccessor.getIssueManager()
def componentManager = ComponentManager.instance
def optionsManager = ComponentManager.getComponentInstanceOfType(OptionsManager.class)
def customFieldManager = componentManager.getCustomFieldManager()
def cf = customFieldManager.getCustomFieldObjectByName("Fixed Issues JQL")
def myJQL = issue.getCustomFieldValue(cf) // has a value such as "project = VOL and fixVersion = 6.0"
if (!user) {
user = userUtil.getUserObject('kwhite')
}
List<Issue> issues = null
SearchService.ParseResult parseResult = searchService.parseQuery(user, myJQL)
if (parseResult.isValid()) {
def searchResult = searchService.search(user, parseResult.getQuery(), PagerFilter.getUnlimitedFilter())
// Transform issues from DocumentIssueImpl to the "pure" form IssueImpl (some methods don't work with DocumentIssueImps)
issues = searchResult.issues.collect {issueManager.getIssueObject(it.id)}
} else {
log.error("Invalid JQL: " + myJQL);
}

Related

How to update the comment of an issue in Jira

I am trying to concatenate some text to a comment entered by the user. How can I do that? Here is my code below. I need to access the comment input by the user and then add new text to it. How can I access this? I am using Jira ScriptRunner custom postfunction to be executed when the user clicks on a transition.
import com.atlassian.jira.issue.comments.Comment
import com.atlassian.jira.workflow.JiraWorkflow
import com.atlassian.jira.workflow.WorkflowManager
import org.apache.log4j.Logger
import com.atlassian.jira.component.ComponentAccessor
def log = Logger.getLogger("atlassian-jira.log")
log.warn("This is the last action ")
WorkflowManager workflowManager = ComponentAccessor.getWorkflowManager();
JiraWorkflow workflow = workflowManager.getWorkflow(issue);
List <Object> actions = workflow.getLinkedStep(issue.getStatus()).getActions();
def wfd = workflow.getDescriptor()
def actionName = wfd.getAction(transientVars["actionId"] as int).getName();
log.warn("This is the last action "+actionName)
def comment= "+++ added via workflow action "+"\""+actionName+"\"+++"
Here is the code transientVars is the way to go.
import com.atlassian.jira.issue.comments.Comment
import com.atlassian.jira.workflow.JiraWorkflow
import com.atlassian.jira.workflow.WorkflowManager
import org.apache.log4j.Logger
import com.atlassian.jira.component.ComponentAccessor
def log = Logger.getLogger("atlassian-jira.log")
log.warn("This is the last action ")
WorkflowManager workflowManager = ComponentAccessor.getWorkflowManager();
JiraWorkflow workflow = workflowManager.getWorkflow(issue);
def wfd = workflow.getDescriptor()
def actionName = wfd.getAction(transientVars["actionId"] as int).getName();
log.warn("This is the last action "+actionName)
def comment= "+++ added via workflow action "+"\""+actionName+"\"+++"
String content = transientVars["comment"] +"\n"+comment as String
log.warn("CONTENT"+ content)
transientVars["comment"]= content

Not able to add a project ID/name to a list in Jira/Groovy/Scriptrunner

The following question I present is the following: I'm doing a code that is been tested in the Scriptrunner console and tried into Jira. What I want to reach is the following: I have an issue in any project, at any moment a workflow transition allows me to copy the current issue and all the linked issues in a new project.
The cfProjectPicker is a custom field Project Picker that allows me to select a project.
What I'm having trouble right now on the code is the following:
1- projectKey is returning null valor but projectPicker is returning the correct project selected in the custom field.
2- createNewIssue is not allowing me to recognize the "params" field as a mutable issue, and it is a mutable (if I replace with newIssue it does take it)
3- the list "issuesCopied" is not allowing me to issuesCopied.id.toString() but I'm guessing is giving error due to the point 2.
Any help regarding the matter would be much appreciated because I'm not understanding what I'm doing wrong at moment.
def issueMgr = ComponentAccessor.getIssueManager();
def issueTypeSchemeManager = ComponentAccessor.getIssueTypeSchemeManager()
def customFieldManager = ComponentAccessor.getCustomFieldManager();
def projectMgr = ComponentAccessor.getProjectManager();
def groupManager = ComponentAccessor.getGroupManager();
def issueFactory = ComponentAccessor.getIssueFactory();
IssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager();
def cfProjectPicker = customFieldManager.getCustomFieldObjectByName("Seleccionar Proyecto") //cf project picker
def issue = issueMgr.getIssueObject("MART1-1")
ApplicationUser user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser() //User Admin
ApplicationUser currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def currentIssue = issueFactory.getIssue()
//def issue = issueMgr.getIssueObject()
def newIssue = issueFactory.getIssue()
def exit = false
// Array list of the issues created to save them
List<String> issuesCopied = new ArrayList<>();
// ***** CREATE ISSUE *****
if (issuesCopied.isEmpty()){
String projectPicker = issue.getCustomFieldValue(cfProjectPicker)
log.error("Gengar")
log.error(projectPicker)
def projectKey = projectMgr.getProjectObjByKey(projectPicker)
log.error(projectKey)
newIssue.setProjectObject(projectKey)
newIssue.setIssueType(issue.getIssueType())
newIssue.setSummary(issue.getSummary())
newIssue.setDescription(issue.getDescription())
newIssue.setReporter(currentUser)
def params = ["issue":newIssue]
log.error(params)
def createNewIssue = issueMgr.createIssueObject(user,params);
issuesCopied.add(createNewIssue.id.toString())
}

Groovy + Insight (Jira) Exception on split method

I'm trying to create a script with Groovy to be able to auto affect a Jira issue to a specific object in Insight (Add-on of Jira).
Actually, I need to split a value. The value is "2629351(AFAW16-FS01.francois.int)", I want to have AFAW16-FS01.francois.int part only. I can do it if I apply directly the method to the text but it's not working with a string.
Here is my code :
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.fields.CustomField
import com.riadalabs.jira.plugins.insight.services.model.CommentBean;
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.event.type.EventDispatchOption
import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade
import com.riadalabs.jira.plugins.insight.services.model.ObjectAttributeBean
import com.riadalabs.jira.plugins.insight.services.model.ObjectBean
Class objectFacadeClass = ComponentAccessor.getPluginAccessor().getClassLoader().findClass("com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade");
def objectFacade = ComponentAccessor.getOSGiComponentInstanceOfType(objectFacadeClass);
Class iqlFacadeClass = ComponentAccessor.getPluginAccessor().getClassLoader().findClass("com.riadalabs.jira.plugins.insight.channel.external.api.facade.IQLFacade");
def iqlFacade = ComponentAccessor.getOSGiComponentInstanceOfType(iqlFacadeClass);
def objects = iqlFacade.findObjectsByIQLAndSchema(10,"objectTypeId = 2443");
//def test = "AF-172738"
//def ObjectInsightBean = objectFacade.loadObjectBean(test)
//log.warn("ObjectInsightBean " + ObjectInsightBean)
def n = 0
(objects).each {
CurrentObject = objects[n]
def FQDNValue = objectFacade.loadObjectAttributeBean(CurrentObject.getId(),47464).getObjectAttributeValueBeans()[0]; //Load Attribute Value
//log.warn("Server " + objects[n])
//log.warn("FQDNValue " + FQDNValue)
//FQDNValueSTR = FQDNValue.ToString()
log.warn("FQDNValue brut" + FQDNValue)
def values = '2629351(AFAW16-FS01.francois.int)'.split("\\("); //WORKS !
def FQDNSplit = FQDNValue.split("\\("); // NOT WORKS
def Value1 = values[1]
def Value2 = Value1.substring(0, Value1.length() - 1);
//log.warn("Values " + Value2)
//result = (issue.getSummary()) //Show subject
//log.warn("result " + result)
n ++
}
FQDNSplit contain "2629351(AFAW16-FS01.francois.int)" but i have the following error:
class com.riadalabs.jira.plugins.insight.common.exception.GroovyInsightException
GroovyInsightException: No signature of method: com.riadalabs.jira.plugins.insight.services.model.ObjectAttributeValueBean.split() is applicable for argument types: (java.lang.String) values: [\(] Possible solutions: split(groovy.lang.Closure), wait(), wait(long), getAt(java.lang.String), print(java.lang.Object), sprintf(java.lang.String, java.lang.Object)'
Any idea? Thank you!!
The simple comman extracts the substring that you want:
String res = '2629351(AFAW16-FS01.francois.int)'.replaceFirst( /\d\(([^\(\)]+)\)/, '$1' )
assert res == 'AFAW16-FS01.francois.int'
Also you should stick with Java Naming Conventions, and DO NOT name variables starting with capital letters.
Can you describe an easy way to convert FQDNValue to string?
I don't found the good method on Google. Seems working with class but i don't understand the good way.
It looks like you're trying to use String operations on something that isn't a string. If you convert the value into a String then this code will work:
FQDNValue.replaceAll(/.*\((.*)\)/,'$1')
You need a method to get the string value.
e.g.
FQDNValue.getTextValue().replaceAll(/.*\((.*)\)/,'$1')
Your updated code might look like this:
def FQDNValue =
objectFacade.loadObjectAttributeBean(
CurrentObject.getId(),47464
).getObjectAttributeValueBeans()[0].getTextValue()
assert FQDNValue == '2629351(AFAW16-FS01.francois.int)'
println "old: $FQDNValue"
def newValue = FQDNValue.replaceAll(/.*\((.*)\)/,'$1')
println "new: $newValue"
With this output:
old: 2629351(AFAW16-FS01.francois.int)
new: AFAW16-FS01.francois.int
This should work as ObjectAttributeValueBean has a getTextValue method.
Use getTextValue
ObjectAttributeValueBean has a getTextValue method, that returns a String:
public String getTextValue()
i'm go on in the script and found the good solution for the split. Here what i using (i renamed string to have a better understanding)
To convert to string i simply do it (haha)
def fqdn_string = fqdnvalue.toString()
Now i'm blocked to the last part of the code :( maybe you can understand why i can't update the issue
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.fields.CustomField
import com.riadalabs.jira.plugins.insight.services.model.CommentBean;
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.event.type.EventDispatchOption
import com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade
import com.riadalabs.jira.plugins.insight.services.model.ObjectAttributeBean
import com.riadalabs.jira.plugins.insight.services.model.ObjectBean
import groovy.transform.ToString
Class objectFacadeClass = ComponentAccessor.getPluginAccessor().getClassLoader().findClass("com.riadalabs.jira.plugins.insight.channel.external.api.facade.ObjectFacade");
def objectFacade = ComponentAccessor.getOSGiComponentInstanceOfType(objectFacadeClass);
//CustomField jiraCustomField = ComponentAccessor.getCustomFieldManager().getCustomFieldObject(12124);
CustomField valueCF = ComponentAccessor.getCustomFieldManager().getCustomFieldObject(12124);
CustomField insightCF = ComponentAccessor.getCustomFieldManager().getCustomFieldObject(12124);
Class iqlFacadeClass = ComponentAccessor.getPluginAccessor().getClassLoader().findClass("com.riadalabs.jira.plugins.insight.channel.external.api.facade.IQLFacade");
def iqlFacade = ComponentAccessor.getOSGiComponentInstanceOfType(iqlFacadeClass);
def objects = iqlFacade.findObjectsByIQLAndSchema(10,"objectTypeId = 2443");
//def test = "AF-172738"
//def ObjectInsightBean = objectFacade.loadObjectBean(test)
//log.warn("ObjectInsightBean " + ObjectInsightBean)
def n = 0
(objects).each {
CurrentObject = objects[n]
def fqdnvalue = objectFacade.loadObjectAttributeBean(CurrentObject.getId(),47464).getObjectAttributeValueBeans()[0]; //Load Attribute Value
def fqdn_string = fqdnvalue.toString()
def fqdn_string_split = fqdn_string.split("\\(");
def fqdn_string_split_1 = fqdn_string_split[1]
def fqdn_string_split_2 = fqdn_string_split_1.substring(0, fqdn_string_split_1.length() - 2);
result = (issue.getSummary().contains(fqdn_string_split_2)) // if the value fqdn_string_split_2 present in the summary => result = true
if (result==true){
log.info("Statement " + "True" + CurrentObject);
MutableIssue mi = (MutableIssue) issue;
mi.setCustomFieldValue(insightCF, objects[n]); // => Work if i replace objects[n] by objects
ComponentAccessor.getIssueManager().updateIssue(currentUser, mi, EventDispatchOption.DO_NOT_DISPATCH, false); // Error GroovyInsightException: com.riadalabs.jira.plugins.insight.services.model.ObjectBean cannot be cast to java.util.Collection'
}
log.info("fqdn_string_split_2 " + fqdn_string_split_2)
log.info("Result " + result)
n ++
return result;
}
You can access the parts through existing methods
def FQDNValue = objectFacade.loadObjectAttributeBean(CurrentObject.getId(),47464).getObjectAttributeValueBeans()[0]; //Load Attribute Value
def id = FQDNValue.getId(); // "2629351"
def value = FQDNValue.getValue(); // "AFAW16-FS01.francois.int"

How to get a list of modified fields with ScriptRunner on IssueUpdated event?

In my Jira instance, I created a Script Listener for the IssueUpdated event using the ScriptRunner add-on and I'm trying to get a list of the changed fields. For some reason the method getModifiedFields() is coming empty, somebody can help me to fix that?
import com.atlassian.jira.issue.managers.DefaultIssueManager
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.ModifiedValue
log.setLevel(org.apache.log4j.Level.DEBUG)
Issue mainIssue = event.issue
MutableIssue mutableIssue = (MutableIssue)mainIssue
def modFields = mutableIssue.getModifiedFields()
log.debug("Modified fields count: "+modFields.count) // null
log.debug("Modified fields: "+modFields.toString()) // [:]
log.debug("Original Ticket: "+mainIssue.key) // EPS-39
After turning google upside down I've found the answer to my question. More background here: my final goal is to update a target Jira ticket (in another project) with whatever was changed in the main ticket. I have a custom field that contains the original ticket key, so I can track it down (ex: ticket "PRJ-1" -> "Original Ticket": "TRG-1"). To do this I'm going to ScriptRunner -> Script listeners -> custom listener and adding an "Issue Updated" listener.
I'm still stuck in the part where I have a custom label field as you can see by the comments in the end of the code, but at least I could manage to get a list of the changed fields in my main ticket.
import com.atlassian.jira.issue.managers.DefaultIssueManager
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.ModifiedValue
import org.ofbiz.core.entity.GenericValue
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.bc.issue.DefaultIssueService
log.setLevel(org.apache.log4j.Level.DEBUG)
def customFieldManager = ComponentAccessor.getCustomFieldManager()
Issue mainIssue = event.issue
// Get Custom Field Object "Original Ticket"
def originalTicket = customFieldManager.getCustomFieldObjectByName("Original Ticket")
// Get Value of the Custom Field Object "Original Ticket"
String targetTicketKey = mainIssue.getCustomFieldValue(originalTicket).toString()
// Get Original Ticket Object based on the custom field value
def targetIssue = ComponentAccessor.getIssueManager().getIssueObject(targetTicketKey)
// Get list of modified values in the original ticket to update target ticket
List<GenericValue> changeItemsList = event.getChangeLog().getRelated("ChildChangeItem")
Iterator<GenericValue> changeItemListIterator = changeItemsList.iterator()
Object oldValue
Object newValue
def userManager = ComponentAccessor.getUserManager()
def auser = userManager.getUserByKey("Sync User")
def issueManager = ComponentAccessor.getIssueManager()
CustomField custom
// Loop for all the changed fields
while (changeItemListIterator.hasNext()) {
GenericValue changeItem = (GenericValue)changeItemListIterator.next()
String currentFieldName = changeItem.get("field").toString()
log.debug("Current field: "+currentFieldName)
oldValue = changeItem.get("oldstring")
newValue = changeItem.get("newstring")
if (oldValue != null && newValue != null){
log.debug("Field changed from: "+oldValue+" to "+newValue)
switch (currentFieldName){
case "summary":
log.debug("Found switch: Summary")
targetIssue.setSummary(newValue.toString())
break
case "description":
log.debug("Found switch: Description")
targetIssue.setDescription(newValue.toString())
break
case "Affected Version(s)":
log.debug("Found switch: Affected Version(s)")
// This is a label field. I'm stuck here and I don't know how to manipulate the value.
// Labels are a set type, studing more about it.
custom = customFieldManager.getCustomFieldObjectByName("Affected Version(s)")
targetIssue.setCustomFieldValue(custom,newValue)
break
default: log.debug("Not found: "+currentFieldName)
}
}
// Update my target Issue (in another project) that I'm trying to synchronize with the main issue.
issueManager.updateIssue(auser, targetIssue, com.atlassian.jira.event.type.EventDispatchOption.DO_NOT_DISPATCH, false)
}
mutableIssue.modifiedFields used only in scripted Validators.
Iterating through modified fileds in scripted Listener:
List<HashMap<String, Object>> fieldsModified = event.getChangeLog()?.getRelated('ChildChangeItem') as List<HashMap<String, Object>>
for (HashMap<String, Object> field : fieldsModified)
log.debug("Field: ${field["field"]}, old value: ${field["oldstring"]}, new value: ${field["newstring"]}.")
Affected versions is a system field like Summary and Description. Use issue.affectedVersions to update it.

How do I set a radio button value based on a condition of several other radio button selections?

Just need a little direction in finishing my script, I need to gather the values of several radio button fields and perform an if/then condition to determine the default radio button value of one other. This is what I have so far, is this the correct approach? What am I missing? This is a custom field script using Groovy in ScriptRunner.
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.MutableIssue;
//managers
def customFieldManager = ComponentAccessor.getCustomFieldManager()
IssueManager issueManager = ComponentAccessor.getIssueManager();
//gather the fields needed
def field1 = CustomFieldManager.getCustomFieldObjectByName("Field 1")
def field2 = CustomFieldManager.getCustomFieldObjectByName("Field 2")
//gather the values of the fields
def field1Value = issue.getCustomFieldValue(Field1).getValue()
def field2Value = issue.getCustomFieldValue(Field2).getValue()
if (field1Value == "Agree" && field2Value == "Agree"){
def field3 = customFieldManager.getCustomFieldObjectByName("Field 3")
issue.setCustomFieldValue(field3, "Agree")
} else {
issue.setCustomFieldValue(field3, "Disagree")
}
Figured out what the issue was...Emmanual was correct with the context as I was running this in Scriptrunner that was not implemented with Behaviours nor was it added in the context of a 'Scripted Field' which is required if you're going to call the Issue object within the context of that issue.

Resources