Right now it is possible to have a mismatch of fix version between parent and sub task. I want to ensure that this is not possible. No value is fine, as long as all tickets are empty.
Script Runner or other paid plugins are not an option.
I have a Script Runner script listener for this exact case, though I'm also syncing a custom field called "Verified Version/s". You probably don't need that, but I'll include it as an example. It's implemented as a groovy class file, here is a sanitized version:
import com.atlassian.jira.event.issue.AbstractIssueEventListener; import com.atlassian.jira.event.issue.IssueEvent; import com.atlassian.jira.issue.Issue; import com.atlassian.jira.project.version.Version; import com.atlassian.jira.config.SubTaskManager; import com.atlassian.jira.issue.IssueManager; import com.atlassian.jira.issue.CustomFieldManager; import com.atlassian.jira.issue.fields.CustomField; import com.atlassian.jira.event.type.EventDispatchOption; import com.atlassian.jira.workflow.WorkflowManager; import com.atlassian.jira.workflow.JiraWorkflow; import java.util.ArrayList; import java.util.Collection; class SyncParentFixVerifiedVersionsToSubTask extends AbstractIssueEventListener { Category log = Category.getInstance(SyncParentFixVerifiedVersionsToSubTask.class); SubTaskManager subTaskManager = ComponentManager.getInstance().getSubTaskManager(); WorkflowManager workflowManager = ComponentManager.getInstance().getWorkflowManager(); IssueManager issueManager = ComponentManager.getInstance().getIssueManager(); CustomFieldManager customFieldManager = ComponentManager.getInstance().getCustomFieldManager(); Boolean changed = false; Long workflowId; @Override void workflowEvent(IssueEvent event) { try { if (subTaskManager.isSubTasksEnabled()) { Issue eventIssue = event.getIssue(); JiraWorkflow workflow = workflowManager.getWorkflow(eventIssue); if (workflow.getName() == "Put Workflow Name Here") { CustomField vvcf = customFieldManager.getCustomFieldObjectByName("Verified Version/s"); if ( !eventIssue.getIssueTypeObject().isSubTask() ) { // Change is on a potential parent, sync to sub-tasks if there are any Collection<Issue> subTasks = eventIssue.getSubTaskObjects(); List changeItems = event.getChangeLog().getRelated("ChildChangeItem"); // Sync FixVersion/s if( changeItems.any {it.get('field')=='Fix Version'} ) { changed = true; // Collection<Version> fixVersions = new ArrayList<Version>(); // fixVersions = eventIssue.getFixVersions(); Collection<Version> fixVersions = eventIssue.getFixVersions(); if (!subTasks.isEmpty()) { subTasks.each { it.setFixVersions(fixVersions); } } } // Sync Verified Version/s if( changeItems.any {it.get('field')=='Verified Version/s'} ) { changed = true; Collection<Version> verifiedVersions = new ArrayList<Version>(); verifiedVersions = eventIssue.getCustomFieldValue(vvcf); if (!subTasks.isEmpty()) { subTasks.each { it.setCustomFieldValue(vvcf,verifiedVersions); } } } if (changed) { subTasks.each { issueManager.updateIssue(event.getUser(), it, EventDispatchOption.ISSUE_UPDATED, false); } } } else { // Change is on a sub-task, sync from the parent if they are out of sync Issue parentIssue = eventIssue.getParentObject(); // Sync "Fix Version/s" Collection<Version> parentFixVersions = parentIssue.getFixVersions(); if (parentFixVersions == null) parentFixVersions = new ArrayList<Version>(); Collection<Version> fixVersions = eventIssue.getFixVersions(); if (fixVersions == null) fixVersions = new ArrayList<Version>(); if(!(parentFixVersions.containsAll(fixVersions) && fixVersions.containsAll(parentFixVersions))) { eventIssue.setFixVersions(parentFixVersions); changed = true; } // Sync "Verified Version/s" Collection<Version> parentVerifiedVersions = parentIssue.getCustomFieldValue(vvcf); if (parentVerifiedVersions == null) parentVerifiedVersions = new ArrayList<Version>(); Collection<Version> verifiedVersions = eventIssue.getCustomFieldValue(vvcf); if (verifiedVersions == null) verifiedVersions = new ArrayList<Version>(); if(!(parentVerifiedVersions.containsAll(verifiedVersions) && verifiedVersions.containsAll(parentVerifiedVersions))) { eventIssue.setCustomFieldValue(vvcf,parentVerifiedVersions); changed = true; } if (changed) { issueManager.updateIssue(event.getUser(), eventIssue, EventDispatchOption.ISSUE_UPDATED, false); } } } } } catch (ex) { log.debug "Event: ${event.getEventTypeId()} fired for ${event.issue} and caught by SyncParentFixVerifiedVersionsToSubTask" log.debug (ex.getMessage()) } } }
I added the workflow name check so that the listener can be set for all projects, that way you don't risk adding a project and forgetting to add it. That worked for me, but may not for you.
Having said all of that, I've heard people mention that there is some built-in way to sync that field, but I don't have details. It may be that they can only be synced on sub-task creation. Speaking of, the checking for an update to the sub-task is to handle the case where you add a sub-task, or move an issue to a sub-task, etc.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
WOW! Thanks! I should have mentioned Script Runner isn't really an option for us since it's no longer free, and installing it will force us to remain at version 6. We're not using Script Runner now - I was tempted, but shortly after installation it went from free to fee.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I may be wrong about getting Script Runner - I'll be giving this a try soon! Thanks again!!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Jeremy Gaudet I am looking for a solution to the same question too. So, in script listener, we are supposed to place a groovy file in the listeners folder right ? So, what would be the content of that file. Is it the same script as above ? Thanks
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.