Breaking Changes
Version 6.11.0+
If using the Database Picker, from version 6.11.0, any row results will be automatically HTML-encoded. Currently, they are sanitised, meaning any malicious javascript is stripped from them.
This can lead to problems when the database result is something like <foo
- in this case nothing will be shown. When this is fixed the row result will be returned as <foo
.
The reason this is not done automatically is because some users are creating HTML with their SQL query, e.g. select '<b>' || name || '</b>' from foo
.
This means we can’t automatically protect against XSS attacks whilst guaranteeing that all data will be displayable. (Currently, we are protecting against XSS attacks at the cost that some strings may not be displayed).
Any users formatting results in this way should switch to using groovy to customise the displayed value as soon as possible.
When this is fixed, in ScriptRunner 6.11.0, customisations that use SQL to format the result will not continue to work as expected.
Version 6.0.0+
Version Searcher JSON Schema
Previously, when using a script field with the Version Searcher
, the JSON representation for an issue incorrectly represented the schema as a single version, and therefore only returned the first entry of a list. It now returns all list entries; however, the JSON schema has changed from a list to an array. This change might affect you if you were parsing the JSON response for an issue containing a script field with this indexer.
Constant Removal and Replacement
The following constant has been removed in ScriptRunner 6.0:
com.onresolve.scriptrunner.runner.ScriptRunnerImpl.PLUGIN_KEY
It has been replaced with:
com.onresolve.scriptrunner.runner.PluginBuildInfo.PLUGIN_KEY
Please ensure any usages of the ScriptRunnerImpl
constant are removed and replaced before upgrading ScriptRunner to versions 6.0+.
Unavailable Classes in Jira 8.8.0
The following classes are no longer accessible from Velocity in Jira 8.8.0; this change only affects ScriptRunner users using these classes in custom templates within script fields:
java.lang.Class,
java.lang.ClassLoader,
java.lang.Compiler,
java.lang.InheritableThreadLocal,
java.lang.Package,
java.lang.Process,
java.lang.Runtime,
java.lang.RuntimePermission,
java.lang.SecurityManager,
java.lang.System,
java.lang.Thread,
java.lang.ThreadGroup,
java.lang.ThreadLocal,
com.atlassian.applinks.api.ApplicationLinkRequestFactory,
com.atlassian.core.util.ClassLoaderUtils,
com.atlassian.core.util.ClassHelper.
Hidden Fields Removal
Hidden Fields custom fields were removed from ScriptRunner for Jira Server/Data Center in 5.6.10. Hidden fields will no longer be available in your instance. However, all the hidden fields configuration and data will still exist in the database.
Migration
There are two options for dealing with hidden fields:
You would have been using these fields because you didn’t want the contents visible to all users all of the time. Now, the contents will no longer be hidden by the behaviours applied to them in the View Issue screen (these behaviours will hide fields in the Edit Issue screen). We recommend you investigate the Atlassian Marketplace for other apps that provide the ability to hide fields in the View Issue screen.
The recommended approach is to convert them to regular short text or long text fields. To convert hidden fields to regular fields, go to ScriptRunner→Script Console, and execute the following script:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.fields.layout.field.FieldLayoutManager
import org.ofbiz.core.entity.DelegatorInterface
import org.ofbiz.core.entity.EntityExpr
import org.ofbiz.core.entity.EntityOperator
def delegatorInterface = ComponentAccessor.getComponent(DelegatorInterface)
def customFieldManager = ComponentAccessor.customFieldManager
def fieldLayoutManager = ComponentAccessor.getComponent(FieldLayoutManager)
def replacementFieldTypes = [
'com.onresolve.jira.groovy.groovyrunner:hideable-textfield': 'com.atlassian.jira.plugin.system.customfieldtypes:textfield',
'com.onresolve.jira.groovy.groovyrunner:hideable-textarea' : 'com.atlassian.jira.plugin.system.customfieldtypes:textarea',
]
delegatorInterface.findByOr('CustomField', replacementFieldTypes.keySet().collect {
new EntityExpr('customfieldtypekey', EntityOperator.EQUALS, it)
}).each {
def replacementType = replacementFieldTypes[it.getString('customfieldtypekey')]
log.warn("Converting '${it.getString('name')}' to $replacementType.")
it.put('customfieldtypekey', replacementType)
delegatorInterface.store(it, true)
}
fieldLayoutManager.refresh()
customFieldManager.clear()
"Fields converted"
This is safe to re-run if you are not sure it’s been done before, and is the recommended approach to convert these fields to regular fields.
We recommend users change the custom field type of all hidden fields before upgrading to ScriptRunner for Jira 6.0 and above.
If you use these fields on Jira Service Desk, there is the possibility that the fields of these types will be removed from the screen. There is a bug in Jira Service Desk such that if a user opens a request type which contains fields that are currently not present in the system, they will be permanently removed fron the database table that details which fields are part of this request type. If this happens you will need to add them back to the relevant request types.
This problem can be avoided by following this migration procedure before updating.
Alternative Method
Alternatively, you can follow Atlassian guidelines for changing a field type. However this requires database access, and a Jira restart. If changing custom field type via the database, use the following type keys for what to search for and its replacement:
Old Key | Replacement Key |
com.onresolve.jira.groovy.groovyrunner:hideable-textfield??? | com.atlassian.jira.plugin.system.customfieldtypes:textfield |
com.onresolve.jira.groovy.groovyrunner:hideable-textarea??? | com.atlassian.jira.plugin.system.customfieldtypes:textarea |
Rationale
We are sorry for the inconvenience this will cause you if you use these fields, as we almost never remove features.
These fields were removed as there is no maintainable way to truly hide the contents of a field which covers all the various ways that a user might see it. Not just in the view issue screen, but also: in the issue navigator, in the history tab, in the REST API, when exporting to CSV, Word, PDF.
Rather than handle most of these cases but not all, at least not in a maintainable way across all Jira versions, we took the decision that it was more honest to not support these anymore, rather than risk a customer accidentally exposing data to a user that they thought was not possible.
Version 5.6.7 and Above
Some Groovy Classes Backwards-incompatible
To lay the groundwork for new features, sometimes we need to refactor our existing code. When doing this, Adaptavist focuses on backwards compatibility, to ensure features continue to work as they did before upgrading.
A few users may have created groovy classes that overrode either com.onresolve.scriptrunner.canned.jira.workflow.postfunctions.CloneIssue
or com.onresolve.scriptrunner.canned.jira.workflow.postfunctions.CreateSubTask
. We have had to change these in a way that is backwards-incompatible, therefore these will no longer work. We are currently working on better ways to allow users to make these kinds of customizations.
There is no simple fix to make the overriding scripts compatible. Rather than overriding them, there are several options available:
Use the Additional Issue Actions code section to add code that executes after
Clone Issue
is completed.Add a Custom Script Function/Listener to perform additional actions after the Clone/Create function.
Call the function programmatically, dynamically setting the inputs as required.
import com.onresolve.scriptrunner.canned.jira.workflow.postfunctions.CloneIssue
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
def inputs = [
'FIELD_TARGET_PROJECT' : 'FOO',
'FIELD_SELECTED_FIELDS': null, //clone all the fields
] as Map<String, Object>
def executionContext = [
issue: issue,
]
def cloneIssueBean = ScriptRunnerImpl.scriptRunner.createBean(CloneIssue)
cloneIssueBean.execute(inputs, executionContext)
The best way to find the keys and values of the inputs is to view the network request in your browser when you configure the function. For example:
If these options don’t meet your needs, please contact Adaptavist Support for help.
Downgrading
Due to changes and improvements to our API, downgrading is not guaranteed to work so it is only recommended when confirmed by Adaptavist Support.