ScriptRunner copy Epic custom field to every Epic child

Lev Ryvkin March 26, 2019

Hello everyone!

I need a help with the code for Script Runner.

I am trying to build the listener for the event of issue updated.

If the trigger issue is Epic I need to iterate through all issues in epic and copy custom field cf[10112] "Project team" to every issue in epic.

I know you can use 

def query = jqlQueryParser.parseQuery("\"Epic Link\" in (${issue.key})")

def results = searchProvider.search(query, user, PagerFilter.getUnlimitedFilter())

And then iterate with 

results.getIssues().each{
}

 But, unfortunately, I lack the knowledge in overall ScriptRunner code logic. 

Could you please help me with this task?

 

Thanks in advance! 

 

Update (working code for custom listener of "issue updated" event):

import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.search.SearchProvider
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.web.bean.PagerFilter

def issue = event.issue as Issue

if(issue.issueType.name=="Epic")
{
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class)
def issueManager = ComponentAccessor.getIssueManager()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

//def query = jqlQueryParser.parseQuery("\"Epic Link\" in (${issue.key})")
def query = jqlQueryParser.parseQuery("issue in childIssuesOf(\"${issue.key}\")")
def results = searchProvider.search(query, user, PagerFilter.getUnlimitedFilter())

log.error("List of epic children : " + results.getIssues())

def customFieldManager = ComponentAccessor.getCustomFieldManager()

int cfProjectTeamId = 10112
def cfProjectTeam = customFieldManager.getCustomFieldObject(cfProjectTeamId)
def cfProjectTeamValue = issue.getCustomFieldValue(cfProjectTeam)
log.error("Epic Project team : " + cfProjectTeamValue)

def changeHistoryManager = com.atlassian.jira.component.ComponentAccessor.getChangeHistoryManager()
results.getIssues().each {myIssue ->;
def docIssue = issueManager.getIssueObject(myIssue.id)
def cfProjectTeamCurrentValue = docIssue.getCustomFieldValue(cfProjectTeam)
log.error("Project team to be replaced : " + cfProjectTeamCurrentValue)
cfProjectTeam.updateValue(null, docIssue, new ModifiedValue(cfProjectTeamCurrentValue, cfProjectTeamValue), new DefaultIssueChangeHolder())
}
}

 

3 answers

1 accepted

0 votes
Answer accepted
Antoine Berry
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
March 27, 2019

Hi @Lev Ryvkin ,

You are absolutely right, please try and use this code : 

import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue

// Your jql
def jqlSearch = ""\"Epic Link\" in (${issue.key})""
SearchService searchService = ComponentAccessor.getComponent(SearchService.class)
def userManager = ComponentAccessor.getUserManager()
IssueManager issueManager = ComponentAccessor.getIssueManager()
ApplicationUser user = userManager.getUserByKey('user_key')
List<Issue> issues = null
SearchService.ParseResult parseResult = searchService.parseQuery(user, jqlSearch)
if (parseResult.isValid()) {
def searchResult = searchService.search(user, parseResult.getQuery(), PagerFilter.getUnlimitedFilter())
issues = searchResult.issues.collect {issueManager.getIssueObject(it.id)}
} else {
log.error("Invalid JQL: " + jqlSearch);
}

def customFieldManager = ComponentAccessor.getCustomFieldManager()

int cfProjectTeamId = 10112
def cfProjectTeam = customFieldManager.getCustomFieldObject(cfProjectTeamId)
def cfProjectTeamValue = issue.getCustomFieldValue(cfProjectTeam)

def changeHistoryManager = com.atlassian.jira.component.ComponentAccessor.getChangeHistoryManager()
for (Issue issueLinked:issues){
def cfProjectTeamCurrentValue = issueLinked.getCustomFieldValue(cfOrgcfProjectTeam)
cfProjectTeam.updateValue(null, issueLinked, new ModifiedValue(cfProjectTeamCurrentValue, cfProjectTeamValue), new DefaultIssueChangeHolder())
}

 Just replace the user_key (pick a user that can access the issues).

Lev Ryvkin March 27, 2019

Thanks! It looks almost what I need, but, unfortunately, it doesn't compile.

I've added

def issue = event.issue as Issue 

and running the whole code with 

if(issue.issueType.name=="Epic"){}

So the code is:

import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue

def issue = event.issue as Issue

