Example scripts
To homepage
Bitbucket

Prevent Branch Creation If Branch Name Lacks a Valid Jira Issue With Specific Status
App in script

ScriptRunner For Bitbucket
by Adaptavist
Compatibility

Bitbucket (6.0 - 7.17)

ScriptRunner For Bitbucket (7.10.0)
Language |
groovy
import com.atlassian.applinks.api.ApplicationLinkResponseHandler
import com.atlassian.applinks.api.ApplicationLinkService
import com.atlassian.applinks.api.application.jira.JiraApplicationType
import com.atlassian.bitbucket.hook.repository.RepositoryHookResult
import com.atlassian.bitbucket.repository.MinimalRef
import com.atlassian.bitbucket.repository.RefChangeType
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.sal.api.net.Request
import com.atlassian.sal.api.net.Response
import com.atlassian.sal.api.net.ResponseException
import groovy.json.JsonSlurper
private RepositoryHookResult rejectedResult(String message) {
RepositoryHookResult.rejected(message, message)
}
private RepositoryHookResult getIssueKeyValidationResult(String issueKey, String requiredStatusName, MinimalRef branchRef) {
def applicationLinkService = ComponentLocator.getComponent(ApplicationLinkService)
def primaryJiraApplicationLink = applicationLinkService.getPrimaryApplicationLink(JiraApplicationType)
def authenticatedRequestFactory = primaryJiraApplicationLink.createImpersonatingAuthenticatedRequestFactory() ?:
primaryJiraApplicationLink.createAuthenticatedRequestFactory()
authenticatedRequestFactory.createRequest(Request.MethodType.GET, "rest/api/2/issue/$issueKey")
.addHeader('Content-Type', 'application/json')
.execute(new ApplicationLinkResponseHandler<RepositoryHookResult>() {
@Override
RepositoryHookResult credentialsRequired(Response response) throws ResponseException {
rejectedResult(
"Please authenticate with Jira: ${authenticatedRequestFactory.authorisationURI}"
)
}
@Override
RepositoryHookResult handle(Response response) throws ResponseException {
if (!response.successful) {
if (response.statusCode == 404) {
return rejectedResult(
"Branch with name: ${branchRef.displayId} matches Jira issue key: $issueKey but no issue with this key exists, branch creation cancelled."
)
}
log.warn("Jira call failed, status: ${response.statusCode}.")
return rejectedResult(
'Validation of issue key in branch name failed, please contact your system administrator.'
)
}
def issueJson = new JsonSlurper().parseText(response.responseBodyAsString) as Map<String, Object>
def statusName = issueJson['fields']['status']['name'] as String
if (!requiredStatusName.equalsIgnoreCase(statusName)) {
return rejectedResult(
"Issue with key: $issueKey was found from branch name, but its status: ($statusName) does not match the required status name: ($requiredStatusName)."
)
}
RepositoryHookResult.accepted()
}
})
}
def builder = new RepositoryHookResult.Builder()
/// The name of the status which the issue from the branch name must be in (this is checked case insensitively).
def requiredStatusName = 'In Progress'
// A regular expression for extracting Jira issue keys from branch names, this is the default regular expression used by Bitbucket.
// If your Jira issue keys do not match the default pattern, alterations will need to be made here.
def jiraIssueKeyPattern = ~'(?<=^|[a-z]\\-|[\\s\\p{Punct}&&[^\\-]])([A-Z][A-Z0-9_]*-\\d+)(?![^\\W_])'
// Find all created refs which relate to a branch creation
def createdBranchRefs = refChanges.find { it.type == RefChangeType.ADD && it.refId.startsWith('refs/heads') }*.ref
// For each created branch ref, check the branch name for an issue key, and then verify the status of that issue via a linked Jira instance.
createdBranchRefs.each { branchRef ->
def matcher = branchRef.id =~ jiraIssueKeyPattern
if (matcher.find()) {
def issueKey = matcher.group(1)
builder.add(getIssueKeyValidationResult(issueKey, requiredStatusName, branchRef))
} else {
def message = "Branch with name: ${branchRef.displayId} does not contain a reference to a Jira issue."
builder.add(rejectedResult(message))
}
}
builder.build()
Having an issue with this script?
Report it here