NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name Jira no fix version in ready for release
// @namespace https://openuserjs.org/users/floodmeadows
// @description Show list of Jira tickets with a state of Ready for Release without a value for fix_version
// @copyright 2022, floodmeadows (https://openuserjs.org/users/floodmeadows)
// @license MIT
// @version 0.4
// @include https://jira.*.uk/secure/RapidBoard.jspa?rapidView=5483*
// @grant none
// @updateURL https://openuserjs.org/meta/floodmeadows/Jira_no_fix_version_in_ready_for_release.meta.js
// @downloadURL https://openuserjs.org/install/floodmeadows/Jira_no_fix_version_in_ready_for_release.user.js
// ==/UserScript==
// ==OpenUserJS==
// @authors floodmeadows
// ==/OpenUserJS==
/* jshint esversion: 6 */
//--- Enter your search query -----------//
const jql = 'MY_JIRA_SEARCH_QUERY'; // e.g. 'project = MY-PROJECT AND status in (LIST_OF_STATUS_VALUES) ORDER BY key'
//---------------------------------------//
const currentUrl = new URL(document.URL);
const myJiraBaseUrl = currentUrl.protocol + '//' + currentUrl.host;
(function () {
'use strict';
addPossibleIssuesContainer();
checkForProblemIssues();
})();
function addPossibleIssuesContainer() {
const parentElementId = 'ghx-modes-tools';
var subtasksToCheckContainer = document.createElement("div");
var t = "Possible issues: ";
subtasksToCheckContainer.setAttribute('id','subtasks-to-check-container');
subtasksToCheckContainer.setAttribute('style','position:absolute; top:4em; right:1.5em; margin-top:0.5em; text-align:right;');
document.getElementById(parentElementId).appendChild(subtasksToCheckContainer);
}
function checkForProblemIssues() {
var headers = new Headers();
headers.append("Content-Type", "application/json");
const baseApiUrl = myJiraBaseUrl + '/rest/api/latest/search';
const baseStoryUrl = myJiraBaseUrl + '/browse/';
const fields = 'key,summary,status';
const jiraApiSearchUrl = baseApiUrl + '?jql=' + encodeURI(jql) + '&fields=' + fields;
const jiraWebSearchUrl = myJiraBaseUrl + '/issues/?jql=' + encodeURI(jql);
console.log('api URL: ' + jiraApiSearchUrl);
console.log('web URL: ' + jiraWebSearchUrl);
var requestOptions = {
method: 'GET',
headers: headers
};
fetch(jiraApiSearchUrl, requestOptions)
.then(response => response.json())
.then(
json => {
var problemIssues = [];
// console.log('json = ' + JSON.stringify(json))
for (const [_, issue] of Object.entries(json.issues)) {
console.log("issue.fields.fixVersions = " + issue.fields.fixVersions);
if (issue.fields.status.name == "Ready for Release" && typeof(issue.fields.fixVersions == 'undefined')) {
problemIssues.push(" <a href='" + baseStoryUrl + issue.key + "' target='_blank' title='" + issue.fields.summary.replace(/'/g, "'") + "'>" + issue.key + "</a>");
console.log(baseStoryUrl + issue.key + " is in Ready for Release, but has no fixVersion.");
}
}
var e = document.getElementById('subtasks-to-check-container');
if (problemIssues.length > 0) {
console.log("R4R but no fix version: " + problemIssues);
e.innerHTML = '<a href="' + jiraWebSearchUrl + '" target="_blank">' + problemIssues.length + ' items</a> Ready for Release but no fix version: ' + problemIssues;
} else {
e.innerHTML = "All good: Ready for Release tickets all have fixVersions.";
}
}
)
.catch(error => console.log('error', error));
}