Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

ScriptRunner: Getting list of Boards in a Project

Jürgen Talik January 11, 2023

I want to get boards connected to specific project using ScriptRunner and Jira Java API.

 

According to documentation there is interface called BoardManager which includes method called getBoardsForProject(long projectId). This sounds like exactly what I need but for some reason, no matter the project, it always returns null.


Here's my ScriptRunner code:

 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.board.Board
import com.atlassian.jira.board.BoardManager

def boardManager = ComponentAccessor.getComponent(BoardManager);

def b = boardManager.getBoardsForProject(12401);

return b;

When using the same project id in REST API call /rest/agile/1.0/board?projectKeyOrId=12401, I'm getting the Boards I'm expecting. I know, it is possible to use REST API calls in ScriptRunner as well, but this is something I don't want to do.

Any ideas, how to modify my script to get the needed data?

 

3 answers

1 accepted

1 vote
Answer accepted
Graham Twine
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 2, 2023
//I have tried the following and all return nothing. The Rapidview service is not even returning an instnace of the service :(

import
org.apache.log4j.Level
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.ServiceOutcome
import com.atlassian.jira.board.BoardManager
import com.atlassian.jira.board.BoardService
import com.atlassian.jira.board.Board
import com.atlassian.jira.board.store.BoardStore
import com.atlassian.greenhopper.service.rapid.view.RapidViewService
import com.atlassian.greenhopper.service.sprint.SprintService
import com.atlassian.jira.user.ApplicationUser

log.setLevel(Level.DEBUG)

def boardManager = ComponentAccessor.getComponent(BoardManager)
def boardService = ComponentAccessor.getComponent(BoardService)
def boardStore = ComponentAccessor.getComponent(BoardStore)
def rapidViewService = ComponentAccessor.getComponent(RapidViewService)
def sprintService = ComponentAccessor.getComponent(SprintService)
def projectManager = ComponentAccessor.projectManager

ApplicationUser me = ComponentAccessor.jiraAuthenticationContext.loggedInUser

String result = "<span>Hi</span>"
def out = rapidViewService.getRapidViews(me)
out.get().each {
result += "<br />$it"
}

projectManager.projects.each { project ->
List<Board> projectBoards = boardManager.getBoardsForProject(project.id)
result += "<br />$project -> $projectBoards"
projectBoards.each { board ->
result += "<br/>$project -> $board"
}

projectBoards = boardStore.getBoardsForProject(project.id)
result += "<br />$project -> $projectBoards"
projectBoards.each{ board ->
result += "<br />$project -> $board"
}

ServiceOutcome<List<Board>> outcome = boardService.getBoardsForProject(me, project.id)
projectBoards = outcome.get()
result += "<br />$project -> $projectBoards"
projectBoards.each { board ->
result += "<br />$project -> $board"
}
}

return result
Graham Twine
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 2, 2023

I have found two ways to get to these services and managers.

1)

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.greenhopper.service.rapid.view.RapidViewService
def rapidViewService = ComponentAccessor.getOSGiComponentInstanceOfType(RapidViewService)
2)
import com.atlassian.greenhopper.service.rapid.view.RapidViewService
import com.onresolve.scriptrunner.runner.customisers.JiraAgileBean
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
@WithPlugin( "com.pyxis.greenhopper.jira" )
@JiraAgileBean RapidViewService rapidViewService
I am getting useful data out of both mechanisms.
Jürgen Talik February 3, 2023

While this does return information about boards, it doesn't return a list of boards associated with each project. 

All three getBoardsForProject implementations still return null.

Code I tried:

import org.apache.log4j.Level
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.ServiceOutcome
import com.atlassian.jira.board.BoardManager
import com.atlassian.jira.board.BoardService
import com.atlassian.jira.board.Board
import com.atlassian.jira.board.store.BoardStore
import com.atlassian.greenhopper.service.rapid.view.RapidViewService
import com.atlassian.greenhopper.service.sprint.SprintService
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.greenhopper.service.rapid.view.RapidViewService

log.setLevel(Level.DEBUG)

def boardManager = ComponentAccessor.getComponent(BoardManager)
def boardService = ComponentAccessor.getComponent(BoardService)
def boardStore = ComponentAccessor.getComponent(BoardStore)
def rapidViewService = ComponentAccessor.getOSGiComponentInstanceOfType(RapidViewService)
def sprintService = ComponentAccessor.getComponent(SprintService)
def projectManager = ComponentAccessor.projectManager

ApplicationUser me = ComponentAccessor.jiraAuthenticationContext.loggedInUser

