Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Scriptrunner console script to match up Labels values with Epic Names

Conor McCooey
Contributor
January 24, 2019

We have noticed a bug with the Pivotal Tracker to JIRA import tool, in that it does not import epics as issue types. This has been reported to Atlassian and they are raising a bug.

While this bug could take a very long time to get fixed (if ever) i am looking at an alternative solution. Steps below -

1. Run the importer to import all issues from Pivotal Tracker excluding the Epics. Any issues linked to an Epic will have the Epic name added as a label.

2. CSV export/import the Epics from Pivotal Tracker
These newly created Epics will have Epic Name that matches some of the labels on the stories that were imported.

3. Create and run a script in the Console that does the following -

A) Get list of all Epics (Issue Key & Epic Name) in project (JQL)
B) Get list of all Stories in project that have a label (JQL)
C) If story label matches an epic name, then get the epic issue key, and add it to the story epic link field, to properly create Epic - Story relationship in Jira.

Examples of the Epic Name / Label values are -

EPIC NAME - "formalize development process"

LABEL = "formalize_development_process"

So they differ, in that spaces have been replaced with an underscore when the epic name was added as a label by the Pivotal Tracker importer 

I would greatly appreciate if any of you developers out there could take a look at my requirements and code and help me fill in the gaps.

My code -

 

package examples.docs
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.search.SearchProvider
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.issue.Issue

def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class)
def issueManager = ComponentAccessor.getIssueManager()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

// GET EPICS - only want epic.key and epic.epic_name put into list/array - how?
def query = jqlQueryParser.parseQuery("project = PTEPICS and type = Epic")
def epic_results = searchProvider.search(query, user, PagerFilter.getUnlimitedFilter())

// GET ISSUES
def query2 = jqlQueryParser.parseQuery("project = PTEPICS and type != Epic and type not in subTaskIssueTypes()")
def issue_results = searchProvider.search(query2, user, PagerFilter.getUnlimitedFilter())

//FOR EACH ISSUE - how to do 1,2,3 below?
issue_results.getIssues().each {Issue ->
// 1. extract issue.label value
// 2. if issue.label == compare with list/arry of epic.epic_names and if a match then
// 3. set the issue.epic_link = epic.epic_key (of the matched epic)
}

 

 

Many thanks in advance,

Conor

1 answer

1 accepted

0 votes
Answer accepted
Aidan Derossett [Adaptavist]
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 24, 2019

Hey again Conor! :D

I've been playing around with this and have managed to put together a working script using the code that you've provided. Since I added quite a few lines, I've also loaded the script up with comments to help explain any of the code that may be convoluted (feel free to remove these). However, let me know if you have any other questions or concerns after looking it over and running a few tests. 

See the code below:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.search.SearchProvider
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.web.bean.PagerFilter

def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class)
def customFieldManager = ComponentAccessor.customFieldManager
def issueManager = ComponentAccessor.issueManager
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

def epicNameCF = customFieldManager.getCustomFieldObjectsByName("Epic Name").first()
def epicLinkCF = customFieldManager.getCustomFieldObjectsByName("Epic Link").first()

// GET EPICS
def query = jqlQueryParser.parseQuery("project = PTEPICS and type = Epic")
def epic_results = searchProvider.search(query, user, PagerFilter.getUnlimitedFilter())
//The query will return DocumentIssue object which can't be cast to MutableIssues
//So the below is required to obtain a full list of Issue objects (which can be cast)
def epicList = epic_results.issues.collect{issueManager.getIssueByCurrentKey(it.key)}

// GET ISSUES
def query2 = jqlQueryParser.parseQuery("project = PTEPICS and type != Epic and type not in subTaskIssueTypes()")
def issue_results = searchProvider.search(query2, user, PagerFilter.getUnlimitedFilter())
//The query will return DocumentIssue object which can't be cast to MutableIssues
//So the below is required to obtain a full list of Issue objects (which can be cast)
def issueList = issue_results.issues.collect{issueManager.getIssueByCurrentKey(it.key)}

//FOR EACH ISSUE
issueList.each{
// 1. extract issue.label value
// 2. if issue.label == compare with list/arry of epic.epic_names and if a match then
// 3. set the issue.epic_link = epic.epic_key (of the matched epic)

//Cast the issue to a MutableIssue (you can only set/change data of issues with this type)
def issue = it as MutableIssue

//Get the label (presumably the only label) and replace any underscores with spaces
def issueLabel = issue.labels.first()?.label?.replaceAll("_"," ")
//Search the list of epics for an epic with a name matching the label
def relatedEpic = epicList.find{it.getCustomFieldValue(epicNameCF) == issueLabel}

if(relatedEpic)
{
//Set the issue's Epic Link to the found epic
issue.setCustomFieldValue(epicLinkCF, relatedEpic)

//Update both of the epic and the issue in the Jira datastore
issueManager.updateIssue(user, issue, EventDispatchOption.DO_NOT_DISPATCH, false)
issueManager.updateIssue(user, relatedEpic, EventDispatchOption.DO_NOT_DISPATCH, false)
}
}

Best of luck!
Aidan

Conor McCooey
Contributor
January 28, 2019

Thanks Aidan! Works perfectly :-)

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events