Seek assistance writing a Scriptrunner script that sets/clears the Resolution globally based on Status Category, without using Post Functions.
+ Also, have the ability to limit the script to certain projects initially for testing, before enabling globally.
++ We have the Automation plugin, which is a good candidate for simply executing the script on the Issue Transitioned event, and also allows for project-level implementation.
import com.atlassian.jira.util.ImportUtils
import com.atlassian.jira.issue.index.IssueIndexingService
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.component.ComponentAccessor
def is = ComponentAccessor.issueService
def iip =is.newIssueInputParameters()
iip.setSkipScreenCheck(true) //only need this if the resolution is not editable
//iip.resolutionId = null
iip.resolutionId = issue.status.statusCategory.primaryAlias == 'Done' ? '10000' : null
def result = is.validateUpdate(currentUser, issue.id, iip)
assert result.valid : result.errorCollection.errors
def updatedIssue = is.update(currentUser, result, EventDispatchOption.DO_NOT_DISPATCH, false).issue
//updatedIssue.resolutionDate = new Date().toTimestamp()
//issue.store()
//update the JIRA index so that jql for "resolved" work
//boolean wasIndexing = ImportUtils.isIndexIssues()
//ImportUtils.setIndexIssues(true)
//ComponentAccessor.getComponent(IssueIndexingService.class).reIndex(updatedIssue)
//ImportUtils.setIndexIssues(wasIndexing)
Rationale: Our small team manages multiple large Jira instances with thousands of projects, all managed by our Users/Project Admins (and not by the Jira Admins). The instances have been deliberately configured to give the Users and Project Admins as many project configuration options as possible without needing a Jira Admin. Overall, we have been very successful. Resolutions are one of our last pinch points.
Project Admins cannot manage their own Resolutions reliably without a Jira Admin needing to configure Transition Screens and Post Functions. We've worked on multiple potential solutions (user training to use Simplified Workflows, Project Automation), but still, Jira Admins are the bottleneck for Resolutions.
So we've decided that the Resolution should be set globally for all issues based on the Status Category. This way, Project Admins can passively self administer their Resolution by only using "Done" statuses when they want the Resolution to be set.
Any help configuring this functionality is greatly appreciated! If I need to go it alone, so be it. I'll post the code here for others to use.
I was able to put together an Automation Rule/Scriptrunner Script combo that will edit the Resolution & Resolved date based on the Status Category.
I leveraged more of the Rule Conditions to make the scripts as simple as possible, since I'm not Scriptrunner savvy and don't want to create something I can't fix. The scripts will probably evolve over time, but for now, it does what it needs to do.
Set Resolution Script:
import com.atlassian.jira.util.ImportUtils
import com.atlassian.jira.issue.index.IssueIndexingService
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.component.ComponentAccessor
import java.sql.Timestamp
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
def is = ComponentAccessor.issueService
def iip =is.newIssueInputParameters()
iip.setSkipScreenCheck(true) //only need this if the resolution is not editable
iip.resolutionId = issue.status.statusCategory.primaryAlias == 'Done' ? '10000' : null
def result = is.validateUpdate(currentUser, issue.id, iip)
assert result.valid : result.errorCollection.errors
def updatedIssue = is.update(currentUser, result, EventDispatchOption.DO_NOT_DISPATCH, false).issue
import java.sql.Timestamp
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
def issueMutable = issue as MutableIssue
def issueManager = ComponentAccessor.issueManager
def issueService = ComponentAccessor.issueService
def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
issueMutable.setResolutionDate(new Timestamp(System.currentTimeMillis()))
issueMutable.store()
Set Resolved date to Null Script
import java.sql.Timestamp
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
def issueMutable = issue as MutableIssue
def issueManager = ComponentAccessor.issueManager
def issueService = ComponentAccessor.issueService
def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
issueMutable.setResolutionDate(null)
issueMutable.store()
Script Runner is giving me a warning about the issueMutable.store() line:
Any suggestions?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Can you re-ask this question in the other thread (link below)?
I only posted the outcome here for some extra reach. It'll be the better place to document the follow-on questions.
Solved: Scriptrunner w/ Automation - Set Resolution (atlassian.com)
I have several new things to post, once you ask. :)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Three months later, and I can say that this has been wildly successful.
The auto-resolution script runs around 7000 times a day, happily setting/clearing the Resolution & Resolved date. I created a new field "Outcome", populated it with the same field options as Resolution, copied over the values globally, and placed it on the transition screens in place of Resolution.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I would advise against this. One major benefit of resolutions is it tells you why an issue is done and shows up in reporting. Where as if you try to differentiate issues based off their status this won't show up in reporting.
Having the Done status and then having only one resolution from a scalable agile standpoint will provide false data. The resolution provides the ability to also be done via screens and then allows user to select why it's done, like duplicate issues, things that won't be done etc.
By skipping this you are missing out on major features of jira and will really hinder users as the tool is scaled
From a UI standpoint yes it's easier but the data will not always be accurate and there is nothing worse than false data in a system.
Best,
Clark
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Completely understand this compromise. I'm a highly-experienced Jira Admin. Resolutions have many benefits for instances that have tighter control on workflow & project configurations. But that is not our delivery model. Our users get projects created automatically, and they get full permissions to edit workflows. So they very quickly (1) break the Simplified Workflow feature inside of Boards, and (2) break the workflow post-function & transition screen Resolution configs by removing/editing transitions. So having the Resolution set automatically & globally would be a desirable behavior.
Want to talk about False Data? I've pulled the data for Resolutions:
And this is with us spending several hours a week trying to configure projects with post-functions and transition screens. So we do have a False Data problem, mostly stemming from the Resolution not being set. Setting globally fixes tens of thousands of issues, while sacrificing granularity on a thousand (which we've implemented a workaround to capture anyway).
Want to talk about missing out on the features of Jira? Atlassian makes "Simplified Workflows" so users can automatically set the Resolution to Done. So Atlassian recognizes that setting all issues to Done gives a majority of the desired functionality.
Clearly in our instance, most of our users would prefer the automatic setting, and our Jira Admin team (2 people) will gain many hours per week back.
If you know a way to configure this, I'm all ears.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You are correct atlassian does have simplified workflows. However depending on the size of the instance it isn't always recommended to allow them in your instance.
Looking back on Jira history: https://community.atlassian.com/t5/Jira-questions/Resolution-automatically-set-to-Fixed-once-a-Custom-field-is/qaq-p/874085
May solve your issue.
But I would still weigh the risks. If your instance is a large instance I would suggest standardizing the workflows. i do see you are still on a server instance. in two years server is being deprecated.
Regardless if you go data center or cloud, there will be roadmap functionality you may not currently have. From experience, using the roadmap functionality is something many users will ask for, however it, on a company portfolio level it is near impossible to implement if there are not core sets of workflows/statuses etc, and potentially removing the simplified workflow options. My company is very large and we've been already working on this for 3 years, so if you are still in the planning stages for cloud or data center make sure to think about those other functionality you will be gaining from your migration as well. It's much easier to set yourself up starting now for success then needing to back track in a couple years.
Best,
Clark
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
It doesn't sound like you've got Scriptrunner chops that will further my mission. But what the hell, I'll debate anyway without an expectation of a Scriptrunner outcome.
Yes, I'm aware of ALL of that. Our delivery model is such that the instance is not tightly controlled, because there is tremendous value in allowing our end users to customize their projects to fit their needs. In a way, we made Server act like Data Center & Cloud. We're running Advanced Roadmaps, BigPicture, Project Automation, Context Manager, Group Ambassadors, Scriptrunner, Profoma, and a host of other plugins that extend the absolute max customization options to the end user. The only thing our admin team must do is create the project, which we want to do on behalf of the customer instead of giving them the ability.
Imagine visiting my Jira site.
Dozens of benefits and force multipliers are realized with this delivery method. Every user in the organization is empowered to manage any sized project, with no waiting, no asking permission, nothing stopping them.
We have two remaining opportunities to automate further:
If our admin team can automate the setting/clearing of Resolutions, it would solve one of the last manual tasks that we must do.
These Jira/Confluence environments are engineered to scale. If we have 50 users, or 50,000, our operation doesn't change (besides the license and server sizes).
I engineered and built all of this over the past 5 years. Atlassian asked me to do a presentation at their 2021 Gov Symposium. So when I say I'm a Jira Expert, please take me at my word.
Now, back to Resolving issues, which I'm already very close to a solution thanks to @PD Sheehan
Solved: Scriptrunner w/ Automation - Set Resolution (atlassian.com)
import com.atlassian.jira.util.ImportUtils
import com.atlassian.jira.issue.index.IssueIndexingService
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.component.ComponentAccessor
def is = ComponentAccessor.issueService
def iip =is.newIssueInputParameters()
iip.setSkipScreenCheck(true) //only need this if the resolution is not editable
//iip.resolutionId = null
iip.resolutionId = issue.status.statusCategory.primaryAlias == 'Done' ? '10000' : null
def result = is.validateUpdate(currentUser, issue.id, iip)
assert result.valid : result.errorCollection.errors
def updatedIssue = is.update(currentUser, result, EventDispatchOption.DO_NOT_DISPATCH, false).issue
//updatedIssue.resolutionDate = new Date().toTimestamp()
//issue.store()
//update the JIRA index so that jql for "resolved" work
//boolean wasIndexing = ImportUtils.isIndexIssues()
//ImportUtils.setIndexIssues(true)
//ComponentAccessor.getComponent(IssueIndexingService.class).reIndex(updatedIssue)
//ImportUtils.setIndexIssues(wasIndexing)
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.