Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Migrating from a language like groovy to a language like Simple Issue Language (SIL) can be challenging for some users since the SIL language has been simplified so that it does not require many of the steps used in groovy code. Here are some common steps that can be helpful in preparing a groovy script for conversion, especially when using an AI tool like WorkFlow Pro - AI assistant for Jira.

Basic differences between groovy and SIL

Import statements

With scripting/programming, import statements (lines 1-4 from the example groovy script shown below) are used to bring in code from other modules or packages, allowing you to use their functions, classes, and variables in your current program. The groovy language relies heavily on these other modules or packages which are usually Atlassian packages that provide the API to interact with the system.

The SIL language does not rely on import statements in the code and therefore they can simply be deleted. This saves a lot of time that is normally spent research API documentation about which class files need to be imported or which class file contains a specific functionality.

This also guards users against system updates since it is the imported class files that are changed with version updates. Since SIL scripts do not access the classes directly they are not impacted by those changes. Instead, the Power Scripts application is updated to use the proper API class. Once updated, the scripts will continue to function as normal.

Info

If using something like AI to migrate groovy scripts to SIL it is recommended to delete the import statements before asking AI to perform the conversion. Despite the AI being trained on the SIL language it has a habit of trying to closely follow patterns found in the groovy script and replicate those patterns in SIL. The AI can get confused when those patterns are not supposed to exist in SIL.

Class initialization

The Simple Issue Language was designed to be as simple as possible and so it avoids directly using the classes from the Atlassian API directly. This makes SIL easier to use and also protects scripts from changes within those classes. It also removes the step that is usually required in groovy to initialize those classes like can be seen in lines 12-13 in the example groovy script shown below.

Info

It is not always necessary to remove these initialization code lines prior to submitting to the AI for conversion. However, if the AI tries to replicate this pattern in SIL then they should be removed.

Example #1

Expand
titleExample Groovy Script #1

This groovy script will find all projects where a specific Jira group is used by a project, through its permission scheme. A group is being deemed as being used by a project, where it's used by its permission scheme, either directly or through a project role.

Code Block
import com.atlassian.confluence.user.DisabledUserManager
import com.atlassian.crowd.embedded.api.CrowdService
import com.atlassian.sal.api.component.ComponentLocator
import com.onresolve.scriptrunner.parameters.annotation.ShortTextInput

@ShortTextInput(label = "Users", description = "Type usernames of deactivated users you would like to reactivate, seperated by spaces")
String names
assert names

def disabledUsers = names.split()

def disabledUserManager = ComponentLocator.getComponent(DisabledUserManager)
def crowdService = ComponentLocator.getComponent(CrowdService)

disabledUsers.each { userName ->
    def user = crowdService.getUser(userName)
    if (user) {
        if (disabledUserManager.isDisabled(user)) {
            disabledUserManager.enableUser(user)
            log.info("User $user.name has been enabled")
        } else {
            log.info("User $user.name is not disabled")
        }
    } else {
        log.debug("User $userName was not found.")
    }
}

Initializing the issue

Similar to initializing classes, it is not required in SIL to initialize the issue so that it is editable (line 7 in the example groovy script below). This is especially true if the script is running in the context of the issue.

Code Block
//groovy
def issue = Issues.getByKey('SR-1') as MutableIssue

//SIL
string key = "SR-1";

Functions for setting values

In the SIL language it is also not required to use a function to set the value of field (see lines 12-13). This is a common mistake that AI will often make when trying to convert groovy to SIL.

Code Block
//groovy
setPriority('Highest')

//SIL
priority = "Highest";

Function for storing issue data

While SIL does have a function for storing issues data, saveModifiedIssues() (cloud only), this function is used for optimizing memory usage and is not required at all. The groovy code on line 16 could be completely removed. With SIL, all changes will be committed when the script completes.

Reindexing

SIL scripts will automatically reindex the issue if there are changes. The groovy code on line 17 is not required and can be deleted.

Example #2

Expand
titleExample Groovy Script #2

This script can be useful for bulk changing issues, without sending emails, or affecting the last update time of the issue. No record of the change will appear in the change history either.

Code Block
import com.adaptavist.hapi.jira.issues.Issues
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.index.IssueIndexingParams
import com.atlassian.jira.issue.index.IssueIndexingService

def issueIndexingService = ComponentAccessor.getComponent(IssueIndexingService)

def issue = Issues.getByKey('SR-1') as MutableIssue

issue.set {
    setPriority('Highest')
    setSummary('my new summary')
}

issue.store()
issueIndexingService.reIndex(issue, IssueIndexingParams.INDEX_ISSUE_ONLY)

Basic error handling

One of the ways that the SIL language was simplified to reduce the code the user must write is by taking care of common coding tasks automatically. Within most functions in the SIL language are steps on how the code should react if the data is null, missing, or invalid in a way that can cause an error resulting in the code crashing. Since this basic error handling is already built in it is not required that the user include it in the SIL script so lines 15-21 could be removed from the example below.

Info

SIL does have error handling ability and some functions will throw specific error types. This is done so that the user can have options on how the script should perform when it encounters the error.

Type conversion

The SIL language is very lenient when it comes to type conversion and will handle most conversions automatically.

Example #3

Expand
titleExample Groovy Script #3

Setting a template field as mandatory

Code Block
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.CustomFieldManager


CustomFieldManager cfm = ComponentAccessor.getCustomFieldManager();
CustomField tempalteCF = cfm.getCustomFieldObject(10112L);
log.error('[LOG] tempalteCF: ' + tempalteCF)

Map templateValue = issue.getCustomFieldValue(tempalteCF)
log.error('[LOG] templateValue: ' + templateValue)

boolean templateIsEmpty = templateValue.get("SELECTED_TEMPLATE") == null;

if (templateIsEmpty) {
    log.error("Tempalte is empty")
    return false;
}

log.error("Tempalte is not empty")
return true;

Tips and tricks

and shit

SIL aliases

The SIL language has a built-in feature called SIL aliases which helps manage the use of custom field id’s in the code and makes for easier reading of the code and easier migrations. It is a good idea to switch to using aliases when converting a groovy script to SIL.

Troubleshooting

runnerLog()

When writing scripts in the SIL Manager a special function called runnerLog() can be used to write output to the console. These messages are only visible from the SIL Manager or the SIL Runner Gadget and are perfectly safe to leave in the code even if they are intended to run elsewhere like a post function.

These messages are very helpful for understanding what is happening within the script and for debugging.

Debugging/Run Configuration

Using the run configuration setting, the SIL Manager can be configured to test scripts as if they were being triggered by a specific issue. Combined with the script debugger this is a very useful tool for troubleshooting scripts.

Contents:

Table of Contents
minLevel1
maxLevel2
outlinefalse
stylenone
typelist
printabletrue