Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Post-function: Clean issue links and leave a comment in the affected issues

Code Block
breakoutModewide
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)