how use ScriptRunner to convert a subtask to a issue

zhang store January 17, 2021

I want to implement such a function. When a user creates a subtask, the subtask is automatically converted to an issue, and then the issue and the parent issue are associated into a link of type blocks

2 answers

1 vote
Ismael Jimoh
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.
January 17, 2021

Hi @zhang store 

Can you clarify your use case here? You could simply remove the sub-task issue type from the project or add a validator to the create transition that prevents users from creating sub-tasks.

Once the above is in place, you can then instruct them clearly on how to create linked issues.

The above is a process I’ll recommend rather than converting sub-tasks to standard issues.

Regards.

zhang store January 17, 2021

Well, we originally wanted to use subtask to manage user stories and tasks. However, after using subtask, we found that there was a problem in the estimation of development time. Later, we wanted to use linked issue to solve the problem. However, using the linked issue function of ScriptRunner will cause the dialog box not to close after creating an issue, and it will also lead to the situation that it cannot be linked. So I want to automatically convert subtask to issue by listener after creating subtask

Ismael Jimoh
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.
January 18, 2021

Hi @zhang store 

The above is weird and I would suggest looking at your logs to confirm why your linked issues behave as they do.

The process of converting sub-task into linked issues doesn’t also guarantee you that all would be fine because you could the run into the same issues you initially had when creating standard linked issues.

Provide a log entry of what happens when you create a linked issue and the error shown on the screen and I’ll try and assist with this.

Regards.

0 votes
Max Lim _Adaptavist_
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.
January 19, 2021

Looking at your requirements:

1. You want to create an issue using a button just like More>Create Sub-task button.

2. The issue is automatically linked to the issue the button is pressed on.

 

This is exactly the kind of use case for Create Constrained Issue feature of ScriptRunner.

1. Navigate ScriptRunner>Fragments>Create Script Fragments>Constrained create issue dialog:

  • Under "What section should this go in", choose "operations-top-level" or "operations-subtasks" (try them yourself).
  • Under "Key", fill in "link-create-report" (or anything you liked, it is used below)

2. To automatically linked to the issue, create a behaviour. Navigate ScriptRunner>Behaviours>Add Behaviour>Add same mapping as the button> On Initialiser, add the following script:

import com.atlassian.jira.component.ComponentAccessor

if (getBehaviourContextId() == "link-create-report") {

// the name of the issue link
final String issueLinkName = "blocks"

def contextIssueKey = ComponentAccessor.getIssueManager().getIssueObject(getContextIssueId()).getKey()

getFieldById("issuelinks-linktype").setFormValue(issueLinkName)
getFieldById("issuelinks-issues").setFormValue([contextIssueKey])
}

getBehaviourContextId() and getContextIssueId() are documented here.

 

Note: If you feel like ScriptRunner is not behaving probably, please submit a report through support portal.

zhang store January 19, 2021
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.onresolve.scriptrunner.runner.util.OSPropertyPersister
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.security.roles.ProjectRoleManager
import com.atlassian.jira.bc.project.component.ProjectComponentManager
import com.atlassian.jira.issue.IssueFieldConstants

import static com.atlassian.jira.issue.IssueFieldConstants.ISSUE_TYPE

def issueManager = ComponentAccessor.getIssueManager()
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def projectRoleManager = ComponentAccessor.getComponent(ProjectRoleManager)
def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser

if ("create-linked-blocking-issue" == getBehaviourContextId() && "" == getFieldById("customfield_10117").getValue()) {
// 设置类型
def allIssueTypes = ComponentAccessor.constantsManager.allIssueTypeObjects
def issueTypeField = getFieldById(ISSUE_TYPE)

def remoteUsersRoles = projectRoleManager.getProjectRoles(user, issueContext.projectObject)*.name
def availableIssueTypes = []
availableIssueTypes.addAll(allIssueTypes.findAll { it.name in ["Bug", "Improvement", "New Feature"] })
issueTypeField.setFieldOptions(availableIssueTypes)

def contextIssue = issueManager.getIssueObject(getContextIssueId())
def sprintField = customFieldManager.getCustomFieldObjectsByName("Sprint")
def sprintName = contextIssue.getCustomFieldValue(sprintField)?.name?.last()?.toString()

// 设置项目
def projectComponentManager = ComponentAccessor.getComponent(ProjectComponentManager)
def projectComponents = projectComponentManager.findAllForProject(contextIssue?.projectObject?.id)
getFieldById("components").setFieldOptions(projectComponents)
getFieldById("project-field").setFormValue(contextIssue?.projectObject?.name)

// 设置类型
if (contextIssue?.issueType?.name?.contains("Improvement")) {
issueTypeField.setFormValue("Improvement")
} else if (contextIssue.issueType.name?.contains("Bug")) {
issueTypeField.setFormValue("Bug")
} else if (contextIssue?.issueType?.name?.contains("Feature")) {
issueTypeField.setFormValue("New Feature")
} else {
issueTypeField.setFormValue("New Feature")
}
// issueTypeField.setReadOnly(true)

getFieldById("issuelinks-linktype").setFormValue("blocks").setReadOnly(true)
getFieldById("issuelinks-issues").setFormValue(contextIssue.key).setReadOnly(true)

def summary = contextIssue?.summary
getFieldById("summary").setFormValue(summary.substring(summary.indexOf("】") + 1, summary.length()))
getFieldById("description").setFormValue(contextIssue.description)
// 设置Owner
getFieldById("customfield_10117").setFormValue(contextIssue.getCustomFieldValue(customFieldManager.getCustomFieldObjectByName("Owner"))?.name)
// 设置QA
getFieldById("customfield_10114").setFormValue(contextIssue.getCustomFieldValue(customFieldManager.getCustomFieldObjectByName("QA"))?.name)
// 设置Reviewer
getFieldById("customfield_10113").setFormValue(contextIssue.getCustomFieldValue(customFieldManager.getCustomFieldObjectByName("Reviewer"))?.name)
// 设置优先级
getFieldById("priority-field").setFormValue(contextIssue?.priority?.name)
// 不复制组件值,因为创建链接任务一般都是创建属于其它组件的任务
// 设置时间追踪
getFieldById("timetracking_originalestimate").setFormValue("3h")
getFieldById("timetracking_remainingestimate").setFormValue("3h")
getFieldById("customfield_10106").setFormValue("3")
// 设置标签
String[] labels = contextIssue.labels
getFieldById(IssueFieldConstants.LABELS).setFormValue(labels)
// Sprint的值,暂时不能设置值,只能设置成必填
getFieldById("customfield_10101-field").setRequired(true)
// getFieldById("customfield_10101-field").setFormValue(sprintName)
}