if(issue.issueType.name=="Epic") {
// Your jql
def jqlSearch = ("\"Epic Link\" in (${issue.key})")
SearchService searchService = ComponentAccessor.getComponent(SearchService.class)
def userManager = ComponentAccessor.getUserManager()
IssueManager issueManager = ComponentAccessor.getIssueManager()
ApplicationUser user = userManager.getUserByKey('user_key')
List<Issue> issues = null
SearchService.ParseResult parseResult = searchService.parseQuery(user, jqlSearch)
if (parseResult.isValid()) {
def searchResult = searchService.search(user, parseResult.getQuery(), PagerFilter.getUnlimitedFilter())
issues = searchResult.issues.collect {issueManager.getIssueObject(it.id)}
} else {
log.error("Invalid JQL: " + jqlSearch);
}

def customFieldManager = ComponentAccessor.getCustomFieldManager()

int cfProjectTeamId = 10112
def cfProjectTeam = customFieldManager.getCustomFieldObject(cfProjectTeamId)
def cfProjectTeamValue = issue.getCustomFieldValue(cfProjectTeam)

def changeHistoryManager = com.atlassian.jira.component.ComponentAccessor.getChangeHistoryManager()
for (Issue issueLinked:issues){
def cfProjectTeamCurrentValue = issueLinked.getCustomFieldValue(cfOrgcfProjectTeam)
cfProjectTeam.updateValue(null, issueLinked, new ModifiedValue(cfProjectTeamCurrentValue, cfProjectTeamValue), new DefaultIssueChangeHolder())
}
}

Attaching compile errors.image.pngimage.pngCapture.PNG 

Antoine Berry
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
March 27, 2019

Sorry, forgot to replace on variable. Change the last for loop for : 

for (Issue issueLinked:issues){
def cfProjectTeamCurrentValue = issueLinked.getCustomFieldValue(cfProjectTeam)
cfProjectTeam.updateValue(null, issueLinked, new ModifiedValue(cfProjectTeamCurrentValue, cfProjectTeamValue), new DefaultIssueChangeHolder())
}

 Do not worry about these errors. If you want to try once, go in "Script console", copy paste this code and run it. Just replace the jql for your test case : 

def jqlSearch = ""\"Epic Link\" in (ABC-123)""
Lev Ryvkin March 27, 2019

Well, it seems to work, but doesn't update anything. How should we debug it?

Lev Ryvkin March 27, 2019

As far as I found it doesn't even go to 

for (Issue issueLinked:issues){}

cycle as i added log.error(cfProjectTeamCurrentValue), which must output every project team list in every issue. And it does not at all.

But it works for epic.

int cfProjectTeamId = 10112
def cfProjectTeam = customFieldManager.getCustomFieldObject(cfProjectTeamId)
def cfProjectTeamValue = issue.getCustomFieldValue(cfProjectTeam)
log.error(cfProjectTeamValue)

actually returns Epic project team correctly.

Something is wrong with "for" cycle. 

Antoine Berry
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
March 27, 2019

I would suggest you update your for loop like this : 

for (Issue issueLinked:issues){
log.error("issueLinked : " + issueLinked)
def cfProjectTeamCurrentValue = issueLinked.getCustomFieldValue(cfProjectTeam)
log.error("cfProjectTeamCurrentValue : " + cfProjectTeamCurrentValue)
cfProjectTeam.updateValue(null, issueLinked, new ModifiedValue(cfProjectTeamCurrentValue, cfProjectTeamValue), new DefaultIssueChangeHolder())
}

Does it log something ? If not, it means your jql does not return anything, then check it with : 

log.error("jqlSearch : " + jqlSearch)
Lev Ryvkin March 27, 2019

Logs inside cycle do not return anything.

log.error("jqlSearch : " + jqlSearch)

Returns

 image.pngBut the actual search returns 1 result 

Capture.PNG

Antoine Berry
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
March 27, 2019

It seems we need the jql is not parsed correctly in groovy then. Maybe try to replace the " with ' (double quotes by simple quotes) ?

Antoine Berry
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
March 27, 2019

I mean, around Epic Link.

Lev Ryvkin March 27, 2019

It’s not the case. This line is suggested by Adaptivist vendor. 

Based on error I provided above I think <List> Of issues is not created at all.

there is an error in .collect method. 

I’ll come back to this later tomorrow. 

If you have anything more to adjust, you are more than welcome. I’ll try it tomorrow.

Thank you very much anyway! I think we are really close.

Lev Ryvkin March 27, 2019
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.search.SearchProvider
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.web.bean.PagerFilter

def issue = event.issue as Issue

if(issue.issueType.name=="Epic")
{
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class)
def issueManager = ComponentAccessor.getIssueManager()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

