Synchronize associated custom field once per script

If you have created a new custom field of type single-line text or single-select having the same name as a traffic-light field, then this new field is treated as an associated field. Its content will be set to the label of the related traffic-light field when a user changes this traffic-light field. Suppose a user modifies the label of the new custom field. In that case, the content of the associated traffic-light field will be updated automatically the next time this traffic-light field is rendered.

You can use the following script to copy the current labels of a specific traffic-light field into their associated custom fields for all project issues once.

 Instructions

  1. Use a suitable test environment for the following steps to become familiar with what you are doing without any impact on your production data: a separate test instance, sandbox, or a simple test project with sample data.

  2. Log in as a Jira system admin and call an issue of your project you are focussing on.

  3. Open your browser’s web dev tools (generally, hit F12 or the equivalent browser menu item).

  4. Before running the script, you must switch to the correct context within your browser. Below, you will find a screen copy of Firefox’s web dev tools and the necessary steps.

  5. Modify the two constants in lines 2 and 3 of the script below representing your traffic-light field name and related project key.
    PAY ATTENTION: if your field name contains foreign characters like French “é”, etc., you may have to update the script manually because the related property name may differ. Use the free app “https://marketplace.atlassian.com/apps/1214509/entity-property-tool-for-jira?hosting=cloud&tab=overview“ of Atlassian labs to verify that issue entity property name. Generally, a space within the name will be replaced by Jira natively by a plus (“+”), which the script handles automatically.

  6. Copy and paste the updated script into your browser’s console and hit ENTER to execute/run this script. Within the console, you will see the issues updated as log entries.

  7. Verify that everything works as you expect.

  8. Repeat the successful steps within your production environment/project.

// PLEASE MODIFY THE FOLLOWING 2 CONSTANTS ACCORDING TO YOUR NEEDS const trafficLightFieldName = 'risk'; const projectKey = 'XYZ'; const jql = `project = "${projectKey}"`; var setAssociatedCustomfield = function(trafficLightField, issueKey, propertyValue) { // if associated customfield exist, then update it's content accordingly var index = -1; var name = trafficLightField.name; for (var i = 0; index == -1 && i < trafficLight.systemfields.length; i++) { if (trafficLight.systemfields[i].custom && (trafficLight.systemfields[i].name === name || trafficLight.systemfields[i].untranslatedName === name)) index = i; } if (propertyValue && index > -1) { var data = propertyValue.match(/([(\[<{*]+[^,>)\]}*]*(,[^,>)\]}*]*,[^,>)\]}*]*){0,1}[,>)\]}*](\s*TREND){0,1})(.*)/); var label = (data != null ? data[4].trim() : ""); var fields = {}; if (trafficLight.systemfields[index].schema.type === "option") { fields[trafficLight.systemfields[index].id] = { value: label }; } else fields[trafficLight.systemfields[index].id] = label; AP.request({ url: '/rest/api/2/issue/' + issueKey, type: 'PUT', data: JSON.stringify({ "fields": fields }), success: function(fields) { console.log("[Traffic-Light] successfully updated issue " + issueKey + "'s associated customfield"); }, error: function(arguments) { console.log(arguments); }, contentType: "application/json" }); } }; function getIssues(jql, startAt=0) { const chunk = 20; AP.request({ url: `/rest/api/3/search?maxResults=${chunk}&startAt=${startAt}&jql=${jql}&properties=${trafficLightFieldName.replace(/ /g,"%2B")}`, type: 'GET', contentType: "application/json", success: function(data) { data = JSON.parse(data); console.log(data.issues); if (data.startAt + data.issues.length < data.total) setTimeout(() => { getIssues(jql, startAt + chunk); }, 1000); data.issues.forEach(issue => { const propertyValue = issue.properties[trafficLightFieldName.replace(/ /g,"+")]?.content; if (propertyValue) { console.log("updating " + issue.key + ": set " + trafficLightFieldName + " to label of", propertyValue); setAssociatedCustomfield(trafficLight.fields.active.global.find(field => field.name == trafficLightFieldName), issue.key, propertyValue); } else console.log("no updating " + issue.key + ": empty propertyValue"); }); }, error: function(arguments) { console.log(arguments); } }); } getIssues(jql);