Hi,
I am sharing this information for others to benefit. All our Atlassian products are in Server deployment. All applications are linked with Applink configuration.
Requirement:
Other use cases where this code might help:
Create a New Script Runner Macro in Confluence:
I have not used any parameter variable; only set one value for example but Unused
Then this code block
//MACRO Code
import org.apache.log4j.Level
import org.apache.log4j.Logger
def log = Logger.getLogger("com.onresolve.jira.groovy")
log.setLevel(Level.DEBUG)
//for SQL
import groovy.sql.Sql
import java.sql.Driver
//for BB APP Link
import com.atlassian.applinks.api.ApplicationLink
import com.atlassian.applinks.api.ApplicationLinkService
import com.atlassian.applinks.api.application.bitbucket.BitbucketApplicationType
import com.atlassian.applinks.api.application.jira.JiraApplicationType
import com.atlassian.sal.api.component.ComponentLocator
//Unused
def limitTags = parameters.limitTags as Integer ?: 10
def driver = Class.forName('org.postgresql.Driver').newInstance() as Driver
def props = new Properties()
props.setProperty("user", "<database username - make sure READ ONLY user>")
props.setProperty("password", "<password>")
def conn = driver.connect("jdbc:postgresql://dB_URL:5432/jira", props)
def sql = new Sql(conn)
def selectOptions = ""
//get filtered jira projects
try {
sql.eachRow("SELECT p.pname, p.pkey\
FROM nodeassociation na, projectcategory pc, project p\
WHERE na.sink_node_id=pc.id\
AND na.source_node_id=p.id\
AND na.sink_node_entity='ProjectCategory'\
AND na.association_type='ProjectCategory'\
AND pc.cname IN ('ProjectCategory_x', 'ProjectCategory_y')\
ORDER BY p.pname;") {
selectOptions = selectOptions + "<option value='" + it['pkey'] + "'>" + it['pname'] + " (" + it['pkey'] + ")"+ "</option>"
}
} finally {
sql.close()
}
def ApplicationLink getPrimaryBitBucketLink() {
def applicationLinkService = ComponentLocator.getComponent(ApplicationLinkService.class)
final ApplicationLink BBLink = applicationLinkService.getPrimaryApplicationLink(BitbucketApplicationType.class)
BBLink
}
def bb_app_link_id = getPrimaryBitBucketLink().getId()
def bb_url = getPrimaryBitBucketLink().getDisplayUrl()
def ApplicationLink getPrimaryJiraLink() {
def applicationLinkService = ComponentLocator.getComponent(ApplicationLinkService.class)
final ApplicationLink JIRALink = applicationLinkService.getPrimaryApplicationLink(JiraApplicationType.class)
JIRALink
}
def jira_app_link_id = getPrimaryJiraLink().getId()
def jira_url = getPrimaryJiraLink().getDisplayUrl()
//https://stiltsoft.com/blog/2017/11/table_filter_and_charts_with_team_calendars/
"Select Project: <select id='select_jira_project'><option value='None'>None</option>" + selectOptions + "</select>\
Number of Tags (max 10):<input id='input_limit_tags' value='10' size='4'>\
<button id='btn_get_bb_tags' class='aui-button aui-button-primary' disabled>Get BB Tags Data</button>\
<input id='input_bb_app_link_id' hidden value='" + bb_app_link_id + "'></input><input id='input_bb_url' hidden value='" + bb_url + "'></input>\
<input id='input_jira_app_link_id' hidden value='" + jira_app_link_id + "'></input><input id='input_jira_url' hidden value='" + jira_url + "'></input>\
POWN Issue Link:<a id='pown_link' href=''></a>\
<p id='p_spinner'>Click the button and please wait for loading the table...</p>\
<table width='80%' id='tbl_bb_tags' >\
<thead><tr><th>Project, repo</th><th>Tag/Version</th><th>Last Commit Date</th><th>Last Commit Message</th><th>Branch</th></tr></thead>\
<tbody></tbody>\
</table>\
"
//Macro Javascript code section
AJS.toInit(function() {
let buttonSelector = '#btn_get_bb_tags';
let button = document.querySelector(buttonSelector);
let selectSelector = '#select_jira_project';
let select = document.querySelector(selectSelector);
AJS.$("#p_spinner").css("visibility", "hidden");
function changeHandler(changeEvent) {
var selectedProject = AJS.$('#select_jira_project').children("option:selected").val();
AJS.$('#tbl_bb_tags tbody').empty();
if(selectedProject == 'None') {
AJS.$('#btn_get_bb_tags').prop('disabled', true);
} else {
AJS.$('#btn_get_bb_tags').prop('disabled', false);
AJS.$("#p_spinner").css("visibility", "visible");
}
}
function clickHandler(clickEvent) {
/*AJAX call to get 'BB Project and Repo' JIRA custom field value of selectedProject PROD_OWN Issue;
PROD_OWN is a JIRA project containing one issue for each other JIRA Project with respective project's meta data which can be used in many other places
for example ProductX has one JIRA issue with custom field 'BB Project and Repo' - customfield_14962 with values BitbucketProject,repo_slug as comma separated*/
var selectedProject = AJS.$('#select_jira_project').children("option:selected").val();
var jira_app_link_id = AJS.$('#input_jira_app_link_id').val();
var jira_url = AJS.$('#input_jira_url').val();
var jira_url_y = AJS.Confluence.getBaseUrl() + '/plugins/servlet/applinks/proxy?appId=' + jira_app_link_id +'&path=' + jira_url + '/rest/api/2/search?jql=%22Product%20to%20Own%22%20%3D' + selectedProject + '&fields=customfield_14962';
var jira_url_x = jira_url + '/rest/api/2/search?jql=%22Product%20to%20Own%22%20%3D' + selectedProject + '&fields=customfield_14962';
var bb_proj = "";
var bb_repo = "";
AJS.$.ajax({
url : jira_url_x,
type: 'get',
dataType: 'json',
async: false,
success: function(data) {
var pown_key = data['issues'][0]['key'];
AJS.$("#pown_link").attr("href", jira_url + '/browse/' + pown_key).text(pown_key);
var bb_proj_repo_Array = data['issues'][0]['fields']['customfield_14962'].split(',');
bb_proj = bb_proj_repo_Array[0];
bb_repo = bb_proj_repo_Array[1];
}
});
/*AJAX call to get tags from Bitbucket*/
var limitTags = AJS.$('#input_limit_tags').val();
if(parseInt(limitTags) > 10){
limitTags = 10;
}
var bb_app_link_id = AJS.$('#input_bb_app_link_id').val();
var bb_url = AJS.$('#input_bb_url').val();
var bb_url_x = AJS.Confluence.getBaseUrl() + '/plugins/servlet/applinks/proxy?appId=' + bb_app_link_id +'&path=' + bb_url + '/rest/api/1.0/projects/';
var bb_tags_url_x = AJS.Confluence.getBaseUrl() + '/plugins/servlet/applinks/proxy?appId=' + bb_app_link_id +'&path=' + bb_url + '/rest/api/1.0/projects/' + bb_proj + '/repos/' + bb_repo + '/tags?limit=' + limitTags;
AJS.$.ajax({
url : bb_tags_url_x,
type: 'get',
dataType: 'json',
async: false,
success: function(data) {
var tableBody = AJS.$('#tbl_bb_tags tbody');
var tag_name = "";
var last_commit_date = "";
var last_commit_message = "";
var branch_name = "";
AJS.$.each(data.values, function(index, thisTag) {
tag_name = '<a href="' + bb_url + '/projects/' + bb_proj + '/repos/' + bb_repo + '/commits/'+ thisTag['latestCommit'] + '">' + thisTag['displayId'] + '</a>';
/*AJAX to get branch for a given tag and its latestCommit*/
var bb_branch_url_x = AJS.Confluence.getBaseUrl() + '/plugins/servlet/applinks/proxy?appId=' + bb_app_link_id +'&path=' + bb_url + '/rest/branch-utils/1.0/projects/' + bb_proj + '/repos/' + bb_repo + '/branches/info/' + thisTag['latestCommit'] + '?limit=1';
AJS.$.ajax({
url : bb_branch_url_x,
type: 'get',
dataType: 'json',
async: false,
success: function(data) {
/*branch_name = data['values'][0]['displayId'];*/
AJS.$.each(data.values, function(index, thisBranch) {
if(thisBranch['displayId'].indexOf('refs/heads/bugfix') === -1
&& thisBranch['displayId'].indexOf('refs/heads/feature') === -1
&& thisBranch['displayId'].indexOf('refs/heads/hotfix') === -1
&& thisBranch['displayId'].indexOf('refs/heads/enh') === -1) {
branch_name = '<a href="' + bb_url + '/projects/' + bb_proj + '/repos/' + bb_repo + '/compare/commits?sourceBranch=refs%2Fheads%2F'+ thisBranch['displayId'] + '&targetBranch=refs%2Fheads%2Fmaster">' + thisBranch['displayId'] + '</a>';
}
})
}
});
var bb_commits_url_x = AJS.Confluence.getBaseUrl() + '/plugins/servlet/applinks/proxy?appId=' + bb_app_link_id +'&path=' + bb_url + '/rest/api/1.0/projects/' + bb_proj + '/repos/' + bb_repo + '/commits/' + thisTag['latestCommit'];
AJS.$.ajax({
url : bb_commits_url_x,
type: 'get',
dataType: 'json',
async: false,
success: function(data) {
last_commit_message = data['message'];
var committerDate = new Date(data['committerTimestamp']);
var month = committerDate.getMonth()+1;
if(committerDate.getDate() < 10) {
var date = '0' + committerDate.getDate();
} else {
var date = committerDate.getDate();
}
last_commit_date = committerDate.getFullYear() + '-' + month + '-' + date;
console.log(last_commit_date);
}
});
var tr = AJS.$('<tr></tr>');
tr.append(AJS.$('<td></td>').text(bb_proj + ', ' + bb_repo));
tr.append(AJS.$('<td></td>').html(tag_name));
tr.append(AJS.$('<td></td>').text(last_commit_date));
tr.append(AJS.$('<td></td>').text(last_commit_message));
tr.append(AJS.$('<td></td>').html(branch_name));
tableBody.append(tr);
}); /*AJS.$.each(data.values, function(index, thisTag)*/
} /* success of tags AJAX call */
});
AJS.$("#p_spinner").css("visibility", "hidden");
}
button.addEventListener('click', clickHandler);
select.addEventListener('change', changeHandler);
})
//Macro CSS style section
#select_jira_project {
height : 30px;
background-color: #ffffcc;
}
table {
border-collapse: collapse;
}
table, th, td {
border: 1px solid black;
color: black;
}
table thead th {
color: black;
background-color: #ffd9b3;
}
.hidden{
visibility: hidden;
}
Ramakrishnan Srinivasan
1 comment