Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Create Issus in Epic with Post Function

Austin Boyd July 23, 2019

I have a script that I had working but now for some reason it isn't and I can't figure out why. The script is supposed to work as a post function for an Epic being created, and based on checked values in a checkbox field, it should create issues in the epic during the create issue step. 

 

There are no system errors, and the logging I put in places seems to work, but no new issues are being created and being linked to the epic. 

 

Here is the code setup for running in the Script Console: 

 

import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.project.Project
import groovy.transform.Field
import com.atlassian.jira.issue.customfields.option.LazyLoadedOption
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.user.ApplicationUser
import org.apache.log4j.Logger
import org.apache.log4j.Level




// Enable logging so that you can use something like log.debug("Creating new issue, based on Collateral..")
Logger log = Logger.getLogger("com.example")
log.setLevel(Level.DEBUG)

def customFieldManager = ComponentAccessor.getCustomFieldManager()
@Field
ApplicationUser user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

// Define the name of the custom field you're wanting to target for creating issues against
def customFieldName = 'Elements'
// Get the custom field object
def customFieldObject = customFieldManager.getCustomFieldObjectByName(customFieldName)
// To test in the script console, uncomment the next line and enter an existing ticket number
def issue = ComponentAccessor.getIssueManager().getIssueObject("WWM-1550")
// Comment out the next line when testing in the script console, otherwise it is necessary when placing in a post fuction
// Issue issue = issue

// Get all the values of the custom field
def customFieldValues = customFieldObject.getValue(issue)


// For each checkbox in the custom field selected, the next two sections will create a ticket for it
customFieldValues.each { LazyLoadedOption it ->
def optionValue = it.getValue()
log.debug("Getting Custom Field Values: ${customFieldValues}")
def newIssue = createIssue(issue, optionValue)
}


private Issue createIssue(Issue issue, String optionValue) {
// Enable logging so that you can use something like log.debug("Creating new issue, based on Collateral..")
Logger log = Logger.getLogger("com.example")
log.setLevel(Level.DEBUG)
Project project = issue.getProjectObject()
IssueService issueService = ComponentAccessor.issueService
IssueInputParameters issueInputParameters = issueService.newIssueInputParameters()
def constantsManager = ComponentAccessor.getConstantsManager()
def customFieldManager = ComponentAccessor.getCustomFieldManager()
// Define epic link
def epicLink = customFieldManager.getCustomFieldObjectByName("Epic Link")
log.debug("Epic Link = ${issue.key}")

// This is where to set issue parameters like issue type, custom field values, reporter, etc
issueInputParameters.setProjectId(project.id)
.setIssueTypeId("3")
.setReporterId(user.name)
.setSummary("Test issue - " + optionValue)
.addCustomFieldValue(epicLink.id, issue.key)


// This part validates the issue creation
IssueService.CreateValidationResult createValidationResult = issueService.validateCreate(user, issueInputParameters);
Issue newIssue
if (createValidationResult.isValid()) {
IssueService.IssueResult createResult = issueService.create(user, createValidationResult);
if (createResult.isValid()) {
newIssue = createResult.issue
}

}
log.debug("Creating new issue, based on ${optionValue}..")
return newIssue
}


 

I'm pretty new to groovy so I may need some specific help with additional logging to track down the issue. 

 

Edit:  I do see this in the catalina.out logs: 

23-Jul-2019 15:09:11.872 WARNING [http-nio-8080-exec-12] com.sun.jersey.spi.container.servlet.WebComponent.filterFormParameters A servlet request, to the URI https://subdomain.domain.net/rest/scriptrunner/latest/canned/com.onresolve.scriptrunner.canned.common.StaticCompilationChecker, contains form parameters in the request body but the request body has been consumed by the servlet or a servlet filter accessing the request parameters. Only resource methods using @FormParam will work as expected. Resource methods consuming the request body by other means will not work as expected.

 

1 answer

1 accepted

0 votes
Answer accepted
Steven F Behnke
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 23, 2019

Your script works for me through console. It will not link them to the Epic if the Epic Link is not actually present on the Create screen for the Task issuetype (issuetype == '3'). 

You can completely ignore the log line

23-Jul-2019 15:09:11.872 WARNING [http-nio-8080-exec-12] com.sun.jersey.spi.container.servlet.WebComponent.filterFormParameters A servlet request, to the URI https://subdomain.domain.net/rest/scriptrunner/latest/canned/com.onresolve.scriptrunner.canned.common.StaticCompilationChecker, contains form parameters in the request body but the request body has been consumed by the servlet or a servlet filter accessing the request parameters. Only resource methods using @FormParam will work as expected. Resource methods consuming the request body by other means will not work as expected.

It is irrelevant and is related to the UI in the scriptrunner plugin, nothing more.

 

Can you confirm that for sure no issues are created? You may want to create a list of all issues you're creating, and then print them at the end to see if it gives you a clue. Since the script worked for me via copy paste into console, I suspect it's creating issues but not linking them.

 

Additionally, I rewrote the script a bit for accuracy and clarity here:

import com.atlassian.jira.component.ComponentAccessor

import com.atlassian.greenhopper.api.customfield.ManagedCustomFieldsService
import com.onresolve.scriptrunner.runner.customisers.JiraAgileBean
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueInputParameters
import com.atlassian.jira.issue.customfields.option.Option
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.user.ApplicationUser
import org.apache.log4j.Logger
import org.apache.log4j.Level

Logger log = Logger.getLogger('com.myscript.createIssuesInEpic')
log.setLevel(Level.DEBUG)

@WithPlugin("com.pyxis.greenhopper.jira")
@JiraAgileBean
ManagedCustomFieldsService agileCustomFields

def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def customField = ComponentAccessor.customFieldManager.getCustomFieldObject(19617L)
def epicLinkField = agileCustomFields.getEpicLinkCustomField().get()
def issueService = ComponentAccessor.issueService
def issue = ComponentAccessor.issueManager.getIssueByCurrentKey('JIRA-2368')
// issue = issue as Issue

Closure<IssueInputParameters> generateInputFrom = { Issue epic, Option option ->
def input = issueService.newIssueInputParameters()
input.setProjectId(10600L)
.setIssueTypeId('3')
.setReporterId(user.name)
.setSummary('Hello World')
.addCustomFieldValue(epicLinkField.idAsLong, epic.key)

return input
}

Closure<Issue> createIssueUsing = { IssueInputParameters input ->
def validation = issueService.validateCreate(user, input)
if (!validation.isValid()) {
log.error "Error while validating input. ${validation.errorCollection}"
return null
}

def result = issueService.create(user, validation)
if (!result.isValid()) {
log.error "Error while creating issue. ${result.errorCollection}"
return null
}

return result.issue as Issue
}

def values = issue.getCustomFieldValue(customField) as List<Option>
if (values == null) return

def issues = values.collect { Option option ->
generateInputFrom(issue, option)
}.collect { IssueInputParameters input ->
createIssueUsing(input)
}

log.debug "Created following issues: ${issues}"
Austin Boyd July 23, 2019

Thanks @Steven F Behnke your hint about the Epic Link field led me to figuring out that I was targeting an issuetype that wasn't part of the Issue Type Scheme in the project I had been working out of. 

Like Steven F Behnke likes this

Suggest an answer

Log in or Sign up to answer