Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

How to learn how to develop ScriptRunner scripts?

Brian May 27, 2020

Hello fellow Scriptrunner fans,

I've been using ScriptRunner for over a year now and I've cobbled together the ability to find scripts from these forums or from Adaptavist's script library or from Scriptrunner documentation itself.  Basically I'm still a beginner.

I can even modify these scripts now in a basic way to adapt them to what I need done.  But now my needs are growing and when I can't find something already pre-written I'm at a loss.

What resources did you use to learn how to create these scripts?  Many times there are things in the Adaptavist Script Library and I have no idea why/how they work, they just do.  I'd like to learn the how/why.  I'm hoping/wishing there is some great ScriptRunner script development book out there that I can read and unlock the mysteries of Grovvy script writing.

For example, I want to build a script that I can use in the script console that takes 1 user that I supply and will add this user to a project role (that I supply) to X number of projects which I supply.  I want to learn how to build this myself.

I see things like componentaccessor and all these other Import lines but I have no idea why they are needed, I just import them.  I just recently discovered I can use the code editor and hit ctrl-space or ctrl-j and learn about available methods or see the documentation but often times the documentation is difficult to understand.  I seem to learn best by seeing functioning code and then tweaking that.  I don't know how to translate the code found in the official documentation.  Where's my Rosetta stone for this stuff?

For example, from the the latest jira api 8.9.0 I found this;

void addActorsToProjectRole(Collection<String> actors,
                            ProjectRole projectRole,
                            Project project,
                            String actorType,
                            ErrorCollection errorCollection)

Just by the name this sounds real promising for what I want to do.  What does this look like in real code in a real groovy script?

Do I replace the blue? What does the blue mean?  Do I need to include the blue code?  Does Project project need to be there is only 1 project necessary.  How do I know how to interpret this?

void addActorsToProjectRole(Collection<String> 'mx45678', <--- user i want to add
                            ProjectRole team contributor, <-- a project role
                            Project TOKE, <-- my project key but i have more
                            String actorType, <--No idea what this is
                            ErrorCollection errorCollection) <-- No idea what this is

 

2 answers

Suggest an answer

Log in or Sign up to answer
2 votes
Ravi Sagar _Sparxsys_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 1, 2020

Hi @Brian 

Let me share few things.

 

"What resources did you use to learn how to create these scripts?  Many times there are things in the Adaptavist Script Library and I have no idea why/how they work, they just do.  I'd like to learn the how/why.  I'm hoping/wishing there is some great ScriptRunner script development book out there that I can read and unlock the mysteries of Grovvy script writing."

  • Learn Groovy definitely helps. I find http://groovy-lang.org/ as one of the best place to learn this language. Prior programming knowledge definitely makes things easy. 
  • I don't think one need to have complete mastery over Groovy to get things done with ScriptRunner. I find good grasp of lists, maps, iterate, collect, closures, strings, methods, classes and objects good enough to most of the tasks.
  • In the beginning using IntelliJ makes things a lot easier. It assists with code completion and can auto import classes for you. You can read about it here
  • Adaptavist Library and Atlassian Community has plenty of example and sample code.

"For example, I want to build a script that I can use in the script console that takes 1 user that I supply and will add this user to a project role (that I supply) to X number of projects which I supply.  I want to learn how to build this myself."

  • Well I usually use console to validate the script too with sample users or issues. I would say build the logic first based on what you are trying to achieve.
    • From which source you will supply X number of projects? Some other system? csv file? or within Jira or hard coded project keys in a list?
    • Create a simple method that will take parameters, so you can reuse them or call them whenever needed may be multiple times based using a loop.

"I see things like componentaccessor and all these other Import lines but I have no idea why they are needed, I just import them.  I just recently discovered I can use the code editor and hit ctrl-space or ctrl-j and learn about available methods or see the documentation but often times the documentation is difficult to understand.  I seem to learn best by seeing functioning code and then tweaking that.  I don't know how to translate the code found in the official documentation.  Where's my Rosetta stone for this stuff?"

  • Yes the new code editor makes things a lot easier and quickly navigating to java docs using Ctrl-j makes life easy. I also copy the code I found and tweak it to suit my requirements.
  • Talk about reading java docs. 

"

void addActorsToProjectRole(Collection<String> actors,
                            ProjectRole projectRole,
                            Project project,
                            String actorType,
                            ErrorCollection errorCollection)

"

  • @Peter-Dave Sheehan above explained how it works.
  • If you look at the parameters the type tell you what you need to pass. If it is a project object then you can usually find it in the issue it self using issue.getProjectObject(). Reading and navigating through java docs takes time but as I mentioned before if you use IntelliJ linked with Jira's source code (if you have license) then it will help make things quicker.

