Listing out the groovy scripts for different scenarios below which might be useful in future requirements.
1. Script to transition sub-task to same as parent task on update or create event (Cloud)
// Check if issue types are sub-tasks if (issue.fields.issuetype.subtask) { logger.info("This is a subtask") return } else if (!issue.fields.issutype.subtask) { logger.info("This is not a subtask") // Retrieve the key def parentKey = issue.key logger.info("Parent Key: " + parentKey) // Get the parent issue object def result = get('/rest/api/2/issue/' + parentKey + "?expand=transitions") .header('Content-Type', 'application/json') .asObject(Map) // Find the parent status def parentStatus = result.body.fields.status.name logger.info("Parent Status: " + parentStatus) // Find the subtask status def subTaskStatus = result.body.fields.subtasks.fields.status.name logger.info("Sub task Status: " + subTaskStatus) // Find the subtasks key String[] subTaskKeyInArray = result.body.fields.subtasks.key //def subTaskKeyString = subTaskKeyInArray.join(", ") logger.info("Length of the array is:" + subTaskKeyInArray.length) //Defining statuses def open = "Open" def qaInProg = "QA In Prog" def pendingCTS = "Pending CTS" def ctsClosed = "CTS Closed" def investigating = "Investigating" def investigatingComplete = "Investigating Complete" def fixed = "Fixed" def transition(transitionId, subTaskKey) { def transitionIssue = post("/rest/api/2/issue/" + subTaskKey + "/transitions") .header("Content-Type", "application/json") .body([transition: [id: transitionId]]) .asObject(Map) logger.info("Sub Task issue transitioned") } for(int i = 0; i < subTaskKeyInArray.length; i++) { logger.info("Value of i " + i) logger.info("Sub task:" + subTaskKeyInArray[i]) // Put conditions to set transition ids based on condition is true if (subTaskStatus.contains(qaInProg) && parentStatus.contains(investigating)) { logger.info("Transition id after entering loop: 41") transition("41", subTaskKeyInArray[i]) } if (subTaskStatus.contains(qaInProg) && parentStatus.contains(pendingCTS)) { logger.info("Transition id after entering loop: 51") transition("51", subTaskKeyInArray[i]) } if (subTaskStatus.contains(qaInProg) && parentStatus.contains(ctsClosed)) { logger.info("Transition id after entering loop: 61") transition("61", subTaskKeyInArray[i]) } if (subTaskStatus.contains(qaInProg) && parentStatus.contains(fixed)) { logger.info("Transition id after entering loop: 121") transition("121", subTaskKeyInArray[i]) } if (subTaskStatus.contains(open) && parentStatus.contains(qaInProg)) { logger.info("Transition id after entering loop: 11") transition("11", subTaskKeyInArray[i]) } if (subTaskStatus.contains(open) && parentStatus.contains(pendingCTS)) { logger.info("Transition id after entering loop: 21") transition("21", subTaskKeyInArray[i]) } if (subTaskStatus.contains(open) && parentStatus.contains(ctsClosed)) { logger.info("Transition id after entering loop: 61") transition("61", subTaskKeyInArray[i]) } if (subTaskStatus.contains(open) && parentStatus.contains(fixed)) { logger.info("Transition id after entering loop: 121") transition("121", subTaskKeyInArray[i]) } if (subTaskStatus.contains(investigating) && parentStatus.contains(investigatingComplete)) { logger.info("Transition id after entering loop: 71") transition("71", subTaskKeyInArray[i]) } if (subTaskStatus.contains(investigating) && parentStatus.contains(pendingCTS)) { logger.info("Transition id after entering loop: 81") transition("81", subTaskKeyInArray[i]) } if (subTaskStatus.contains(investigating) && parentStatus.contains(ctsClosed)) { logger.info("Transition id after entering loop: 61") transition("61", subTaskKeyInArray[i]) } if (subTaskStatus.contains(investigating) && parentStatus.contains(fixed)) { logger.info("Transition id after entering loop: 121") transition("121", subTaskKeyInArray[i]) } if (subTaskStatus.contains(investigatingComplete) && parentStatus.contains(pendingCTS)) { logger.info("Transition id after entering loop: 101") transition("101", subTaskKeyInArray[i]) } if (subTaskStatus.contains(investigatingComplete) && parentStatus.contains(ctsClosed)) { logger.info("Transition id after entering loop: 161") transition("161", subTaskKeyInArray[i]) } if (subTaskStatus.contains(investigatingComplete) && parentStatus.contains(fixed)) { logger.info("Transition id after entering loop: 121") transition("121", subTaskKeyInArray[i]) } if (subTaskStatus.contains(investigatingComplete) && parentStatus.contains(investigating)) { logger.info("Transition id after entering loop: 111") transition("111", subTaskKeyInArray[i]) } if (subTaskStatus.contains(pendingCTS) && parentStatus.contains(ctsClosed)) { logger.info("Transition id after entering loop: 141") transition("141", subTaskKeyInArray[i]) } if (subTaskStatus.contains(pendingCTS) && parentStatus.contains(fixed)) { logger.info("Transition id after entering loop: 121") transition("121", subTaskKeyInArray[i]) } if (subTaskStatus.contains(pendingCTS) && parentStatus.contains(investigating)) { logger.info("Transition id after entering loop: 131") transition("131", subTaskKeyInArray[i]) } if (subTaskStatus.contains(fixed) && parentStatus.contains(ctsClosed)) { logger.info("Transition id after entering loop: 151") transition("151", subTaskKeyInArray[i]) } if (subTaskStatus.contains(fixed) && parentStatus.contains(investigating)) { logger.info("Transition id after entering loop: 131") transition("131", subTaskKeyInArray[i]) } } }
2. Script to prompt the user if they want to close the parent ticket when all sub-tasks under the ticket are done (Cloud)
// Check if issue types are sub-tasks if (!issue.fields.issuetype.subtask) { return } // Get the parent issue as a Map def parent = (issue.fields as Map).parent as Map // Retrieve all the subtasks of this issue's parent def parentKey = parent.key logger.info("Parent Key: " + parentKey) // Specify the name of the version to extract from the issue def closedStatus = "Done" logger.info("Closed Status: " + closedStatus) // Get the parent issue object def result = get('/rest/api/2/issue/' + parentKey) .header('Content-Type', 'application/json') .asObject(Map) //Find the assignee name def assignee = result.body.fields.assignee.displayName logger.info("Assignee name is :" + assignee) // Find the subtasks status String[] subTasks = result.body.fields.subtasks logger.info("Subtasks length: " + subTasks.length) def allSubTasksResolved; for(int i = 0; i < subTasks.length; i++) { def subTasksStatus = result.body.fields.subtasks[i].fields.status.name logger.info("sub task status: " + subTasksStatus) if(subTasks.findAll{subTasksStatus.contains(closedStatus)}){ allSubTasksResolved = true } // If all subtasks have the Done status set the flag to true if(subTasks.findAll{!subTasksStatus.contains(closedStatus)}){ allSubTasksResolved = false } } if(allSubTasksResolved == true){ logger.info("All sub tasks are in Done status") def prompt = post("/rest/api/2/issue/" + parentKey + "/notify") .header("Content-Type", "application/json") .body([ subject: 'All sub-tasks transitioned to Done status', textBody: "All the sub-tasks related to " + parentKey + " are transitioned to Done status", htmlBody: "<p>Do you want to close the </p>" + parentKey + "<p> issue?</p>" , to: [ users: [[ name: assignee, active: true ]] ] ]) .asString() } else if (allSubTasksResolved == false){ logger.info("All sub tasks are not in Done status") }
3. Script to change the fixVersions field of sub-tasks based on parent task on update event (Server)
import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.event.type.EventDispatchOption import com.atlassian.jira.issue.Issue import com.atlassian.jira.issue.IssueManager import com.atlassian.jira.issue.MutableIssue import com.atlassian.jira.project.version.Version IssueManager issueManager = ComponentAccessor.getComponent(IssueManager.class) Issue updatedIssue = event.getIssue() log.error "Issue is: " + updatedIssue Collection<Version> fixVersions = new ArrayList<Version>() fixVersions = updatedIssue.getFixVersions() log.error "Fix versions of parent are: " + fixVersions Collection<Issue> subTasks = updatedIssue.getSubTaskObjects() log.error "Sub tasks are: " + subTasks subTasks.each { log.error "Type : " + it.issueType.getName() if(it.issueType.getName() == "Migration") { if (it instanceof MutableIssue) { ((MutableIssue) it).setFixVersions(fixVersions) issueManager.updateIssue(event.getUser(), it, EventDispatchOption.ISSUE_UPDATED, false) log.error "Fix version of subbtask" } } }
Learning:
Knowledge on how scriptrunner listener works for both cloud and server
Got to understand different scenarios for Jira based on which scripts were written
Basic knowledge on groovy
No | Date | Topics learnt |
1 | 12-03-2020 | Introduction to Groovy, how groovy works, static and dynamic compilation, optional typed, how to use scriptrunner to execute scripts in script console, how to look up to javadoc for methods and classes |
2 | 13-03-2020 | Variables, rules, operators, built in scripts and scenarios in scriptrunner, listeners, exception handling, how to get all the details related to a specific issue (code) |