String result = "<span>Hi</span>"
def out = rapidViewService.getRapidViews(me)
out.get().each {
result += "<br />$it"
}

projectManager.projects.each { project ->
List<Board> projectBoards = boardManager.getBoardsForProject(project.id)
result += "<br />$project -> $projectBoards"
projectBoards.each { board ->
result += "<br/>$project -> $board"
}

projectBoards = boardStore.getBoardsForProject(project.id)
result += "<br />$project -> $projectBoards"
projectBoards.each{ board ->
result += "<br />$project -> $board"
}

ServiceOutcome<List<Board>> outcome = boardService.getBoardsForProject(me, project.id)
projectBoards = outcome.get()
result += "<br />$project -> $projectBoards"
projectBoards.each { board ->
result += "<br />$project -> $board"
}
}

return result

 Result:

Project: TSTKB -> []
Project: TSTKB -> []
Project: TSTKB -> []
Project: ATDEV -> []
Project: ATDEV -> []
Project: ATDEV -> []
Project: AV -> []
Project: AV -> []
Project: AV -> []
Project: ATL -> []
Project: ATL -> []
Project: ATL -> []
etc
Graham Twine
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, 2023 edited

It just turns out this is part of Jira Agile so this is the place to do things regarding sprints, ranking, boards etc.

 

com.atlassian.greenhopper.service.rapid.view.RapidViewService

 

import com.atlassian.greenhopper.service.rapid.view.RapidViewService
import com.atlassian.greenhopper.service.sprint.SprintService
import com.atlassian.greenhopper.service.sprint.SprintManager
import com.atlassian.greenhopper.service.sprint.SprintIssueService
import com.atlassian.greenhopper.service.sprint.SprintQueryService
import com.atlassian.greenhopper.service.sprint.SprintHistoryService
import com.atlassian.greenhopper.service.sprint.Sprint
import com.atlassian.greenhopper.service.sprint.Sprint.SprintBuilder
import com.onresolve.scriptrunner.runner.customisers.JiraAgileBean
import com.onresolve.scriptrunner.runner.customisers.WithPlugin


@WithPlugin( "com.pyxis.greenhopper.jira" )
@JiraAgileBean RapidViewService rapidViewService
@JiraAgileBean SprintIssueService sprintIssueService
@JiraAgileBean SprintQueryService sprintQueryService
@JiraAgileBean SprintHistoryService sprintHistoryService
@JiraAgileBean SprintManager sprintManager
@JiraAgileBean SprintService sprintService

 

Graham Twine
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, 2023

After bumbling about a bit I have found what I think you are looking for @Jürgen Talik 

 

import org.apache.log4j.Level

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.ApplicationUser

import com.atlassian.jira.project.ProjectManager
import com.atlassian.jira.project.Project

import com.atlassian.greenhopper.service.ServiceOutcome
import com.atlassian.greenhopper.service.rapid.ProjectRapidViewService

import com.atlassian.greenhopper.model.rapid.RapidView

import com.onresolve.scriptrunner.runner.customisers.JiraAgileBean
import com.onresolve.scriptrunner.runner.customisers.WithPlugin

log.setLevel(Level.INFO)

@WithPlugin('com.pyxis.greenhopper.jira')
@JiraAgileBean ProjectRapidViewService projectRapidViewService
ProjectManager projectManager = ComponentAccessor.projectManager

ApplicationUser me = ComponentAccessor.jiraAuthenticationContext.loggedInUser

// @FIXME Use markup builder instead
String result = ''

String[] keys = ['TSTKB', 'ATDEV', 'AV', 'ATL']

keys.each { pKey ->
Project project = projectManager.getProjectByCurrentKey(pKey)
log.info("Searching for rapid view bords that belong to ${project.name}")

result += "<h3>${project.key}</h3>"
projectRapidViewService.findRapidViewsByProject(me, project).each { outcome ->
List<RapidView> boards = ((ServiceOutcome<List<RapidView>>)outcome).value

boards.each { rv ->
result += "${rv.name}<br/>"
}
}

result += "<hr />"
}
return result
Like Jürgen Talik likes this
Jürgen Talik February 6, 2023 edited

Fantastic, thank you @Graham Twine! Indeed, ProjectRapidViewService was the missing piece of the puzzle!

Here is my MVP code for anyone interested:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.project.ProjectManager
import com.atlassian.jira.project.Project
import com.atlassian.greenhopper.service.rapid.ProjectRapidViewService
import com.atlassian.greenhopper.model.rapid.RapidView
import com.onresolve.scriptrunner.runner.customisers.JiraAgileBean
import groovy.json.JsonOutput

@JiraAgileBean ProjectRapidViewService projectRapidViewService

