In the first part of this article we created several scripts, packaged them into a plugin, installed the plugin and called one of the scripts from the Script Console.
In this part of the article we will try to deploy ScriptRunner objects such as a Listener, a REST endpoint, a Script fragment and a Scripted field.
You can take the source code of the plugin here.
Let's first create a listener, a REST endpoint and a script fragment in our dev environment.
The first listener is a custom listener:
The second listener is the Adds the current user as a watcher listener:
The REST endpoint looks like this:
The Script fragment looks like this:
After we created all the items we need to add them to our plugin so that the items would be installed after our plugin installation.
Go to Add-ons->Built-In Scripts->Configuration Exporter and choose all our created objects.
Push the Run button and you will see something like this:
Copy all the text in the selected red rectangle and add it to the src/main/resources/scriptrunner.yaml file. The file will look like this:
!descriptor
fragmentConfigItems:
- FIELD_DO_WHAT: NAVIGATE
FIELD_KEY: ru-matveev-alexey-web-item
FIELD_LINK_CONDITION:
- ''
- ''
FIELD_LINK_DESTINATION: ''
FIELD_MENU_LABEL: ''
FIELD_NOTES: Web Item
FIELD_SECTION: add-attachments-link
FIELD_STYLE_CLASS: ''
FIELD_WEIGHT: ''
canned-script: com.onresolve.scriptrunner.canned.jira.fragments.CustomWebItem
id: '520053084'
restConfigItems:
- FIELD_INLINE_SCRIPT: ''
FIELD_NOTES: REST endpoint
FIELD_SCRIPT_FILE: ru/matveev/alexey/main/rest/rest.groovy
canned-script: com.onresolve.scriptrunner.canned.common.rest.CustomRestEndpoint
id: '-168713291'
scriptListeners:
- FIELD_FUNCTION_ID: cf09831f83bc75ec27076557034b952dfc727040
FIELD_INLINE_SCRIPT: ''
FIELD_LISTENER_NOTES: Custom Listener
canned-script: com.onresolve.scriptrunner.canned.jira.workflow.listeners.CustomListener
clazz: ru/matveev/alexey/main/listeners/listener.groovy
events:
- 1
id: '-586588827'
params: '{"FIELD_LISTENER_NOTES":"Custom Listener","projects":"","events":"1","FIELD_INLINE_SCRIPT":"","clazz":"ru/matveev/alexey/main/listeners/listener.groovy","FIELD_FUNCTION_ID":"cf09831f83bc75ec27076557034b952dfc727040","canned-script":"com.onresolve.scriptrunner.canned.jira.workflow.listeners.CustomListener","id":"-268926325"}'
projects:
- ''
- FIELD_CONDITION: []
FIELD_FUNCTION_ID: ''
FIELD_LISTENER_NOTES: Add the current user as a watcher
canned-script: com.onresolve.scriptrunner.canned.jira.workflow.postfunctions.AddWatcher
events:
- 1
params: '{"FIELD_LISTENER_NOTES":"Add the current user as a watcher","projects":"","events":"1","FIELD_CONDITION":["",""],"FIELD_FUNCTION_ID":"","canned-script":"com.onresolve.scriptrunner.canned.jira.workflow.postfunctions.AddWatcher"}'
projects:
- ''
Unfortunately, the Export Configuration option can not export scripted fields. That is why we need to create scripted fields in our code. We will use the Upgrade Task feature of Jira. The Upgrade Task lets you launch a piece of code on plugin startup. An upgrade task will be executed only if it has never been executed yet. You need to make a class, which will implement the PluginUpgradeTask interface. Also this class must be exported as a public service.
First we create the src/main/groovy/ru/matveev/alexey/scriptedfields/AbstractUpgradeTask.groovy file (this file is taken for the sample ScriptRunner plugin):
package ru.matveev.alexey.scriptedfields
import com.atlassian.plugin.osgi.util.OsgiHeaderUtil
import groovy.util.logging.Log4j;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
@Log4j
abstract class AbstractUpgradeTask {
public String getPluginKey() {
Bundle bundle = FrameworkUtil.getBundle(AbstractUpgradeTask.class);
return OsgiHeaderUtil.getPluginKey(bundle);
}
}
This class implements the getPluginKey method, which is one of the methods of the PluginUpgradeTask interface. This method returns the plugin key.
Then we create src/main/groovy/ru/matveev/alexey/scriptedfields/CreateScriptFieldUpgradeTask.groovy(this script was taken from the sample ScriptRunner plugin):
package ru.matveev.alexey.scriptedfields
import com.atlassian.jira.issue.context.GlobalIssueContext
import com.atlassian.plugin.spring.scanner.annotation.export.ExportAsService
import com.atlassian.sal.api.message.Message
import com.atlassian.sal.api.upgrade.PluginUpgradeTask
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
import com.onresolve.scriptrunner.test.ScriptFieldCreationInfo
import groovy.util.logging.Log4j
import javax.inject.Named
@Log4j
@Named
@ExportAsService
class CreateScriptFieldUpgradeTask extends AbstractUpgradeTask implements PluginUpgradeTask {
@Override
int getBuildNumber() {
return 1
}
@Override
String getShortDescription() {
return "This upgrade task creates a scripted field"
}
@Override
Collection<Message> doUpgrade() throws Exception {
def scriptFieldCreation = ScriptFieldCreationInfo.Builder.newBuilder()
.setName("TestScriptFieldSimpleNumberX")
.setSearcherKey(ScriptRunnerImpl.PLUGIN_KEY + ":exactnumber")
.setTemplate("float")
.setContexts([GlobalIssueContext.instance])
.setScriptFile("ru/matveev/alexey/main/scriptedfields/scriptedfield.groovy")
.build()
scriptFieldCreation.create()
return null
}
}
This class is created as a public service, it extends the AbstractUpgradeTask and implements the PluginUpgradeTask. The doUpgrade method creates our custom field.
You can open Terminal and execute atlas-run or you can install a Jira instance and add the plugin. As a result you will see the that all our object were created.
Our scripted field:
Our listeners:
Our REST endpoint:
Our Web fragment:
We can see all our object, which means that we successfully created all the ScriptRunner objects.
Now you can deploy our scripts and objects to any Jira environment by installing the developed in this article plugin.
Alexey Matveev
software developer
MagicButtonLabs
Philippines
1,574 accepted answers
10 comments