In this article I would like to talk on how to deploy Adaptivist Scriptrunner scripts and objects such as Behaviours, Listeners, Script Fragments, Scripted fields, REST endpoints to a Jira instance.
This article will consist of two parts. In the first part we will learn how to deploy scripts, and in the second part we will learn how to deploy ScriptRunner objects.
You can find the source code of the developed in this article plugin here.
Suppose, we have three Jira environments: dev, test and production. We develop our scripts and create objects in the dev environment, and then we move our configuration to the test and production environments. I can see three ways how we can do it:
In this article we will discuss the third way.
You can find information on script plugin here. You can find an example of such a plugin here.
In my opinion this sample plugin has several disadvantages:
Let us try to create our own plugin.
Open terminal and execute:
atlas-create-jira-plugin
Answer questions the following way:
Define value for groupId: : ru.matveev.alexey.scriptrunner
Define value for artifactId: : scriptrunner-plugin
Define value for version: 1.0.0-SNAPSHOT: :
Define value for package: ru.matveev.alexey.scriptrunner: :
Confirm properties configuration:
groupId: ru.matveev.alexey.scriptrunner
artifactId: scriptrunner-plugin version: 1.0.0-SNAPSHOT
package: ru.matveev.alexey.scriptrunner
Y: : Y
Your pom.xml file should look like this (I made comments to the most important parts of the file):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--
I added the parent pom.xml, which does all the magic. I took this pom.xml from the ScriptRunner sample plugin
-->
<parent>
<groupId>com.adaptavist.pom</groupId>
<artifactId>scriptrunner-jira-standard</artifactId>
<version>10</version>
<relativePath/>
</parent>
<groupId>ru.matveev.alexey.scriptrunner</groupId>
<artifactId>scriptrunner-plugin</artifactId>
<version>1.0.0-SNAPSHOT</version>
<organization>
<name>Example Company</name>
<url>http://www.example.com/</url>
</organization>
<name>scriptrunner-plugin</name>
<description>This is the ru.matveev.alexey.scriptrunner:scriptrunner-plugin plugin for Atlassian JIRA.</description>
<packaging>atlassian-plugin</packaging>
<dependencies>
<!--
I excluded a couple of dependencies from the dependency below, because the plugin did not want to start for ScriptRunner versions higher than 5.3.0
-->
<dependency>
<groupId>com.onresolve.jira.groovy</groupId>
<artifactId>groovyrunner</artifactId>
<version>${scriptrunner.version}</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>com.onresolve.scriptrunner.platform</groupId>
<artifactId>scriptrunner-test-libraries-jira</artifactId>
</exclusion>
<exclusion>
<groupId>jndi</groupId>
<artifactId>jndi</artifactId>
</exclusion>
<exclusion>
<groupId>jta</groupId>
<artifactId>jta</artifactId>
</exclusion>
<exclusion>
<groupId>is.origo.jira</groupId>
<artifactId>tempo-plugin</artifactId>
</exclusion>
<exclusion>
<groupId>com.tempoplugin</groupId>
<artifactId>tempo-core</artifactId>
</exclusion>
<exclusion>
<groupId>groovyrunner</groupId>
<artifactId>test</artifactId>
</exclusion>
<exclusion>
<groupId>com.atlassian.plugin.automation</groupId>
<artifactId>automation-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-annotation</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>maven-jira-plugin</artifactId>
<version>${amps.version}</version>
<extensions>true</extensions>
<configuration>
<productVersion>${jira.version}</productVersion>
<productDataVersion>${jira.version}</productDataVersion>
<!--
I increased JVM memory, because Jira 7.9.0 does not want to run with the default settings
-->
<jvmArgs>-Xms512M -Xmx1g</jvmArgs>
<enableQuickReload>true</enableQuickReload>
<enableFastdev>false</enableFastdev>
<applications>
<!--
I added Jira Software to the plugin because I want Jira Software to start on the atlas-run command.
-->
<application>
<applicationKey>jira-software</applicationKey>
<version>${jira.version}</version>
</application>
<!--
I added Jira Service Desk to the plugin because I want Jira Service Desk to start on the atlas-run command.
-->
<application>
<applicationKey>jira-servicedesk</applicationKey>
<version>${jira.servicedesk.application.version}</version>
</application>
</applications>
<instructions>
<Atlassian-Plugin-Key>${atlassian.plugin.key}</Atlassian-Plugin-Key>
<Export-Package>
ru.matveev.alexey.scriptrunner.api,
</Export-Package>
<Import-Package>
org.springframework.osgi.*;resolution:="optional",
org.eclipse.gemini.blueprint.*;resolution:="optional",
*
</Import-Package>
<Spring-Context>*</Spring-Context>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-maven-plugin</artifactId>
<version>${atlassian.spring.scanner.version}</version>
<executions>
<execution>
<goals>
<goal>atlassian-spring-scanner</goal>
</goals>
<phase>process-classes</phase>
</execution>
</executions>
<configuration>
<scannedDependencies>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-external-jar</artifactId>
</dependency>
</scannedDependencies>
<verbose>false</verbose>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<jira.version>7.9.0</jira.version>
<jira.servicedesk.application.version>3.12.0</jira.servicedesk.application.version>
<scriptrunner.version>5.3.9</scriptrunner.version>
<amps.version>6.3.6</amps.version>
<plugin.testrunner.version>1.2.3</plugin.testrunner.version>
<atlassian.spring.scanner.version>2.0.0</atlassian.spring.scanner.version>
<atlassian.plugin.key>${project.groupId}.${project.artifactId}</atlassian.plugin.key>
<testkit.version>6.3.11</testkit.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<!--
This is required to find the parent pom and ScriptRunner dependencies
-->
<repository>
<id>adaptavist-external</id>
<url>https://nexus.adaptavist.com/content/repositories/external</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
<checksumPolicy>fail</checksumPolicy>
</releases>
</repository>
</repositories>
</project>
Delete the src/main/java folder and the src/test folder.
Let us create a couple of scripts, which we will use later in our listeners, scripted field, rest endpoint, script fragment and the script console:
src/main/resources/ru/matveev/alexey/main/listeners/listener.groovy
package ru.matveev.alexey.main.listeners
import org.slf4j.LoggerFactory;
def log = LoggerFactory.getLogger(this.getClass())
log.debug("listener {} executed", this.getClass())
src/main/resources/ru/matveev/alexey/main/rest/rest.groovy
package ru.matveev.alexey.main.rest
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.json.JsonBuilder
import groovy.transform.BaseScript
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response
@BaseScript CustomEndpointDelegate delegate
doSomething(httpMethod: "GET", groups: ["jira-administrators"]) { MultivaluedMap queryParams, String body ->
return Response.ok(new JsonBuilder([abc: 42]).toString()).build();
}
src/main/resources/ru/matveev/alexey/main/scriptedfields/scriptedfield.groovy
package ru.matveev.alexey.main.scriptedfields
import org.slf4j.LoggerFactory;
def log = LoggerFactory.getLogger(this.getClass())
log.debug("scripted field {} executed", this.getClass())
src/main/resources/ru/matveev/alexey/main/scripts/script.groovy
package ru.matveev.alexey.main.scripts
import org.slf4j.LoggerFactory;
def log = LoggerFactory.getLogger(this.getClass())
log.debug("script {} executed", this.getClass())
src/main/resources/ru/matveev/alexey/main/webfragments/webfragments.groovy
package ru.matveev.alexey.main.webfragments
import org.slf4j.LoggerFactory;
def log = LoggerFactory.getLogger(this.getClass())
log.debug("script {} executed", this.getClass())
Now we will run the plugin and have a look, if we can access our scripts.
Open terminal in the plugin folder and run the following command:
atlas-run
After Jira is launched, open localhost:8080/jira in your browser and login to Jira under admin:admin.
Let s set the DEBUG level for the ru.matveev package. Open cog wheel -> System->Logging and Profiling, click the Configure button:
Enter ru.matveev for the Package name, set DEBUG for the Logging Level and click the Add button.
Now we can try to execute one of our scripts.
Go to Add-ons -> Script Console. Choose the File tab and enter ru/matveev/alexey/main/scripts/script.groovy. You can also see that our plugin added a couple of new script roots, which means that ScriptRunner can see out scripts. You can read more about script roots here.
Click the Run button to execute the script:
We can see that our script was executed, which means that we successfully added our scripts.
We will learn how to deploy ScriptRunner object in the second part of this tutorial.
Alexey Matveev
software developer
MagicButtonLabs
Philippines
1,575 accepted answers
6 comments