Page History
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
import com.atlassian.jira.issue.Issue import com.atlassian.jira.issue.link.IssueLinkManager import com.atlassian.jira.issue.link.IssueLinkType import com.atlassian.jira.issue.link.IssueLinkTypeManager import com.atlassian.jira.ComponentManager import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.jql.builder.JqlQueryBuilder import com.atlassian.jira.user.util.UserUtil import com.atlassian.jira.user.util.UserManager; import com.atlassian.jira.bc.issue.IssueService import com.atlassian.jira.bc.issue.search.SearchService import com.atlassian.jira.issue.search.SearchProvider import com.atlassian.jira.issue.search.SearchResults import com.atlassian.jira.web.bean.PagerFilter; import com.atlassian.jira.issue.MutableIssue import com.atlassian.jira.user.UserPropertyManager import com.atlassian.jira.propertyset.JiraPropertySetFactory; import com.google.common.collect.ImmutableMap; import com.opensymphony.module.propertyset.PropertySet; import com.opensymphony.module.propertyset.PropertySetManager; import com.atlassian.jira.util.BuildUtils import com.atlassian.jira.util.BuildUtilsInfo import com.atlassian.jira.util.BuildUtilsInfoImpl import com.atlassian.plugin.PluginAccessor import com.atlassian.plugin.PluginManager import com.atlassian.jira.bc.license.JiraLicenseService import com.atlassian.jira.bc.license.JiraLicenseServiceImpl import org.apache.log4j.Level import org.apache.log4j.Logger import com.atlassian.jira.issue.IssueManager import org.ofbiz.core.entity.GenericValue import com.atlassian.jira.ComponentManager import com.atlassian.jira.event.type.EventDispatchOption import groovy.json.JsonOutput import groovy.transform.BaseScript import groovy.json.JsonSlurper; import groovy.json.StreamingJsonBuilder; import javax.ws.rs.core.MultivaluedMap import javax.ws.rs.core.Response import com.atlassian.jira.issue.index.IssueIndexingService import com.atlassian.jira.util.ImportUtils import com.atlassian.jira.bc.issue.IssueService import com.atlassian.jira.bc.issue.IssueService.CreateValidationResult import com.atlassian.jira.bc.issue.IssueService.IssueResult import com.atlassian.jira.user.ApplicationUser Logger.getLogger("com.onresolve").setLevel(Level.DEBUG) projectManager = ComponentAccessor.getProjectManager() componentManager = ComponentManager.getInstance() issueManager = ComponentAccessor.getIssueManager() def issueFactory = ComponentAccessor.getIssueFactory() issueService = ComponentAccessor.issueService searchService = ComponentAccessor.getComponent(SearchService.class); serviceAccount = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser() customFieldManager = ComponentAccessor.getCustomFieldManager() def subTaskManager = ComponentAccessor.getSubTaskManager() issueService = ComponentAccessor.getIssueService() def user = ComponentAccessor.jiraAuthenticationContext.getLoggedInUser() Object getIssues(jqlQuery){ // A list of GenericValues representing issues List<Issue> searchResults = null; SearchService.ParseResult parseResult = searchService.parseQuery(serviceAccount, jqlQuery); if (parseResult.isValid()) { // throws SearchException SearchResults results = searchService.search(serviceAccount, parseResult.getQuery(), PagerFilter.getUnlimitedFilter()); searchResults = results.getIssues(); return searchResults; } return [] } Object getFieldValueByName(issue,customField) { def cField = customFieldManager.getCustomFieldObjectByName(customField) def cFieldValue = issue.getCustomFieldValue(cField) return cFieldValue } Object setFieldValueByName(issue,customField,value) { def cField = customFieldManager.getCustomFieldObjectByName(customField) issue.setCustomFieldValue(cField,*value) } Object setFieldValueByNameInParameters(inputParameters,customFieldName,value) { def customField = customFieldManager.getCustomFieldObjectByName(customFieldName) inputParameters.addCustomFieldValue(customField.id, value) } def project = projectManager.getProjectObjByKey("CALC") def newIssueType = ComponentAccessor.issueTypeSchemeManager.getIssueTypesForProject(project).find { it.name == "Test Execution" } def newIssue def issueInputParameters = issueService.newIssueInputParameters() issueInputParameters.with { projectId = project.id summary = "Issue created from script" issueTypeId = newIssueType.id reporterId = user.name } def jql = "project = ${project.key} and issuetype = Test and component = UI" def issues = getIssues(jql) def testKeys = issues.collect{ it.key } appUser = user.getDirectoryUser() CreateValidationResult createValidationResult = issueService.validateCreate(user, issueInputParameters) if (!createValidationResult.isValid()) { log.error "Error validating new issue"+createValidationResult.getErrorCollection() } else { IssueResult createResult = issueService.create(user, createValidationResult) newIssue = createResult.issue log.debug(newIssue.key) associateTestsToTestExecution(newIssue.key, testKeys) } |
Validate requirement
...
upon making a transition
Sometimes you may need to assure that the requirement is actually OK covered before transitioning it to some status, or before resolving it.
The following script validates the requirement based on the directly linked tests executed for the version assigned to the requirement issue.
You can either make the validation based on the existence of failed tests (i.e. requirement status is "NOK") or, in a more complete way by making sure all of them are passing (i.e. requirement status is "OK").
.
Info | ||
---|---|---|
| ||
This solution is not perfect for several reasons, so please take the following notes into consideration:
|
You need to:
- edit the workflow transition of the "coverable issue" (e.g. story, requirement), by editing the related workflow
- add a ScriptRunner Post Function, in the Post Functions tab
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
Map<String, Object> searchResult = get('/rest/api/2/search') | ||||||
Code Block | ||||||
| ||||||
import com.atlassian.jira.issue.Issue import com.atlassian.jira.issue.link.IssueLinkManager import com.atlassian.jira.issue.link.IssueLinkType import com.atlassian.jira.issue.link.IssueLinkTypeManager import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.jql.builder.JqlQueryBuilder import com.atlassian.jira.user.util.UserManager; import com.atlassian.jira.bc.issue.IssueService import com.atlassian.jira.bc.issue.search.SearchService; import com.atlassian.jira.issue.search.SearchProvider import com.atlassian.jira.issue.search.SearchResults import com.atlassian.jira.web.bean.PagerFilter; import com.atlassian.jira.issue.MutableIssue import com.atlassian.jira.user.UserPropertyManager import com.atlassian.jira.propertyset.JiraPropertySetFactory; import com.google.common.collect.ImmutableMap; import com.opensymphony.module.propertyset.PropertySet; import com.opensymphony.module.propertyset.PropertySetManager; import com.atlassian.jira.util.BuildUtils import com.atlassian.jira.util.BuildUtilsInfo import com.atlassian.jira.util.BuildUtilsInfoImpl import com.atlassian.plugin.PluginManager import com.atlassian.jira.bc.license.JiraLicenseService import com.atlassian.jira.bc.license.JiraLicenseServiceImpl import org.apache.log4j.Level import org.apache.log4j.Logger import com.atlassian.jira.issue.IssueManager import com.opensymphony.workflow.InvalidInputException Object getIssues(jqlQuery){ // A list of GenericValues representing issues List<Issue> searchResults = null; SearchService.ParseResult parseResult = searchService.parseQuery(serviceAccount, jqlQuery); if (parseResult.isValid()) { // throws SearchException SearchResults results = searchService.search(serviceAccount, parseResult.getQuery(), PagerFilter.getUnlimitedFilter()); searchResults = results.getIssues(); return searchResults; } .queryString('jql', "key return [] } searchService = ComponentAccessor.getComponent(SearchService.class); issueManager = ComponentAccessor.getIssueManager() serviceAccount = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser() Issue issue = issue; log.debug(issue.project.name) projectName = issue.project.name version = issue.fixVersions.join('') log.debug(version) //jql = "key = ${issue.key} and issue in requirements('NOK','${projectName}','${version}')" jql = "key = ${issue.key} and issue in requirements('OK','${projectName}','${version}')" issues = getIssues(jql) count = issues.size //log.debug(count) /* if (count>0) { invalidInputException = new InvalidInputException("Some tests are failing. You must assure that they pass before making the transition.") } */ if (count == 0) { invalidInputException = new InvalidInputException("Some tests need to be executed. You must assure that they pass before making the transition.")= ${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 } |
Reopen/transition linked Tests to a requirement
...