//def query = jqlQueryParser.parseQuery("\"Epic Link\" in (${issue.key})")
def query = jqlQueryParser.parseQuery("issue in childIssuesOf(\"${issue.key}\")")
def results = searchProvider.search(query, user, PagerFilter.getUnlimitedFilter())

log.error("List of epic children : " + results.getIssues())

def customFieldManager = ComponentAccessor.getCustomFieldManager()

int cfProjectTeamId = 10112
def cfProjectTeam = customFieldManager.getCustomFieldObject(cfProjectTeamId)
def cfProjectTeamValue = issue.getCustomFieldValue(cfProjectTeam)
log.error("Epic Project team : " + cfProjectTeamValue)

def changeHistoryManager = com.atlassian.jira.component.ComponentAccessor.getChangeHistoryManager()
results.getIssues().each {myIssue ->;
def docIssue = issueManager.getIssueObject(myIssue.id)
def cfProjectTeamCurrentValue = docIssue.getCustomFieldValue(cfProjectTeam)
log.error("Project team to be replaced : " + cfProjectTeamCurrentValue)
cfProjectTeam.updateValue(null, docIssue, new ModifiedValue(cfProjectTeamCurrentValue, cfProjectTeamValue), new DefaultIssueChangeHolder())
}
}

 The code that actually worked. The problem was in parser, which did not create a list of issues, so the update cycle was never executed. 

Now this works as intended. Thanks everyone who participated!

 

Best regards, 

Lev.

Like Antoine Berry likes this
Antoine Berry
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
March 28, 2019

Good job debugging this ! I have never had any issues with the code that I provided so I would not have guessed the parser was not working.

Have a great one.

Antoine

Lars Sundell August 14, 2020

Hello

Sorry for bumping this old issue, but I have user the script above for a while, but after a resent update to JIRA 8.5.6 It has started to give some errors. 

First a disclaimer. I have next to zero experience with groovy and is heavily depended on copy and paste from code like the one above. 

The problem is the line: 

def results = searchProvider.search(query, user, PagerFilter.getUnlimitedFilter())

If gives this error: Cannot find matching method

Any tips on an alternative way of creating the list of epic children would be appreciated. 

Lev Ryvkin August 15, 2020

@Lars Sundell 
Hello Lars!

As I can see they actually changed the SearchProvider interface.

Based on their documentation here

https://docs.atlassian.com/software/jira/docs/api/8.5.0/com/atlassian/jira/issue/search/SearchProvider.html

it accepts USER value no more.

 

Current implementation is like this: search(SearchQuery query, PagerFilter pager)

So, in conclusion, try this (remove user variable):

def results = searchProvider.search(query, PagerFilter.getUnlimitedFilter()) 

 

Lars Sundell August 17, 2020

Hello Lev

Thanks for your reply. 

I have tested the suggested modification, but without success. 

My script looks like this 

import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.search.SearchProvider
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.web.bean.PagerFilter

def issue = event.issue as Issue

if(issue.issueType.name=="Epic")
{
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class)
def issueManager = ComponentAccessor.getIssueManager()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

def query = jqlQueryParser.parseQuery("issue in childIssuesOf(\"${issue.key}\")")
def results = searchProvider.search(query, PagerFilter.getUnlimitedFilter())

log.error("List of epic children : " + results.getIssues())

def customFieldManager = ComponentAccessor.getCustomFieldManager()

int cfViewersId = 11537 // viewers filed
def cfViewers = customFieldManager.getCustomFieldObject(cfViewersId)
def cfViewersValue = issue.getCustomFieldValue(cfViewers)
log.error("Epic Project team : " + cfViewersValue)

def changeHistoryManager = com.atlassian.jira.component.ComponentAccessor.getChangeHistoryManager()
results.getIssues().each {myIssue ->;
def docIssue = issueManager.getIssueObject(myIssue.id)
def cfViewersCurrentValue = docIssue.getCustomFieldValue(cfViewers)
log.error("Project team to be replaced : " + cfViewersCurrentValue)
cfViewers.updateValue(null, docIssue, new ModifiedValue(cfViewersCurrentValue, cfViewersValue), new DefaultIssueChangeHolder())
}
}

The error is still:

[Static type checking] - cannot find matching method"
com.atlassian.jira.issue.search.SearchProvider#search(com.atlassian.quaery.Quary, com.atlassian.jira.web.bean.PageFilter <T extends java.lang.Object>)...

Could it be that the query input is of wrong format (I have not changed the query from when it did work)?

One challenge I have is that this is a listener so I have not found a way to test the script by step - by step commenting out things. If I copy it to the console where I can do this (when it is error free) I am unable to bet past the "def issue = event.issue as Issue" as this has to be replaced with something pointing to an issue I guess.  

