Post-function: Clean issue links and leave a comment in the affected issues
import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.event.type.EventDispatchOption import com.atlassian.jira.issue.link.IssueLinkTypeManager def issueManager = ComponentAccessor.getIssueManager() def issueLinkManager = ComponentAccessor.getIssueLinkManager() def customFieldManager = ComponentAccessor.getCustomFieldManager() def commentManager = ComponentAccessor.getCommentManager() def adminUser = ComponentAccessor.getUserManager().getUserByName("jira-automat") //to be replaced with actual admin user by providing user name def issueLinkIdToBeChanged = 10500 as long //"split to" link, supposed to be changed to default Epic Link or SAJ link ("Child Epics", "Parent Epic") depending on issue types def defaultEpicLinkTypeId = 10001 as long; //default Epic Link id; to be replaced with actual Id def sajEpicToEpicLinkTypeId = 12345 as long; //custom link created with SAJ ("Child Epics", "Parent Epic"); to be replaced with actual Id def availableIssueLinkTypes = ComponentAccessor.getComponent(IssueLinkTypeManager).issueLinkTypes def sajEpicToEpicLinkType = availableIssueLinkTypes.findByName("Epic-to-Epic") //custom link created with SAJ ("Child Epics", "Parent Epic"); to be replaced with actual link type name def epicFieldName = "Epic Link" //if German language in use: "Epic-Verknüpfung" /* ---------- Get and check all outward links of current issue ---------- */ def outwardLinks = issueLinkManager.getOutwardLinks(issue.id) //current issue --- outward Link > destination issue for (link in outwardLinks) { def destinationIssue = issueManager.getIssueObject(link.destinationId) if (link.issueLinkType.getId() == defaultEpicLinkTypeId) { //if an OUTWARD Epic Link exists... (current issue --- outward Epic Link > destination issue) /* ---------- Change or remove invalid Epic Links and leave comment ---------- */ if (destinationIssue.getIssueType().name == "Epic") { if (issue.getIssueType().name == "Epic") { //IF: Epic --- outward Epic Link > Epic issueLinkManager.changeIssueLinkType(link, sajEpicToEpicLinkType, adminUser) //THEN: Epic --- "Child Epics" link > Epic commentManager.create(issue, adminUser, "(!) {color:#505F79}Invalid outward default Epic Link to Epic " + destinationIssue.getKey() + " replaced with \"" + sajEpicToEpicLinkType.getName() + "\" link.{color}", false) commentManager.create(destinationIssue, adminUser, "(!) {color:#505F79}Invalid inward default Epic Link from Epic " + issue.getKey() + " replaced with \"" + sajEpicToEpicLinkType.getName() + "\" link.{color}", false) } else { //IF: current issue (any type) --- outward Epic Link > Epic issueLinkManager.removeIssueLink(link, adminUser) //THEN: remove link commentManager.create(issue, adminUser, "(!) {color:#505F79}Invalid outward default Epic Link to Epic " + destinationIssue.getKey() + " removed.{color}", false) commentManager.create(destinationIssue, adminUser, "(!) {color:#505F79}Invalid inward default Epic Link from " + issue.getIssueType().name + " " + issue.getKey() + " removed.{color}", false) } } } else if (link.issueLinkType.getId() == sajEpicToEpicLinkTypeId) { //if a "Child Epics" link exists... (current issue --- "Child Epics" link > destination issue) /* ---------- Remove incorrect SAJ links ("Child Epics", "Parent Epic") and leave comment ---------- */ if (issue.getIssueType().name == "Milestone" || issue.getIssueType().name == "Task" || issue.getIssueType().name == "Story") { //IF: Milestone/Task/Story --- "Child Epics" link > destination issue (any type) issueLinkManager.removeIssueLink(link, adminUser) //THEN: remove link commentManager.create(issue, adminUser, "(!) {color:#505F79}Incorrect \"Child Epics\" link to " + destinationIssue.getIssueType().name + " " + destinationIssue.getKey() + " removed.{color}", false) commentManager.create(destinationIssue, adminUser, "(!) {color:#505F79}Incorrect \"Parent Epic\" link to " + issue.getIssueType().name + " " + issue.getKey() + " removed.{color}", false) } } else if (link.issueLinkType.getId() == issueLinkIdToBeChanged) { //if a "split to" link exists... (current issue --- "split to" link > destination issue) /* ---------- Change "split to" link to default Epic Link or SAJ link ("Child Epics", "Parent Epic") depending on issue types ---------- */ if (issue.getIssueType().name == "Epic") { if (destinationIssue.getIssueType().name == "Epic" || destinationIssue.getIssueType().name == "Milestone") { //IF: Epic --- "split to" link > Epic/Milestone issueLinkManager.changeIssueLinkType(link, sajEpicToEpicLinkType, adminUser) //THEN: Epic --- "Child Epics" link > Epic/Milestone commentManager.create(issue, adminUser, "(!) {color:#505F79}Link \"split to\" to " + destinationIssue.getIssueType().name + " " + destinationIssue.getKey() + " replaced with \"" + sajEpicToEpicLinkType.getName() + "\" link.{color}", false) commentManager.create(destinationIssue, adminUser, "(!) {color:#505F79}Link \"split to\" to Epic " + issue.getKey() + " replaced with \"" + sajEpicToEpicLinkType.getName() + "\" link.{color}", false) } else if (destinationIssue.getIssueType().name == "Task" || destinationIssue.getIssueType().name == "Story") { //IF: Epic --- "split to" link > Task/Story issueLinkManager.removeIssueLink(link, adminUser) def epicLinkCustomField = customFieldManager.getCustomFieldObjects(destinationIssue).findByName(epicFieldName) destinationIssue.setCustomFieldValue(epicLinkCustomField, issue) //THEN: Epic --- outward Epic Link > Task/Story commentManager.create(issue, adminUser, "(!) {color:#505F79}Link \"split to\" to " + destinationIssue.getIssueType().name + " " + destinationIssue.getKey() + " replaced with outward default Epic Link.{color}", false) commentManager.create(destinationIssue, adminUser, "(!) {color:#505F79}Link \"split to\" to Epic " + issue.getKey() + " replaced with inward default Epic Link.{color}", false) } } else if (issue.getIssueType().name == "Milestone") { if (destinationIssue.getIssueType().name == "Epic") { //IF: Milestone --- "split to" link > Epic issueLinkManager.removeIssueLink(link, adminUser) issueLinkManager.createIssueLink(destinationIssue.id, issue.id, sajEpicToEpicLinkTypeId, 1L, adminUser) //THEN: Milestone --- "Parent Epic" link > Epic / Milestone < "Child Epics" link --- Epic commentManager.create(issue, adminUser, "(!) {color:#505F79}Link \"split to\" to Epic " + destinationIssue.getKey() + " replaced with \"" + sajEpicToEpicLinkType.getName() + "\" link.{color}", false) commentManager.create(destinationIssue, adminUser, "(!) {color:#505F79}Link \"split to\" to Milestone " + issue.getKey() + " replaced with \"" + sajEpicToEpicLinkType.getName() + "\" link.{color}", false) } } else if (issue.getIssueType().name == "Task" || issue.getIssueType().name == "Story") { if (destinationIssue.getIssueType().name == "Epic") { //IF: Task/Story --- "split to" link > Epic issueLinkManager.removeIssueLink(link, adminUser) def epicLinkCustomField = customFieldManager.getCustomFieldObjects(issue).findByName(epicFieldName) issue.setCustomFieldValue(epicLinkCustomField, destinationIssue) //THEN: Task/Story < inward Epic Link --- Epic commentManager.create(issue, adminUser, "(!) {color:#505F79}Link \"split to\" to Epic " + destinationIssue.getKey() + " replaced with inward default Epic Link.{color}", false) commentManager.create(destinationIssue, adminUser, "(!) {color:#505F79}Link \"split to\" to " + issue.getIssueType().name + " " + issue.getKey() + " replaced with outward default Epic Link.{color}", false) } } } issueManager.updateIssue(adminUser, destinationIssue, EventDispatchOption.ISSUE_UPDATED, false) } /* ---------- Get and check all inward links of current issue ---------- */ def inwardLinks = issueLinkManager.getInwardLinks(issue.id) //current issue <--- inward Link --- source issue for (link in inwardLinks) { def sourceIssue = issueManager.getIssueObject(link.sourceId) if (link.issueLinkType.getId() == defaultEpicLinkTypeId) { //if an INWARD Epic Link exists... (current issue < inward Epic Link --- source issue) /* ---------- Change or remove invalid Epic Links and leave comment ---------- */ if (issue.getIssueType().name == "Epic") { if (sourceIssue.getIssueType().name == "Epic") { //IF: Epic < inward Epic Link --- Epic issueLinkManager.changeIssueLinkType(link, sajEpicToEpicLinkType, adminUser) //THEN: Epic --- "Parent Epic" link > Epic / Epic < "Child Epics" link --- Epic commentManager.create(issue, adminUser, "(!) {color:#505F79}Invalid inward default Epic Link from Epic " + sourceIssue.getKey() + " replaced with \"" + sajEpicToEpicLinkType.getName() + "\" link.{color}", false) commentManager.create(sourceIssue, adminUser, "(!) {color:#505F79}Invalid outward default Epic Link to Epic " + issue.getKey() + " replaced with \"" + sajEpicToEpicLinkType.getName() + "\" link.{color}", false) } else { //IF: Epic < inward Epic Link --- Task/Story issueLinkManager.removeIssueLink(link, adminUser) //THEN: remove link commentManager.create(issue, adminUser, "(!) {color:#505F79}Invalid inward default Epic Link from " + sourceIssue.getIssueType().name + " " + sourceIssue.getKey() + " removed.{color}", false) commentManager.create(sourceIssue, adminUser, "(!) {color:#505F79}Invalid outward default Epic Link to Epic " + issue.getKey() + " removed.{color}", false) } } } else if (link.issueLinkType.getId() == sajEpicToEpicLinkTypeId) { //if a "Parent Epic" link exists... (current issue < "Child Epics" Link --- source issue (inward) / current issue --- "Parent Epic" Link > source issue (outward)) /* ---------- Remove incorrect SAJ links ("Child Epics", "Parent Epic") and leave comment ---------- */ if ((issue.getIssueType().name == "Milestone" && sourceIssue.getIssueType().name != "Epic") || issue.getIssueType().name == "Task" || issue.getIssueType().name == "Story") { //IF: Milestone < "Child Epics" Link --- source issue (any type except Epic); OR: Task/Story < "Child Epics" Link --- source issue (any type) issueLinkManager.removeIssueLink(link, adminUser) //THEN: remove link commentManager.create(issue, adminUser, "(!) {color:#505F79}Incorrect \"Parent Epic\" link to " + sourceIssue.getIssueType().name + " " + sourceIssue.getKey() + " removed.{color}", false) commentManager.create(sourceIssue, adminUser, "(!) {color:#505F79}Incorrect \"Child Epics\" link to " + issue.getIssueType().name + " " + issue.getKey() + " removed.{color}", false) } } else if (link.issueLinkType.getId() == issueLinkIdToBeChanged) { //if a "split to" link exists... (current issue < "split to" link --- source issue) /* ---------- Change "split to" link to default Epic Link or SAJ link ("Child Epics", "Parent Epic") depending on issue types ---------- */ if (sourceIssue.getIssueType().name == "Epic") { if (issue.getIssueType().name == "Epic" || issue.getIssueType().name == "Milestone") { //IF: Epic/Milestone < "split to" link --- Epic issueLinkManager.changeIssueLinkType(link, sajEpicToEpicLinkType, adminUser) //THEN: Epic/Milestone --- "Parent Epic" link > Epic / Epic/Milestone < "Child Epics" Link --- Epic commentManager.create(issue, adminUser, "(!) {color:#505F79}Link \"split to\" to Epic " + sourceIssue.getKey() + " replaced with \"" + sajEpicToEpicLinkType.getName() + "\" link.{color}", false) commentManager.create(sourceIssue, adminUser, "(!) {color:#505F79}Link \"split to\" to " + issue.getIssueType().name + " " + issue.getKey() + " replaced with \"" + sajEpicToEpicLinkType.getName() + "\" link.{color}", false) } else if (issue.getIssueType().name == "Task" || issue.getIssueType().name == "Story") { //IF: Task/Story < "split to" link --- Epic issueLinkManager.removeIssueLink(link, adminUser) def epicLinkCustomField = customFieldManager.getCustomFieldObjects(issue).findByName(epicFieldName) issue.setCustomFieldValue(epicLinkCustomField, sourceIssue) //THEN: Task/Story < inward Epic Link --- Epic commentManager.create(issue, adminUser, "(!) {color:#505F79}Link \"split to\" to Epic " + sourceIssue.getKey() + " replaced with inward default Epic Link.{color}", false) commentManager.create(sourceIssue, adminUser, "(!) {color:#505F79}Link \"split to\" to " + issue.getIssueType().name + " " + issue.getKey() + " replaced with outward default Epic Link.{color}", false) } } else if (sourceIssue.getIssueType().name == "Milestone") { if (issue.getIssueType().name == "Epic") { //IF: Epic < "split to" link --- Milestone issueLinkManager.removeIssueLink(link, adminUser) issueLinkManager.createIssueLink(issue.id, sourceIssue.id, sajEpicToEpicLinkTypeId, 1L, adminUser) //THEN: Epic --- "Child Epics" link > Milestone / Epic < "Parent Epic" link --- Milestone commentManager.create(issue, adminUser, "(!) {color:#505F79}Link \"split to\" to Milestone " + sourceIssue.getKey() + " replaced with \"" + sajEpicToEpicLinkType.getName() + "\" link.{color}", false) commentManager.create(sourceIssue, adminUser, "(!) {color:#505F79}Link \"split to\" to Epic " + issue.getKey() + " replaced with \"" + sajEpicToEpicLinkType.getName() + "\" link.{color}", false) } } else if (sourceIssue.getIssueType().name == "Task" || sourceIssue.getIssueType().name == "Story") { if (issue.getIssueType().name == "Epic") { //IF: Epic < "split to" link --- Task/Story issueLinkManager.removeIssueLink(link, adminUser) def epicLinkCustomField = customFieldManager.getCustomFieldObjects(sourceIssue).findByName(epicFieldName) sourceIssue.setCustomFieldValue(epicLinkCustomField, issue) //THEN: Epic --- outward Epic Link > Task/Story commentManager.create(issue, adminUser, "(!) {color:#505F79}Link \"split to\" to " + sourceIssue.getIssueType().name + " " + sourceIssue.getKey() + " replaced with outward default Epic Link.{color}", false) commentManager.create(sourceIssue, adminUser, "(!) {color:#505F79}Link \"split to\" to Epic " + issue.getKey() + " replaced with inward default Epic Link.{color}", false) } } } issueManager.updateIssue(adminUser, sourceIssue, EventDispatchOption.ISSUE_UPDATED, false) } issueManager.updateIssue(adminUser, issue, EventDispatchOption.ISSUE_UPDATED, false)
PLEASE NOTE
⚠Script is restricted to the issue types Epic, Milestone, Task and Story. |