Just a heads up: On March 24, 2025, starting at 4:30pm CDT / 21:30 UTC, the site will be undergoing scheduled maintenance for a few hours. During this time, the site might be unavailable for a short while. Thanks for your patience.
×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
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.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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:
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Online forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.