I'm using Scriptrunner for Jira Cloud. I've found the post function to transition a parent when a subtask transitions, but I would like the entire hierarchy to transition as well - Sub-task, Story and Epic. I'm not finding how to get the parent of any issue type except Sub-task.
def transitionID = '21' // My global In Progress transition ID
def parentKey = 0
if (((Map) issue.fields.issuetype)?.name == 'Sub-task') {
parentKey = issue.fields.parent.key
} else {
What goes here?
}
// The rest call to transition the issue
def result = post("/rest/api/2/issue/${parentKey}/transitions")
.header("Content-Type", "application/json")
.body([transition: [id: transitionID]])
.asObject(Map)
// Check if the issue was transitioned correctly
// Log out the issues updated or which failed to update
if (result.status == 204) {
logger.info("The ${parentKey} issue was also transitioned by the post function.")
} else {
logger.warn("The post function failed to transition the ${parentKey}issue. ${result.status}: ${result.body}")
}
Obviously a WIP but help with this part would be appreciated
A task, story name it what you want don't have a parent, they can have epic link to relate them with the epic they belong to.
Jira works with only three levels of issues:
epics
tasks (give the issuetype the name you want)
subtasks (give the issuetype the name you want)
so the level you don't have is the task to epic level jump
obvously, you can create "fake" levels via links from issue to issue or something like that, but that's just a workaround
this is the JSON that rest/api/latest/issuetype returns for one issuetype:
{
"self":"https://jiraurl/rest/api/latest/issuetype/10801",
"id":"10801",
"description":"",
"iconUrl":"https://jiraurl/secure/viewavatar?size=xsmall&avatarId=10316&avatarType=issuetype",
"name":"Subtarea Petición HR",
"subtask":true,
"avatarId":10316
},
Only issuetypes with "subtask":true have parent issue
So maybe you should filter issues for that "subtask":true instead of the name of the subtask itself
The hierarchy we have includes:
Initiative
Epic
Story or Task
Subtask
If one looks at a Story issue, there is a field "Epic Link". Is this field not exposed from within the JSON?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
'epic link' is treated like a customfield, in my jira is 'customfield_10001'
you can get the value of that field with
import com.atlassian.jira.component.ComponentAccessor
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def cField = customFieldManager.getCustomFieldObject(xxxxx) //being xxxxx the id of the field
// or
// def cField = customFieldManager.getCustomFieldObjectByName('custon field name')
def cfValue = cField.getValue(issue)
//or
// def cfValue = issue.getCustomFieldValue(cField)
if you call
{url}/rest/api/latest/issue/{issuekey}
you get a JSON with all the fields for that issue. , you also have issuetype with the info i gave you in the previous post, the status, and all the info about fields in the issue
{
"expand":"renderedFields,names,schema,operations,editmeta,changelog,versionedRepresentations",
"id":"12992",
"self":"https://url.jira.com/rest/api/latest/issue/12992",
"key":"EMB-394",
"fields":{
"customfield_10870":null,
"resolution":{
"self":"https://url.jira.com/rest/api/2/resolution/10000",
"id":"10000",
"description":"xxxxxx xxxxxx",
"name":"Listo"
},
"customfield_10871":null,
"customfield_10872":null,
"customfield_11829":null,
.... lots of other customfields...
"issuelinks":[
],
"assignee":null,
"customfield_10850":null,
.... lots of other customfields...
"issuetype":{
"self":"https://url.jira.com/rest/api/2/issuetype/10102",
"id":"10102",
"description":"Un problema que dificulta o impide el funcionamiento del producto.",
"iconUrl":"https://url.jira.com/secure/viewavatar?size=xsmall&avatarId=10303&avatarType=issuetype",
"name":"Error",
"subtask":false,
"avatarId":10303
},
"customfield_10940":null,
"customfield_10820":null,
"customfield_10941":null,
.... lots of other customfields...
"status":{
"self":"https://url.jira.com/rest/api/2/status/6",
"description":"The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.",
"iconUrl":"https://url.jira.com/images/icons/statuses/closed.png",
"name":"Cerrada",
"id":"6",
"statusCategory":{
"self":"https://url.jira.com/rest/api/2/statuscategory/3",
"id":3,
"key":"done",
"colorName":"green",
"name":"Listo"
}
},
"customfield_14810":null,
.... lots of other customfields...
"customfield_14631":null,
"project":{
"self":"https://url.jira.com/rest/api/2/project/10605",
"id":"10605",
"key":"EMB",
"name":"TO - Message Broker",
"avatarUrls":{
"48x48":"https://url.jira.com/secure/projectavatar?avatarId=10324",
"24x24":"https://url.jira.com/secure/projectavatar?size=small&avatarId=10324",
"16x16":"https://url.jira.com/secure/projectavatar?size=xsmall&avatarId=10324",
"32x32":"https://url.jira.com/secure/projectavatar?size=medium&avatarId=10324"
},
.... lots of other customfields...
"customfield_10001":"EMB-263",
"customfield_12422":null,
"customfield_12301":null,
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thank you, Fran, this was my missing piece. I have my script working now.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
glad to help.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Janene Pappas would you mind sharing your script please? thank you
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Sure! It's set to run as the Initiating User. I've also since added some more code to update a few fields as well - that's the weekly progress status stuff
The Condition is:
((Map) issue.fields.issuetype)?.name != 'Epic' & ((Map) issue.fields.issuetype)?.name != 'Bug' & ((Map) issue.fields.issuetype)?.name != 'Spike'
and the Code is:
def transitionID = '21'
def parentIssueName = 'customfield_10014'
def parentKey = 0
// Get the parent key, based on the issue type
if (((Map) issue.fields.issuetype)?.name == 'Sub-task') {
parentKey = issue.fields.parent.key
} else {
def fields = issue.fields as Map
parentKey = fields[parentIssueName]
}
if (parentKey != 0) {
// The rest call to transition the issue
def result = post("/rest/api/2/issue/${parentKey}/transitions")
.header("Content-Type", "application/json")
.body([transition: [id: transitionID]])
.asObject(Map)
// Check if the issue was transitioned correctly
// Log out the issues updated or which failed to update
if (result.status == 204) {
logger.info("The ${parentKey} issue was also transitioned by the post function.")
// for an Epic, also transition the weekly progress status, if needed
def parentResult = get('/rest/api/2/issue/' + parentKey)
.header('Content-Type', 'application/json')
.asObject(Map)
if (parentResult.status == 200 && ((Map) parentResult.body.fields.issuetype)?.name != 'Epic') {
logger.info("Parent is not an Epic, returning")
return
}
// Specify the name of the select list field to set
def progressStatusFieldName = 'Weekly Progress Status'
// Get the Custom field to get the option value from
def customField = get("/rest/api/2/field")
.asObject(List)
.body
.find {
(it as Map).name == progressStatusFieldName
} as Map
// Check if the custom field returns a valid field and is not null
assert customField != null : "Cannot find custom field with name of: ${progressStatusFieldName}"
def progValue = (parentResult.body.fields[customField.id] as Map)?.value
if (progValue != "Not Started") {
logger.info("Progress status is ${progValue}, returning")
return
}
def progResult = put("/rest/api/2/issue/${parentKey}")
.header('Content-Type', 'application/json')
.body([
fields: [
(customField.id):[value: "On Target"] as Map
]
])
.asString()
if (progResult.status == 204) {
logger.info( "The ${customField.name} select list field was successfully updated on the ${parentKey} issue")
} else {
logger.info( "${progResult.status}: ${progResult.body}")
}
} else {
logger.warn("The post function failed to transition the ${parentKey}issue. ${result.status}: ${result.body}")
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.