Adaptavist ScriptRunnerアーティファクトを展開する方法

ソフトウェア開発のプロセスでは、通常、いくつかの環境が使用されます。開発、テスト、および産業用の環境です。 この記事では、アトラシアンJira環境間でAdaptavist ScriptRunnerアーティファクトを転送する方法について説明します。



この記事で開発したプラグインのソースコードは、 こちらでご覧いただけます



Adaptavist ScriptRunnerを使用してソフトウェアを開発すると、次のアーティファクトが作成されます。



  1. スクリプト
  2. ビジネスプロセスオブジェクト
  3. スクリプトフィールド
  4. ライサー
  5. RESTメソッド
  6. スクリプトの断片
  7. 行動
  8. カスタムjql関数


この記事では、スクリプトについて説明します。オブジェクトとは、スクリプトフィールド、ライセンサー、RESTメソッド、スクリプトフラグメントを意味します。



いくつかのJira環境を使用しているため、開発環境でソフトウェアを開発した後、他の環境に転送する必要があります。



ScriptRunnerで開発されたソフトウェアは、次のように移植できます。



  1. 手動で。
  2. すべてのスクリプトをバージョン管理システムに保存し、継続的統合および配信サーバーの1つで展開計画を作成し、リポジトリでブランチが変更されたときにスクリプトを自動的に転送します。 ただし、この場合、ScriptRunnerオブジェクトは引き続き手動で転送されます。
  3. すべてのスクリプトとScriptRunnerオブジェクトを含むスクリプトプラグインを作成します。 このプラグインをJiraスクリプトにインストールすると、ScriptRunnerオブジェクトが自動的に展開されます。


この記事では、スクリプトとScriptRunnerオブジェクトを展開する3番目の方法-スクリプトプラグインを使用した展開について説明します。



スクリプトプラグインについてはこちらをご覧ください 。 スクリプトプラグインの例はこちらにあります



Jira 7.9.0用のスクリプトとScriptrunnerオブジェクトをインストールし、ScriptRunner 5.3.9のバージョンを使用する独自のプラグインを開発しようとします。



プラグインを作成する



ターミナルを開き、次のコマンドを入力します。



atlas-create-jira-plugin
      
      





ターミナルの質問には次のように回答します。



 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
      
      





pom.xmlを変更する



以下に、変更後の外観をpom.xmlに示します。 最も重要な部分についてコメントを書きました。



pom.xml
 <?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> <!--   pom.xml,    .    pom.xml      ScriptRunner. --> <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> <!--       ,         ScriptRunner  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> <!--   JVM,   Jira 7.9.0      . --> <jvmArgs>-Xms512M -Xmx1g</jvmArgs> <enableQuickReload>true</enableQuickReload> <enableFastdev>false</enableFastdev> <applications> <!--  Jira Software,   Jira Software    atlas-run. --> <application> <applicationKey>jira-software</applicationKey> <version>${jira.version}</version> </application> <!--  Jira Service Desk,  Jira Service Desk    atlas-run. --> <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> <!--  ,    pom   ScriptRunner. --> <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>
      
      





作成されたプラグインのディレクトリを削除します



src / main / javaおよびsrc / testディレクトリを削除します。



スクリプトを追加する



ScriptRunnerオブジェクトで使用するいくつかのスクリプトを作成しましょう。



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.scriptedfields import org.slf4j.LoggerFactory; def log = LoggerFactory.getLogger(this.getClass()) log.debug("scripted field {} executed", this.getClass())
      
      







スクリプトをテストする



次に、プラグインをインストールして、ScriptRunnerがプラグインのスクリプトを認識できるようにします。



ターミナルを開き、プラグインディレクトリに移動してコマンドを実行します。



 atlas-run
      
      





Jiraが起動したら、localhost:8080 / jiraのブラウザーに移動し、admin:adminアカウントでJiraにログインする必要があります。



スクリプトのログを表示するには、ru.matveevパッケージのDEBUGレベルを設定する必要があります。



[システム]→[ロギングとプロファイリング]に移動し、[構成]ボタンをクリックします。 [パッケージ名]フィールドにru.matveevと入力し、[ログレベル]フィールドで[デバッグ]を選択して、[追加]ボタンをクリックします。







次に、スクリプトの1つを実行してみます。 [アドオン]→[スクリプトコンソール]に移動し、[ファイル]タブでru / matveev / alexey / main / scripts / script.groovyと入力します。 また、ScriptRunnerのスクリプトにスクリプトディレクトリが表示されていることもわかります。







[実行]ボタンをクリックします。







スクリプトが正常に完了したことがわかります。



ライセンサー、スクリプトフラグメント、およびRESTメソッドを作成する



開発環境にプラグインをインストールし、オブジェクトの作成を開始します。



Lysener 1:







Lysener 2:







RESTモジュール:







スクリプトの断片:







オブジェクトを作成したら、これらのオブジェクトの説明をアンロードし、プラグインのscriptrunner.yamlファイルに配置する必要があります。



[アドオン]→[組み込みスクリプト]→[構成のエクスポート]に移動し、作成したすべてのオブジェクトを選択して[実行]ボタンをクリックします。







赤で強調表示されている長方形の内容全体をコピーして、scriptrunner.yamlファイルに保存します。



src / main / resources / scriptrunner.yaml
 !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: - ''
      
      







スクリプトフィールドを追加する



動作およびスクリプトフィールドは、scriptrunner.yamlから追加できません。 この記事では、スクリプトフィールドを作成します。 アップグレードタスクを使用してスクリプトフィールドを作成します。 アップグレードタスクは、プラグインの起動時にコードを実行できるプラグイン機能です。 コードは、まだ実行されていない場合にのみ実行されます。 アップグレードタスクを作成するには、PluginUpgradeTaskインターフェイスを実装するクラスを作成する必要があります。 さらに、クラスはパブリックサービスとして宣言する必要があります。



まず、AbstractUpgradeTask.groovyクラスを作成します(コードはScriptRunnerのサンプルスクリプトプラグインから借用しています)。 このクラスは、PluginUpgradeTaskインターフェイスを含むgetPluginKeyメソッドを実装します。 このメソッドは、プラグインのすべてのアップグレードタスクで普遍的に機能するため、別のクラスに実装されます。



src / main / groovy / ru / matveev / alexey / scriptedfields / AbstractUpgradeTask.groovy
 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); } }
      
      







PluginUpgradeTaskインターフェイスを実装するクラスを作成しましょう(コードはScriptRunnerのサンプルスクリプトプラグインから借用しています)。



src / main / groovy / ru / matveev / alexey / scriptedfields / CreateScriptFieldUpgradeTask.groovy
 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 } }
      
      







オブジェクト転送のテスト



atlas-mvn package



チームでプラグインを組み立て、テスト環境に組み立てたプラグインをインストールします。



オブジェクトが作成されたかどうかを確認します。 スクリプトフィールド:







免許証:







RESTメソッド:







スクリプトの断片:







すべてのオブジェクトが作成されていることがわかります。 これで、プラグインを任意のJiraインスタンスにインストールし、スクリプトとオブジェクトを使用できます。



All Articles