英文:
ScriptRunner Merge Check for Bitbucket Get Associated Jira Issue
问题
我想设置一个合并检查,如果关联的Jira问题有任何阻塞任务,将会阻止合并。
在我来这里之前,我已经搜索了解决方案,并找到了以下示例。但是,就在import com.atlassian.jira.component.ComponentAccessor
的地方,我遇到了"无法解析类"的错误。我正在运行最新版本的Scriptrunner for Bitbucket Server v.7.10.0。
我尝试使用AppLinks,就像以下示例中所示,我发现我可以通过这种方式访问Jira API,但我不确定如何实际确定与触发合并分支关联的问题的任务ID。
我很难找到任何不涉及随机Adaptavist或Atlasian论坛帖子的最新文档。是否有人能提供如何入门的见解?
英文:
I would like to set up a Merge Check that will block a merge if the associated Jira Issue has any blocking tasks.
I have searched for the solution before coming here and found the following example. However, right at import com.atlassian.jira.component.ComponentAccessor
I get an "unable to resolve class" error. I am running the latest version of Scriptrunner for Bitbucket Server v.7.10.0.
I have attempted to use AppLinks as shown in the following example and see that I am able to access the Jira Api this way, however I am unsure of how to actually determine the Task Id of the issue linked to the triggering Merge Branch.
I am having a hard time finding any up to date documentation that doesn't involve random Adaptavist or Atlasian forumn posts. Does anyone have any insight for how I can get started?
答案1
得分: 1
以下是您要翻译的内容:
"The ComponentAccessor is no longer supported, and my non-descript errors were a result of lower permissions. Once being promoted to admin I was able to access the Script Editor window which allowed me to perform the following..."
"To replace the provided 'Is Blocked on Jira' example I instead created a Jira Issue Controller class that is responsible for accessing the information using appLinks and Jira API calls."
"import com.atlassian.applinks.api.ApplicationLinkResponseHandler
import com.atlassian.applinks.api.ApplicationLinkService
import com.atlassian.applinks.api.application.jira.JiraApplicationType
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.sal.api.net.Response
import com.atlassian.sal.api.net.ResponseException
import groovy.json.JsonSlurper
import static com.atlassian.sal.api.net.Request.MethodType.GET
// This class is responsible for retrieving specific issues from the Jira AppLink (api)
class IssueController{
private static String issueEndpoint = '/rest/api/2/issue/'
// doc - https://docs.atlassian.com/applinks-api/3.2/com/atlassian/applinks/api/ApplicationLinkResponseHandler.html
private static ApplicationLinkResponseHandler<Map> handler = new ApplicationLinkResponseHandler<Map>() {
// Triggered when a call to a remote server failed because the caller does not have an established session
// with the server and will need to authorize requests first by visiting the authorization URL provided by
// AuthorisationURIGenerator.
@Override
Map credentialsRequired(Response response) throws ResponseException {
return null
}
@Override
Map handle(Response response) throws ResponseException {
assert response.statusCode == 200
new JsonSlurper().parseText(response.getResponseBodyAsString()) as Map
}
}
static RestObjects.JiraIssue GetJiraIssue(String issueKey){
def appLinkService = ComponentLocator.getComponent(ApplicationLinkService)
def appLink = appLinkService.getPrimaryApplicationLink(JiraApplicationType)
def appLinkUrl = appLink.getDisplayUrl().toString()
// doc - https://docs.atlassian.com/applinks-api/3.2/com/atlassian/applinks/api/ApplicationLinkRequestFactory.html
def applicationLinkRequestFactory = appLink.createAuthenticatedRequestFactory()
// doc - https://docs.atlassian.applinks.api/3.2/com/atlassian/applinks/api/ApplicationLinkRequest.html
def linkRequest = applicationLinkRequestFactory.createRequest(GET, issueEndpoint + issueKey )
def response = linkRequest.execute(handler)
return new RestObjects.JiraIssue(response);
}
}"
"This class returns a custom object RestObjects.JiraIssue
I use to parse the specific API response Map into custom Classes. A short example of the JiraIssue class and how I am able to access the linked blocking issues is shown below."
"package JiraApp.RestObjects
class JiraIssue
{
String key
Fields fields
//public
JiraIssue(keyStr){
this.key = keyStr
}
JiraIssue(Map apiResponseMap)
{
this.key = apiResponseMap['key']
this fields = new Fields(apiResponseMap['fields'] as Map)
}
//Returns list of the keys linked blocking issues
String[] blockingIssueKeys(){
String[] keys = []
fields.issueLinks.each {
link ->
if(link.type.name == 'Blocks' && link.getInwardIssue() != null)
{
def inwardIssue = link.getInwardIssue()
keys += inwardIssue.key
}
}
return keys;
}
class Fields{
Fields(Map fieldsMap){....."
"The rest of this class uses nested classes to parse the input Maps for their fields into usable objects. It also contains objects/functions I have created for my specific application."
"I hope this answer is helpful to someone, the documentation on ScriptRunner for bitbucket is limited."
英文:
The ComponentAccessor is no longer supported, and my non-descript errors were a result of lower permissions. Once being promoted to admin I was able to access the Script Editor window which allowed me to perform the following...
To replace the provided "Is Blocked on Jira" example I instead created a Jira Issue Controller class that is responsible for accessing the information using appLinks and Jira API calls.
import com.atlassian.applinks.api.ApplicationLinkResponseHandler
import com.atlassian.applinks.api.ApplicationLinkService
import com.atlassian.applinks.api.application.jira.JiraApplicationType
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.sal.api.net.Response
import com.atlassian.sal.api.net.ResponseException
import groovy.json.JsonSlurper
import static com.atlassian.sal.api.net.Request.MethodType.GET
// This class is responsiblefor retrieving specific issues from the JiraAppLink (api)
class IssueController{
private static String issueEndpoint = "/rest/api/2/issue/"
// doc - https://docs.atlassian.com/applinks-api/3.2/com/atlassian/applinks/api/ApplicationLinkResponseHandler.html
private static ApplicationLinkResponseHandler<Map> handler = new ApplicationLinkResponseHandler<Map>() {
// Triggered when a call to a remote server failed because the caller does not have an established session
// with the server and will need to authorize requests first by visiting the authorization URL provided by
// AuthorisationURIGenerator.
@Override
Map credentialsRequired(Response response) throws ResponseException {
return null
}
@Override
Map handle(Response response) throws ResponseException {
assert response.statusCode == 200
new JsonSlurper().parseText(response.getResponseBodyAsString()) as Map
}
}
static RestObjects.JiraIssue GetJiraIssue(String issueKey){
def appLinkService = ComponentLocator.getComponent(ApplicationLinkService)
def appLink = appLinkService.getPrimaryApplicationLink(JiraApplicationType)
def appLinkUrl = appLink.getDisplayUrl().toString()
// doc - https://docs.atlassian.com/applinks-api/3.2/com/atlassian/applinks/api/ApplicationLinkRequestFactory.html
def applicationLinkRequestFactory = appLink.createAuthenticatedRequestFactory()
// doc - https://docs.atlassian.com/applinks-api/3.2/com/atlassian/applinks/api/ApplicationLinkRequest.html
def linkRequest = applicationLinkRequestFactory.createRequest(GET, issueEndpoint + issueKey )
def response = linkRequest.execute(handler)
return new RestObjects.JiraIssue(response);
}
}
This class returns a custom object RestObjects.JiraIssue
I use to parse the specific API response Map into custom Classes. A short example of the JiraIssue class and how I am able to access the linked blocking issues is shown below.
package JiraApp.RestObjects
class JiraIssue
{
String key
Fields fields
//public
JiraIssue(keyStr){
this.key = keyStr
}
JiraIssue(Map apiResponseMap)
{
this.key = apiResponseMap["key"]
this.fields = new Fields(apiResponseMap["fields"] as Map)
}
//Returns list of the keys linked blocking issues
String[] blockingIssueKeys(){
String[] keys = []
fields.issueLinks.each {
link ->
if(link.type.name == "Blocks" && link.getInwardIssue() != null)
{
def inwardIssue = link.getInwardIssue()
keys += inwardIssue.key
}
}
return keys;
}
class Fields{
Fields(Map fieldsMap){.....
The rest of this class uses nested classes to parse the input Maps for their fields into usable objects. It also contains objects/functions I have created for my specific application.
I hope this answer is helpful to someone, the documentation on ScriptRunner for bitbucket is limited.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论