This script takes a list of custom field names, and searches each issue in the instance for places where that custom field has been used (i.e., where it has a value other than null).

In this way, we gain insight into the usage of custom fields within a Jira Cloud instance.

The script is interesting for a number of reasons. First, it’s another instance of us having to parse a rawBody response before we can make use of it. Second, it handles the need for pagination, which we’ve also talked about in recent posts.

My intent for this script is for it to serve as a basis for future custom field work in Jira Cloud. Namely, I’d like to be able to easily rename any field with “migrated” in the title.


import groovy.json.JsonSlurper
def stillPaginating = true
//Loop to paginate
def startAt = 0
//Start at a pagination value of 0
def maxResults = 50
//Increment pagination by 50
def issueIDs = []
def fieldNames = ["Actual end", "Actual start", "Change risk", "Epic Status"]
def customFieldMap = [: ]
//Get all the fields in the system
def fieldIDs = get("/rest/api/3/field")
  .header('Content-Type', 'application/json')
  .header('Accept', 'application/json')
def inputStream = fieldIDs.rawBody
def scanner = new java.util.Scanner(inputStream).useDelimiter("\\A")
String rawBody = scanner.hasNext() ? : ""
def json = new JsonSlurper().parseText(rawBody)
//The response is a rawBody, so we need to convert to JSON
json.each{ item ->
//Iterate through the fields in the system
    fieldNames.each{ fieldName ->
    //Iterate through the user-supplied list of fields
        if ( == fieldName) {
            //If the name of any of the fields matches one of the user-supplied field names
            customFieldMap[fieldName] =
          //Add that field name and ID to the map
while (stillPaginating) {
//Loop and paginate while this value is true
  def response = get("/rest/api/2/search?jql=&startAt=${startAt}&maxResults=${maxResults}")
    .header('Content-Type', 'application/json')
    .header('Accept', 'application/json')
 //Fetch the current batch of pagination values
  response.body.object.issues.each{ issue ->
      issue.fields.each{ field ->
          customFieldMap.each{ key, value ->
      if(field[value] != null){
      logger.warn("${issue.key} uses custom field ${key}. It has a value of ${field[value]}.")
    }catch(Exception e){
  if (issueIDs.size() < maxResults) {
     stillPaginating = false
     //Kill the pagination loop if we don't get a full batch of responses
  startAt += 50
  //Move to the next batch of pagination values

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>