Few other things I can share.

  • Keep a repository of common scripts for thing you need to do like
    • Get issues, users, projects and performing JQL search
    • Working with permissions, roles and groups
    • Transitioning and updating issues and adding comments
    • Navigating between links and subtasks
    • Reading and writing files (like CSV)
  • ScriptRunner's documentation has lot of examples from doing very basic things to slightly complicated ones. It is a like doing a tour of various things we can do with ScriptRunner.

Finally I would say respond to others' questions on the community. Just by helping them, solving their problem you will also build your knowledge.

I hope it helps.

Ravi

Brian LeTourneau June 1, 2020

Wow, is this the YouTube famous Ravi?  Thank you so much your time and effort to respond.  I have watched over half of your Scriptrunner videos on YouTube.  I've learned a ton.  Thank you for creating those videos.

I just purchased a Groovy course to learn more about what collect, closures, strings, methods, classes and objects are.  Classes, objects, closures still mystify me.

I've actually got some notes on different ideas that I'd like you to make YouTube videos on.  If you take suggestions, please let me know and I'll respond here.

Like Ravi Sagar _Sparxsys_ likes this
Ravi Sagar _Sparxsys_
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 2, 2020

Thanks :) Yes definitely, do give your suggestions.

0 votes
Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
May 28, 2020

That is such a great question and wonderfully stated too.

I wish I had had the answer when I got started. I am not aware of any good scriptrunner development bible or reference.

After a few years of scriptrunner/groovy hacking, I'm probably at the point where you wish you were. But I got there the same way you are... cobbling lots of scripts together, lots of googling, lots of exploration of the javadocs.

A little bit of java experience probably would have helped, but I picked up bits and pieces along the way enough to be able to get by.

Maybe explaining how javadocs work would be helpful here.

The "blue" text actually represents the type of data that the method is expecting.  So in your example, this means:

  • Collection<String> <--- you should supply something like ['mx45678', 'mx6789']
  • ProjectRole projectRole <--- you should somehow generate an Object of type ProjecRole. So you would look through the various managers and look for something the return a ProjectRole object. I usually start from ComponentAccessor page and click through on some of the managers. Some managers are not available directly from the ComponentAccessor, in those cases, you need to import the manager class and access it with ComponentAccessor.getComponent(ProjectRoleManager). You can display the java docs with frames and just search for the word "manager" and "service". Usually, the names provides some good clues.
  • String actorType <---- this means it's expecting a string the represents the type of actor assignment (are you adding a group or a user to the role, the tell the method what is in the Collection<string> actors. Looking through the java doc page, you might find this line: "actorType - is a type that defines the type of role actor to instantiate (ex./ UserRoleActor.TYPE, GroupRoleActor.TYPE)". So look for a class in the Javadoc called UserRoleActor. I found MockUserRoleActor. Not quite, but close. Looking at that I see that it inherits fields from ProjectRoleActor. So a quick console script "return com.atlassian.jira.security.roles.ProjectRoleActor.USER_ROLE_ACTOR_TYPE" actually returns the string "atlassian-user-role-actor". That seems to fit.
  • ErrorCollection <--- I am not sure, but I suspect this can either be left null or if you pass an Empty ErrorCollection object, it will be populated by the method with any error that happens to be found during the method. I didn't quite find out to get such an empty errorCollection, so I'll try null

So putting it all together, I cobbled this script to add user abc to Users role in project JSP

import com.atlassian.jira.security.roles.ProjectRoleActor
import com.atlassian.jira.bc.projectroles.ProjectRoleService
import com.atlassian.jira.security.roles.ProjectRoleManager
import com.atlassian.jira.component.ComponentAccessor

def projectManager = ComponentAccessor.projectManager
def projectRoleManager = ComponentAccessor.getComponent(ProjectRoleManager)
def projectroleService = ComponentAccessor.getComponent(ProjectRoleService)
def project = projectManager.getProjectObjByKey('JSP')

def userRole = projectRoleManager.getProjectRole('Users')

projectroleService.addActorsToProjectRole(['abc'] as Collection, userRole, project, ProjectRoleActor.USER_ROLE_ACTOR_TYPE , null)

You may notice that you only need import for classes you actually use and define explicitly.

I could import the PrjectManager class and then define the projectManager object as 

ProhectManager projectManager =ComponentAccessor.getProjectManager()

But that doesn't seem necessary to me, I like to keep my script as short and tight as possible, So I use def to let groovy guess the class. It does a pretty good job at it.

I hope I've included enough of my thinking/exploration process you give you a leg up into this adventure.

TAGS
AUG Leaders

Atlassian Community Events