Introduction

So you or your organization have decided to purchase, or at least trial, ScriptRunner. Now what?

If you’re going to learn how to use ScriptRunner, I would very strongly advise that you set it up in a test environment.  This allows you to learn to use the tool, and to not have to worry about making mistakes or deleting production data.

In order to use ScriptRunner, you’ll need to be an admin on the Jira system in question.   As well, I’ll do my best to explain the Groovy code that we’re using, but it would be of great benefit for you to read some primary learning materials on the subject.   Some of what I’ll say will assume a basic knowledge of object-oriented programming principles.   Please note that Groovy is case-sensitive, but is agnostic to whitespace.

All of the testing and learning we’re going to be doing is done in the ScriptRunner Script Console.   You can think of this as sort of a window into your Jira system, in which Groovy code can be run.  The Script Console is accessed by going to your Jira System Setings > Manage Apps > ScriptRunner > Script Console.  ScriptRunner has many more features than just the Console, but this is where we’ll go to run one-off code:

 

 

 

 

 

Getting Started With Imports

So you’ve accessed the Script Console. It’s pretty empty. Now what?  

In this post we’re going to learn how to use ScriptRunner to return the key of every project in a Jira instance.

Let’s talk about imports.  Imports are a standard aspect of almost every programming language, and they allow you to bring in additional functionality in the form of code libraries.  Libraries are simply a preconfigured set of tools or functions available to anyone who wants to use them in their code.   Almost any Groovy script that you want to write for Jira is going to involve the Component Accessor, so let’s start by importing that library with the following import statement:
import com.atlassian.jira.component.ComponentAccessor

On its own, this doesn’t do anything.  But it allows us to use the Component Accessor class in our code, and the Component Accessor is our gateway to all of Jira’s functionality.  Think of the Component Accessor as almost like a translator.   Jira’s code library has many hundreds and hundreds of functions, but the Component Accessor is what allows the ScriptRunner Script Console to make use of those libraries. Let’s look at an example.

 

Using the Component Accessor

Still with our import statement, we’re going to use the Component Accessor to access a part of the Jira library.  Add the following statement below your import statement:

def  allProjects =  ComponentAccessor.GetProjectManager()

Let’s examine what we just added.  def is short for define, and is telling the Script Console that we want to define a new object.  allProjects is the name we’re giving to the new object, as our intention is to have it hold a record of all of the projects in the system.  Notice what comes next. We have invoked the ComponentAccessor, and accessed a method of that class called projectManager.  If you simply type ComponentAccessor. and stop typing after the period, the Script Console should suggest to you a list of all of the available methods that the ComponentAccessor can currently access.

If we were to add an import statement, further methods would become available to the ComponentAccessor, and would appear in the list.  This manner of accessing the specifics of something by referring to the object with a period is foundational to using Groovy and ScriptRunner.

Okay so we used our ComponentAccessor to create an object called allProjects, which is actually of the type ProjectManager.   What use is that?

 

Defining a Collection of Objects

Under the code you’ve already added, type def projects = allProjects., not forgetting to include the period.  As before, we’ve declared a new object.  This object will contain some aspect of the allProjects object.  After the dot, we’re presented with a list of methods or functions that the allProjects object can impart upon our newly declared object. The one we’re interested in is simply called projects:

 

That leaves us with a script console that should contain the following:

import com.atlassian.jira.component.ComponentAccessor

def  allProjects =  ComponentAccessor.projectManager

def projects = allProjects.projects

 

Getting to the Good Stuff

Finally, we’ve reached the point in the script where we have something concrete to work with.   We now have a collection of objects, and we called that collection projects. Each item in that collection is itself a collection of information about one project in the instance.

Because projects is a collection of pieces of information, we’ll need to tell the Script Console to return each piece one at a time.  There are many ways to do this, but we’re going to do it with a closure.  Consider the following code:

import com.atlassian.jira.component.ComponentAccessor
def  allProjects =  ComponentAccessor.projectManager
def projects = allProjects.projects


projects.each{ project ->

log.warn(project.key)
}

 

What we’re telling the Script Console is that for each item in the collection of items called project, we want to do something with that item.  We’re looping or iterating through the collection of items.  Each time we loop and a new item is returned from the collection, we’re simply referring to that item as project.  We could have used any word instead of project, but that word makes the most sense in this context.

So the closure loops through each item, referring to each item as project as it considers them in turn.   We’ve told the closure that for each instance of something called project, we want the project key to be logged in the log file.   We could have told it to return any aspect of the project, so long as it was available to us using that same dot notation.

In fact, within that closure we could have done most anything we wanted to the project objects.   Returning information about them is the simplest example, but the object is yours to do with as you wish.  Speaking of output, let’s look at the expected format.
Right below the blue RUN button on your screen, it should say Result and Logs. The information your script outputs will appear in one of these two places, depending on how you ask the script to return data.   In this case we want the Log tab, since we sent information to the log file:

2023-02-03 21:23:47,232 WARN [runner.ScriptBindingsManager]: DELETEME
2023-02-03 21:23:47,256 WARN [runner.ScriptBindingsManager]: DESS
2023-02-03 21:23:47,256 WARN [runner.ScriptBindingsManager]: DES
2023-02-03 21:23:47,257 WARN [runner.ScriptBindingsManager]: DEMO
2023-02-03 21:23:47,257 WARN [runner.ScriptBindingsManager]: DMCA
2023-02-03 21:23:47,257 WARN [runner.ScriptBindingsManager]: DMCB
2023-02-03 21:23:47,257 WARN [runner.ScriptBindingsManager]: KDES
2023-02-03 21:23:47,257 WARN [runner.ScriptBindingsManager]: NMC
2023-02-03 21:23:47,257 WARN [runner.ScriptBindingsManager]: SD

Your output will undoubtedly be different, as the keys of your projects will be different, but that’s it!

 

Wrapping Up

So what have we done? We imported the Component Accessor, and used that to access the Jira ProjectManager library.   We created a ProjectManager object called projects.   We told the Script Console to tell us about each of the objects in project but that we only wanted to know about the key of each of those items.  The Script Console printed the key of each item in projects to the log, and we got a list of every project key in Jira.

I encourage you to examine some of the methods and information available to you.  Try accessing information about the projects other than the key.  

The next blog post in this series will focus on a more complex example of how an admin might make use of ScriptRunner to return information about a project.

 

3 thoughts on “ScriptWalking #2 – How Do I Use This Thing? (Server/DC)

    • And does log.warn produce output with the default log level of ScriptRunner? I’m never sure

      Handy article to get new admins started, thank you

      • log.warn is my go-to, it outputs to the log pretty reliably without having to define a log-level

        It’s the same on Cloud, except that I have to refer to it as logger and not log!

Leave a Reply to Ken Cancel 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>