Some customers and some partners may be using ScriptRunner in order to automate some tasks and even extend the features provided by Jira.
You can also do some automation related with Xray, specially because we use Jira entities and concepts.
ScriptRunner may be used in order to access existing features or even to extend the built-in features.
Let us know if you're using also ScriptRunner and your use cases so we can improve and share them with other users.
The following scripts are provided as-is, no warranties attached. Use these scripts carefully. Please feel free to adapt them to your needs. Note: We don't provide support for ScriptRunner; if you have doubts concerning its usage, please contact ScriptRunner's support. |
Sometimes you may need to assure that the coverable issue (e.g. requirement) is covered before transitioning it to some status, or before resolving it.
The following script validates the requirement based on the directly linked tests to it.
This solution is not perfect for several reasons, so please take the following notes into consideration:
|
You need to:
Map<String, Object> searchResult = get('/rest/api/2/search') .queryString('jql', "key = ${issue.key} and hasLinks = 'is tested by'") .asObject(Map) .body // if no Tests linked, then force a certain transition (i.e. rollback it) if (searchResult.issues.size == 0) { def res = post("/rest/api/2/issue/" + issue.key + "/transitions") .header("Content-Type", "application/json") .body([ "transition": [ "id": "301" ] ]) .asString() //assert res.status == 204 } |
Whenever you change the specification of a requirement, for example, you most probably will need to review the Tests that you have already specified.
The following script tries to make a transition on all linked Tests to a requirement. You can hook it to a post-function on the transition of the covered issue.
This solution is not perfect because the tests association should be validated properly, based on all the direcly and indirectly linked tests. |
import org.apache.log4j.Logger import org.apache.log4j.Level def transitionIssue(issueKey, transitionId){ def res = post("/rest/api/2/issue/" + issueKey + "/transitions") .header("Content-Type", "application/json") .body([ "transition": [ "id": transitionId ] ]) .asString() } def log = Logger.getLogger("com.example.script") log.setLevel(org.apache.log4j.Level.DEBUG) def result = get('/rest/api/2/issue/' + issue.key) .header('Content-Type', 'application/json') .asObject(Map) if (result.status == 200){ def issueLinks = (List<Map<String, Object>>) result.body.fields.issuelinks def mapping = issueLinks.groupBy { issueLink -> ((Map<String, Map>) issueLink).type.inward }.collectEntries { linkName, linkItem -> [(linkName): linkItem.inwardIssue.key] } log.debug mapping['is tested by'] def transitionId = 11 // Done=>TODO mapping['is tested by'].each { testKey -> transitionIssue(testKey, transitionId) } } else { return "Failed to find issue: Status: ${result.status} ${result.body}" } |
You need to:
In the following example, we'll create a text custom field to show the total amount of directly linked Tests to a given coverable issue.
ScriptRunner for Jira Cloud does not provide scripted field; thus, we have to create a standard text (single line) custom field and we'll update it periodically. For the later, we'll use a periodic job. |
import org.apache.log4j.Logger import org.apache.log4j.Level def transitionIssue(issueKey, transitionId){ def res = post("/rest/api/2/issue/" + issue.key + "/transitions") .header("Content-Type", "application/json") .body([ "transition": [ "id": transitionId ] ]) .asString() } def log = Logger.getLogger("com.example.script") log.setLevel(org.apache.log4j.Level.DEBUG) def issueKey = 'CALC-1' def result = get('/rest/api/2/issue/' + issue.key) .header('Content-Type', 'application/json') .asObject(Map) if (result.status == 200){ def issueLinks = (List<Map<String, Object>>) result.body.fields.issuelinks def mapping = issueLinks.groupBy { issueLink -> ((Map<String, Map>) issueLink).type.inward }.collectEntries { linkName, linkList -> [(linkName): linkList.size()] } log.debug mapping['is tested by'] def testsCountCF = "customfield_10027" def res = put("/rest/api/2/issue/${issue.key}") .header("Content-Type", "application/json") .body([ fields:[ (testsCountCF): mapping['is tested by'].toString() ] ]) .asString() } else { return "Failed to find issue: Status: ${result.status} ${result.body}" } |
You need to: