I have no useful feedback on the changes (haven't had a chance to test
them, probably won't soon) - just wanted to say thanks for taking point on
this Benedict.

On Tue, Apr 16, 2019 at 6:23 AM Benedict Elliott Smith <bened...@apache.org>
wrote:

> Some exciting news from the Jira changes (maybe).
>
> We’re done!  We’ve even achieved the stretch goals.
>
> Does anyone have any further suggestions from the new workflow, after
> having tried it out for a bit?  Speak up while we have the easy capability
> to make changes!
>
> - Somebody has proposed making Change Category a multi-select list, which
> would require recreating this.  Does anybody have an opinion on this?
> - Would anybody prefer that one of the new fields be recreated as a
> project-specific select-list, like Platform and Impacts (see below), so we
> can manage the options?
>
> Gavin McDonald kindly set us up with two plugins.  With the ScriptRunner
> plugin, I’ve setup scripted listeners to maintain the Authors field (based
> on Assignee) and Priority field (based on updates to Severity), as well as
> initialising both of these for all issues.  Try it out - it works
> surprisingly well, but please let me know ASAP if there are any bugs.
>
> The Authors management may be slightly unintuitive, in that if assignee is
> updated we always overwrite Authors to the value of the assignee.  We could
> maybe do something more sophisticated by checking what the prior value of
> Assignee was, but this looked very fiddly.  I think in the vast majority of
> circumstances this will work as we expect; if there are multiple authors
> actively working I expect the assignee not to change; if the assignee is
> cleared we probably want to clear the Authors field; and if it is set to a
> new value it’s probably the new author.  If somebody has suggestions for a
> better approach, please chime in.
>
> The other plugin provided us with project-specific select lists - which
> we’ve used for Platform and Impacts.  These can be modified by any project
> admin, so we can maintain them ourselves.  Impacts and Platform have a
> default value of None and All respectively, to avoid UX ugliness with this
> multi-select list; don’t ask me why this makes them prettier, but it does.
> I had originally proposed using these values so that we could force the
> user to specify a value, but opted to not make the UX ugly, while
> supporting project ownership of the options.  Opinions on this decision
> welcome.
>
> For posterity, here are the ScriptRunner scripts I used and setup:
>
>
> ===== LISTENER TO SET PRIORITY WHEN SEVERITY UPDATED ====
>
> import com.atlassian.jira.component.ComponentAccessor
> import com.atlassian.jira.event.type.EventDispatchOption
> import com.atlassian.jira.issue.MutableIssue
> import com.atlassian.jira.util.ImportUtils
> import com.atlassian.jira.user.ApplicationUser;
> import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
> import com.atlassian.jira.issue.util.IssueChangeHolder
> import com.atlassian.jira.issue.priority.Priority
> import com.atlassian.jira.issue.context.IssueContext
> import com.atlassian.jira.issue.customfields.option.Option
> import com.atlassian.jira.issue.customfields.option.Options
> import com.atlassian.jira.issue.customfields.manager.OptionsManager
>
> def issue = event.issue as MutableIssue
> def severityChange = null !=
> event?.getChangeLog()?.getRelated("ChildChangeItem")?.find {it.field ==
> "Severity"}
> if (issue.issueType.name == "Bug" && severityChange) {
>     def issueManager = ComponentAccessor.getIssueManager()
>     def customFieldManager = ComponentAccessor.getCustomFieldManager()
>     def cf =
> customFieldManager.getCustomFieldObject("customfield_12313820" );
>
>     def constantsManager = ComponentAccessor.getConstantsManager()
>     Priority pUrgent = constantsManager.getPriorities().find {it.name ==
> "Urgent"}
>     Priority pHigh = constantsManager.getPriorities().find {it.name ==
> "High"}
>     Priority pNormal = constantsManager.getPriorities().find {it.name ==
> "Normal"}
>     Priority pLow = constantsManager.getPriorities().find {it.name ==
> "Low"}
>
>     def optManager = ComponentAccessor.getOptionsManager();
>     Options severities =
> optManager.getOptions(cf.getRelevantConfig(IssueContext.GLOBAL))
>     Option sCritical = severities.getOptionForValue("Critical", null)
>     Option sNormal = severities.getOptionForValue("Normal", null)
>     Option sLow = severities.getOptionForValue("Low", null)
>
>     def sdUser = ComponentAccessor.getUserManager().getUserByKey('robot')
>     def priority = issue.getPriority()
>     def severity = issue.getCustomFieldValue(cf)
>
>     if (severity != null) {
>         def newPriority = priority;
>         if (severity == sCritical) {
>             newPriority = pUrgent
>         } else if (severity == sNormal) {
>             newPriority = pNormal
>         } else if (severity == sLow) {
>             newPriority = pLow
>         }
>         if (newPriority != priority) {
>             issue.setPriority(newPriority)
>             issueManager.updateIssue(sdUser, issue,
> EventDispatchOption.DO_NOT_DISPATCH, false)
>         }
>     }
> }
>
>
> ===== LISTENER TO SET AUTHORS WHEN ASSIGNEE UPDATED ====
>
> import com.atlassian.jira.issue.Issue
> import com.atlassian.jira.issue.ModifiedValue
> import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
> import com.atlassian.jira.component.ComponentAccessor
> import com.atlassian.jira.user.ApplicationUser;
> import com.atlassian.jira.issue.MutableIssue
> import com.atlassian.jira.event.type.EventDispatchOption
> import com.atlassian.jira.issue.index.IssueIndexingService
>
> def sdUser = ComponentAccessor.getUserManager().getUserByKey('robot')
> def issueManager = ComponentAccessor.getIssueManager()
> def customFieldManager = ComponentAccessor.getCustomFieldManager()
> def cf = customFieldManager.getCustomFieldObjectByName( "Authors" );
>
> def issue = event.issue as MutableIssue
> def assignee = issue.getAssignee()
> if (assignee != null) {
>     def authors = (List<ApplicationUser>)issue.getCustomFieldValue(cf)
>     if (authors == null || !authors.contains(assignee)) {
>         authors = new ArrayList<ApplicationUser>()
>         authors.add(assignee)
>         issue.setCustomFieldValue(cf, authors)
>         issueManager.updateIssue(sdUser, issue,
> EventDispatchOption.DO_NOT_DISPATCH, false)
>     }
> } else {
>     def authors = (List<ApplicationUser>)issue.getCustomFieldValue(cf)
>     if (authors != null) {
>         issue.setCustomFieldValue(cf, new ArrayList<ApplicationUser>())
>         issueManager.updateIssue(sdUser, issue,
> EventDispatchOption.DO_NOT_DISPATCH, false)
>     }
> }
>
>
> ===== SCRIPT RO COPY ASSIGNEE TO AUTHORS ====
>
> import com.atlassian.jira.component.ComponentAccessor
> import com.atlassian.jira.issue.search.SearchProvider
> import com.atlassian.jira.jql.parser.JqlQueryParser
> import com.atlassian.jira.web.bean.PagerFilter
> import com.atlassian.jira.event.type.EventDispatchOption
> import com.atlassian.jira.issue.MutableIssue
> import com.atlassian.jira.issue.index.IssueIndexingService
> import com.atlassian.jira.util.ImportUtils
> import com.atlassian.jira.user.ApplicationUser;
> import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
> import com.atlassian.jira.issue.util.IssueChangeHolder
>
> def issueManager = ComponentAccessor.getIssueManager()
> def customFieldManager = ComponentAccessor.getCustomFieldManager()
> def cf = customFieldManager.getCustomFieldObjectByName( "Authors" );
>
> def sdUser = ComponentAccessor.getUserManager().getUserByKey('robot')
> def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
> def searchProvider = ComponentAccessor.getComponent(SearchProvider)
> def query1 = jqlQueryParser.parseQuery("project = CASSANDRA")
> def results1 = searchProvider.search(query1, sdUser,
> PagerFilter.getUnlimitedFilter())
> log.warn("All issues=" + results1.total)
> results1.getIssues().each() {
>     documentIssue ->
>         def issue = issueManager.getIssueObject(documentIssue.id)
>         def assignee = issue.getAssignee()
>         if (assignee != null) {
>             def authors =
> (List<ApplicationUser>)issue.getCustomFieldValue(cf)
>             if (authors == null) {
>                 authors = new ArrayList<ApplicationUser>()
>             } else {
>                 authors = new ArrayList<ApplicationUser>(authors)
>             }
>             if (!authors.contains(assignee)) {
>                 authors.add(assignee)
>                 issue.setCustomFieldValue(cf, authors)
>                 issueManager.updateIssue(sdUser, issue,
> EventDispatchOption.DO_NOT_DISPATCH, false)
>                 log.warn(documentIssue.id)
>             }
>         }
> }
>
>
> ===== SCRIPT TO COPY PRIORITY TO SEVERITY ====
>
> import com.atlassian.jira.component.ComponentAccessor
> import com.atlassian.jira.issue.search.SearchProvider
> import com.atlassian.jira.jql.parser.JqlQueryParser
> import com.atlassian.jira.web.bean.PagerFilter
> import com.atlassian.jira.event.type.EventDispatchOption
> import com.atlassian.jira.issue.MutableIssue
> import com.atlassian.jira.issue.index.IssueIndexingService
> import com.atlassian.jira.util.ImportUtils
> import com.atlassian.jira.user.ApplicationUser;
> import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
> import com.atlassian.jira.issue.util.IssueChangeHolder
> import com.atlassian.jira.issue.priority.Priority
> import com.atlassian.jira.issue.context.IssueContext
> import com.atlassian.jira.issue.customfields.option.Option
> import com.atlassian.jira.issue.customfields.option.Options
> import com.atlassian.jira.issue.customfields.manager.OptionsManager
>
> def issueManager = ComponentAccessor.getIssueManager()
> def customFieldManager = ComponentAccessor.getCustomFieldManager()
> def cf = customFieldManager.getCustomFieldObject("customfield_12313820" );
>
> def constantsManager = ComponentAccessor.getConstantsManager()
> Priority pUrgent = constantsManager.getPriorities().find {it.name ==
> "Urgent"}
> Priority pHigh = constantsManager.getPriorities().find {it.name == "High"}
> Priority pNormal = constantsManager.getPriorities().find {it.name ==
> "Normal"}
> Priority pLow = constantsManager.getPriorities().find {it.name == "Low"}
>
> def optManager = ComponentAccessor.getOptionsManager();
> Options severities =
> optManager.getOptions(cf.getRelevantConfig(IssueContext.GLOBAL))
> Option sCritical = severities.getOptionForValue("Critical", null)
> Option sNormal = severities.getOptionForValue("Normal", null)
> Option sLow = severities.getOptionForValue("Low", null)
>
> def sdUser = ComponentAccessor.getUserManager().getUserByKey('robot')
> def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
> def searchProvider = ComponentAccessor.getComponent(SearchProvider)
> def query1 = jqlQueryParser.parseQuery("project = CASSANDRA and priority =
> High")
> def results1 = searchProvider.search(query1, sdUser,
> PagerFilter.getUnlimitedFilter())
> log.warn("All issues=" + results1.total)
> results1.getIssues().each() {
>     documentIssue ->
>         def issue = issueManager.getIssueObject(documentIssue.id)
>         def priority = issue.getPriority()
>         if (priority != null) {
>             def severity = issue.getCustomFieldValue(cf)
>             def newSeverity = severity;
>             if (priority == pUrgent) {
>                 newSeverity = sCritical
>             } else if (priority == pHigh) {
>                 newSeverity = sNormal
>             } else if (priority == pNormal) {
>                 newSeverity = sNormal
>             } else if (priority == pLow) {
>                 newSeverity = sLow
>             } else {
>                 log.warn(priority)
>             }
>             if (newSeverity != severity) {
>                 issue.setCustomFieldValue(cf, newSeverity)
>                 issueManager.updateIssue(sdUser, issue,
> EventDispatchOption.DO_NOT_DISPATCH, false)
>             }
>         }
> }
  • Jira Updates Benedict Elliott Smith
    • Re: Jira Updates Joshua McKenzie

Reply via email to