Antoine Berry
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
August 17, 2020

Hi Lars. A few advices/tips : 

- You can debug a listener, just check the logs when you trigger it.

- If you want to use the console, you can use : 

def issueManager = ComponentAccessor.getIssueManager()
def issue = issueManager.getIssueObject("ABC-123")

to get the issue you like.

- I believe 

searchResult.getIssues()

is deprecated in jira 8. Use 

searchResult.getResults()

instead.

Lars Sundell August 19, 2020

I am still struggling with the searchprovider statment

def results = searchProvider.search(query, PagerFilter.getUnlimitedFilter())

I have tried in console as well (with the modification you suggested @Antoine Berry The error message is still the same:

searchProvider.png

I see that we are using scriptrunner 6.5.0-p5, not the latest. I will request and update but do not expect that to help as there is no indication in the change-log that a related bug is closed. 

One interesting question to get answered is this: is it only me, or is this also an issue for others using version  8.5.6 of JIRA.

Is there other tools that needs a specific version as well or are all the libs included in the JIRA install?

Antoine Berry
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
August 19, 2020

You are fine with this jira version & script runner version, there is no need for another install. Have you tried actually running the script ? The console will often come up with errors since type checking is not always possible in groovy. 

Maybe add some logs in there to clearly identify the issue. I will be able to take a look later if needed.

Lars Sundell August 19, 2020

I did disable the script earlier, but enabled it again now. The error message after the failed run is; 

Time (on server): Wed Aug 19 2020 14:07:18 GMT+0200 (Central European Summer Time)

The following log information was produced by this execution. Use statements like:log.info("...") to record logging information.

2020-08-19 14:07:18,450 ERROR [runner.AbstractScriptListener]: *************************************************************************************
2020-08-19 14:07:18,450 ERROR [runner.AbstractScriptListener]: Script function failed on event: com.atlassian.jira.event.issue.IssueEvent, file: null
groovy.lang.MissingMethodException: No signature of method: com.atlassian.jira.issue.search.providers.LuceneSearchProvider.search() is applicable for argument types: (com.atlassian.query.QueryImpl, com.atlassian.jira.web.bean.PagerFilter) values: [{issue in childIssuesOf(SI-10)}, com.atlassian.jira.web.bean.PagerFilter@3c86d2e3[start=0,end=2147483647,max=2147483647]]
Possible solutions: search(com.atlassian.jira.issue.search.SearchQuery, com.atlassian.jira.web.bean.PagerFilter), search(com.atlassian.jira.issue.search.SearchQuery, com.atlassian.jira.web.bean.PagerFilter, java.util.Set), search(com.atlassian.jira.issue.search.SearchQuery, org.apache.lucene.search.Collector), each(groovy.lang.Closure)
 at Script540.run(Script540.groovy:22)
Lars Sundell August 19, 2020

I added some log.warn lines to the script to try to shake some more info out of the run: 

if(issue.issueType.name=="Epic") 
{
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
log.warn("jqlQueryParser: " + jqlQueryParser)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class)
log.warn("searchProvider: " + searchProvider)
def issueManager = ComponentAccessor.getIssueManager()
log.warn("issueManager: " + issueManager)
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
log.warn("user: " + user)
def query = jqlQueryParser.parseQuery("issue in childIssuesOf(\"${issue.key}\")")
log.warn("query: " + query)
def results = searchProvider.search(query, PagerFilter.getUnlimitedFilter())
log.warn("results: " + results)

 

The result is: 

2020-08-19 15:08:45,542 WARN [runner.ScriptBindingsManager]: jqlQueryParser: com.atlassian.jira.jql.parser.DefaultJqlQueryParser@70752ae7
2020-08-19 15:08:45,543 WARN [runner.ScriptBindingsManager]: searchProvider: com.atlassian.jira.issue.search.providers.LuceneSearchProvider@7c4f849e
2020-08-19 15:08:45,543 WARN [runner.ScriptBindingsManager]: issueManager: com.atlassian.jira.issue.managers.RequestCachingIssueManager@4164483
2020-08-19 15:08:45,543 WARN [runner.ScriptBindingsManager]: user: lt(lt)
2020-08-19 15:08:45,543 WARN [runner.ScriptBindingsManager]: query: {issue in childIssuesOf(SI-10)}
2020-08-19 15:08:45,545 ERROR [runner.AbstractScriptListener]: *************************************************************************************
2020-08-19 15:08:45,545 ERROR [runner.AbstractScriptListener]: Script function failed on event: com.atlassian.jira.event.issue.IssueEvent, file: null
groovy.lang.MissingMethodException: No signature of method: com.atlassian.jira.issue.search.providers.LuceneSearchProvider.search() is applicable for argument types: (com.atlassian.query.QueryImpl, com.atlassian.jira.web.bean.PagerFilter) values: [{issue in childIssuesOf(SI-10)}, com.atlassian.jira.web.bean.PagerFilter@4765e3da[start=0,end=2147483647,max=2147483647]]
Possible solutions: search(com.atlassian.jira.issue.search.SearchQuery, com.atlassian.jira.web.bean.PagerFilter), search(com.atlassian.jira.issue.search.SearchQuery, com.atlassian.jira.web.bean.PagerFilter, java.util.Set), search(com.atlassian.jira.issue.search.SearchQuery, org.apache.lucene.search.Collector), each(groovy.lang.Closure)
 at Script700.run(Script700.groovy:26)
Antoine Berry
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
August 20, 2020

I actually use searchService instead of searchProvider. This is working fine for me, Jira 8.5.5 : 

jqlSearch = "issue in childIssuesOf(\"${issue.key}\")"

SearchService searchService = ComponentAccessor.getComponent(SearchService.class)
def userManager = ComponentAccessor.getUserManager()
IssueManager issueManager = ComponentAccessor.getIssueManager()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
List<Issue> issues = null
SearchService.ParseResult parseResult = searchService.parseQuery(user, jqlSearch)
if (parseResult.isValid()) {
def searchResult = searchService.search(user, parseResult.getQuery(), PagerFilter.getUnlimitedFilter())
issues = searchResult.results.collect {issueManager.getIssueObject(it.id)}
log.warn("issues : " + issues)
} else {
log.error("Invalid JQL: " + jqlSearch);
}

Antoine

Like Lars Sundell likes this
Lars Sundell August 31, 2020

Hello again

I was sure I had posted my final comment on this issue, but see that it is not here.

With the pointers from @Antoine Berry and some reverse engineering (I call it that since I am on very thin ice when trying to write groovy scripts) I ended up with somthing that works fine: 

import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.web.bean.PagerFilter

def issue = event.issue as Issue

if(issue.issueType.name=="Epic")
{
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def jqlSearch = "\"Epic Link\" = \"${issue.key}\""
SearchService searchService = ComponentAccessor.getComponent(SearchService.class)
def userManager = ComponentAccessor.getUserManager()
IssueManager issueManager = ComponentAccessor.getIssueManager()
SearchService.ParseResult parseResult = searchService.parseQuery(user, jqlSearch)
log.warn("Search query: " + parseResult.getQuery())
List<Issue> issues = null
if (parseResult.isValid()) {
def searchResult = searchService.search(user, parseResult.getQuery(), PagerFilter.getUnlimitedFilter())
issues = searchResult.getResults()
log.warn("issues : " + issues) // got results in log
} else {
log.error("Invalid JQL: " + jqlSearch);
}

def customFieldManager = ComponentAccessor.getCustomFieldManager()
int cfViewersId = 11537 // viewers field
def cfViewers = customFieldManager.getCustomFieldObject(cfViewersId)
def cfViewersValue = issue.getCustomFieldValue(cfViewers)
log.error("Epic Project team : " + cfViewersValue)

issues.each {myIssue ->;
def docIssue = issueManager.getIssueObject(myIssue.id)
log.warn("IssueID : " + docIssue)
def cfViewersCurrentValue = docIssue.getCustomFieldValue(cfViewers)
log.warn("Project team to be replaced : " + cfViewersCurrentValue)
cfViewers.updateValue(null, docIssue, new ModifiedValue(cfViewersCurrentValue, cfViewersValue), new DefaultIssueChangeHolder())
}
}

And now it works as intended. Thanks for all the help :)

Like Antoine Berry likes this
0 votes
Humberto Gomes
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.
February 6, 2020

Hi,

here we have this request also, and so much more around this topic,

The solution was: https://marketplace.atlassian.com/apps/1211494/field-sync

Now, he have no code (we have also script runner licence). I made some balance comparing scripting dedicated hours, debug and maintence... and decide to by a comercial app.

Note: i not a field sync company comercial.

0 votes
Krisztian Kovacs
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.
March 27, 2019

Hi @Lev Ryvkin

oh boy, that is not a trivial task. But you seem to be on the right track.

What I'd try is:

1. get the custom field value of the epic

2. in the results.getIssues().each part, get the custom field for each issue and then change its value that you got from the epic's custom field

Does that make sense?

Suggest an answer

Log in or Sign up to answer