getFieldById("issuelinks-linktype").setHidden(true)
getFieldById("issuelinks-issues").setHidden(true)

 

This is my code. There is a problem: each project needs to create a constrained create issue dialog, which is very unfriendly

zhang store January 19, 2021
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.onresolve.scriptrunner.runner.util.OSPropertyPersister
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.security.roles.ProjectRoleManager
import com.atlassian.jira.bc.project.component.ProjectComponentManager
import com.atlassian.jira.issue.IssueFieldConstants

import static com.atlassian.jira.issue.IssueFieldConstants.ISSUE_TYPE

def issueManager = ComponentAccessor.getIssueManager()
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def projectRoleManager = ComponentAccessor.getComponent(ProjectRoleManager)
def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser

if ("create-linked-blocking-issue" == getBehaviourContextId() && "" == getFieldById("customfield_10117").getValue()) {
// 设置类型
def allIssueTypes = ComponentAccessor.constantsManager.allIssueTypeObjects
def issueTypeField = getFieldById(ISSUE_TYPE)

def remoteUsersRoles = projectRoleManager.getProjectRoles(user, issueContext.projectObject)*.name
def availableIssueTypes = []
availableIssueTypes.addAll(allIssueTypes.findAll { it.name in ["Bug", "Improvement", "New Feature"] })
issueTypeField.setFieldOptions(availableIssueTypes)

def contextIssue = issueManager.getIssueObject(getContextIssueId())
def sprintField = customFieldManager.getCustomFieldObjectsByName("Sprint")
def sprintName = contextIssue.getCustomFieldValue(sprintField)?.name?.last()?.toString()

// 设置项目
def projectComponentManager = ComponentAccessor.getComponent(ProjectComponentManager)
def projectComponents = projectComponentManager.findAllForProject(contextIssue?.projectObject?.id)
getFieldById("components").setFieldOptions(projectComponents)
getFieldById("project-field").setFormValue(contextIssue?.projectObject?.name)

// 设置类型
if (contextIssue?.issueType?.name?.contains("Improvement")) {
issueTypeField.setFormValue("Improvement")
} else if (contextIssue.issueType.name?.contains("Bug")) {
issueTypeField.setFormValue("Bug")
} else if (contextIssue?.issueType?.name?.contains("Feature")) {
issueTypeField.setFormValue("New Feature")
} else {
issueTypeField.setFormValue("New Feature")
}
// issueTypeField.setReadOnly(true)

getFieldById("issuelinks-linktype").setFormValue("blocks").setReadOnly(true)
getFieldById("issuelinks-issues").setFormValue(contextIssue.key).setReadOnly(true)

def summary = contextIssue?.summary
getFieldById("summary").setFormValue(summary.substring(summary.indexOf("】") + 1, summary.length()))
getFieldById("description").setFormValue(contextIssue.description)
// 设置Owner
getFieldById("customfield_10117").setFormValue(contextIssue.getCustomFieldValue(customFieldManager.getCustomFieldObjectByName("Owner"))?.name)
// 设置QA
getFieldById("customfield_10114").setFormValue(contextIssue.getCustomFieldValue(customFieldManager.getCustomFieldObjectByName("QA"))?.name)
// 设置Reviewer
getFieldById("customfield_10113").setFormValue(contextIssue.getCustomFieldValue(customFieldManager.getCustomFieldObjectByName("Reviewer"))?.name)
// 设置优先级
getFieldById("priority-field").setFormValue(contextIssue?.priority?.name)
// 不复制组件值,因为创建链接任务一般都是创建属于其它组件的任务
// 设置时间追踪
getFieldById("timetracking_originalestimate").setFormValue("3h")
getFieldById("timetracking_remainingestimate").setFormValue("3h")
getFieldById("customfield_10106").setFormValue("3")
// 设置标签
String[] labels = contextIssue.labels
getFieldById(IssueFieldConstants.LABELS).setFormValue(labels)
// Sprint的值,暂时不能设置值,只能设置成必填
getFieldById("customfield_10101-field").setRequired(true)
// getFieldById("customfield_10101-field").setFormValue(sprintName)
}

getFieldById("issuelinks-linktype").setHidden(true)
getFieldById("issuelinks-issues").setHidden(true)

 

This is my code. There is a problem: each project needs to create a constrained create issue dialog, which is very unfriendly

Suggest an answer

Log in or Sign up to answer