ProjectManager projectManager = ComponentAccessor.projectManager;
ApplicationUser currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser();

Project project = projectManager.getProjectObj(12401);

log.warn("List of boards for project: ${project.getKey()}");

List<RapidView> boards = projectRapidViewService.findRapidViewsByProject(currentUser, project).value;

log.warn(JsonOutput.toJson(boards));

Edit: Optimized the code a bit. 

Like 3 people like this
Graham Twine
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, 2023 edited

@Jürgen Talikcan you mark this as accepted if it is the correct response

 

Including the filter query for each board and format into a table.

I really should be using the MarkupBuilder instad of formatting HTML in strings :(

import org.apache.log4j.Level

import com.atlassian.jira.component.ComponentAccessor

import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.issue.search.SearchRequestManager
import com.atlassian.jira.issue.search.SearchRequest
import com.atlassian.jira.project.ProjectManager
import com.atlassian.jira.project.Project

import com.atlassian.greenhopper.service.ServiceOutcome
import com.atlassian.greenhopper.service.rapid.ProjectRapidViewService
import com.atlassian.greenhopper.model.rapid.RapidView

import com.onresolve.scriptrunner.runner.customisers.JiraAgileBean
import com.onresolve.scriptrunner.runner.customisers.WithPlugin

log.setLevel(Level.INFO)

@WithPlugin('com.pyxis.greenhopper.jira')
@JiraAgileBean ProjectRapidViewService projectRapidViewService
ProjectManager projectManager = ComponentAccessor.projectManager
SearchRequestManager srManager = ComponentAccessor.getComponent(SearchRequestManager)
ApplicationUser me = ComponentAccessor.jiraAuthenticationContext.loggedInUser

String[] keys = ['TSTKB', 'ATDEV', 'AV', 'ATL']

// @FIXME Use markup builder instead
String result = ''

keys.each { pKey ->
Project project = projectManager.getProjectByCurrentKey(pKey)
String projectData = "<h3>${project.key} ${project.name}</h3>"

projectData +=
"""<table class="aui aui-table-sortable">
<thead>
<tr>
<th>Board Id</th>
<th>Board Name</th>
<th>Filter Query</th>
</tr>
</thead>
<tbody>

"""

projectRapidViewService.findRapidViewsByProject(me, project).each { outcome ->
List<RapidView> boards = ((ServiceOutcome<List<RapidView>>)outcome).value
boards.each { rv ->
SearchRequest sr = srManager.getSearchRequestById(rv.savedFilterId)
projectData += "<tr><td>${rv.id}</td><td>${rv.name}</td><td>${sr.query}</td></tr>"
}
}
projectData += "</tbody></table>"
result += projectData
}

return result
Italo _Modus Create_
Contributor
April 11, 2023

@Graham Twine Amazing script!

We are migrating a JIRA Server to Cloud and many business project were failing because they were used in kanban board (see limitation below)

We adapted the script to fetch all projects of business type:

// add import for 
import java.util.stream.Collectors


// replace keys variable to populate with all projects with type Business
// String[] keys = ['TSTKB', 'ATDEV', 'AV', 'ATL']

String[] keys = projectManager.getProjectObjects().stream().filter(it -> it.getProjectTypeKey().getKey().equals("business")).map(it->it.getKey()).collect(Collectors.toList()).toArray()
Like Graham Twine likes this
Graham Twine
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.
April 12, 2023

One could use some criteria such as project category or type get a list of projects instead of just adding a list.

 

In Scriptrunner ...



projectManager.projectObjects.findAll { project ->
project.projectTypeKey.key == "business"
}.each {
// do something with the filtered projects such as above
}

0 votes
Henrique Bittencourt July 7, 2023

@Jürgen Talik 

Is there any chance of getting a Jira Cloud version of this SR code?

Jürgen Talik July 10, 2023

Not from me, sorry. It would take some time to come up with that.

0 votes
Trudy Claspill
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
January 11, 2023

Hello @Jürgen Talik 

Welcome to the Atlassian community!

What version of Jira are you using?

Jürgen Talik January 12, 2023

Hi! Jira version is 8.20.10.

Suggest an answer

Log in or Sign up to answer
TAGS
atlassian, ace, atlassian community event, donation, girls who code, women in tech, malala fund, plan international, kudos, community badge, badge, atlassian badge, International Women’s month, International Women’s Day, women's month, women's day

10 for Change at Atlassian Community Events

Show up and give back by attending an Atlassian Community Event: we’ll donate $10 for every event attendee in March!

Join an Atlassian Community Event!
AUG Leaders

Upcoming Jira Events