Hello,
I have been programming for years but am new to Jira and ScriptRunner.
Sometimes we have to change a versions release date. When I update the fix version release date I want all the issues associated with that version to have updated due dates so that their due date is the new fix version release date.
I found the related article about this topic from 2017 but I don't think it is using script runner and the syntax did not line up with what I am seeing.
Related article: https://community.atlassian.com/t5/Jira-questions/Set-Issue-Due-Date-based-on-fixVersion-release-Date-with-Script/qaq-p/678889
Any help or pointers will be greatly appreciated.
Thanks,
Nathan
Here is my pseudo-code plan.
1. Use Script Listener to trigger when release date is updated.
2. Get version release date.
3. For each issue with a given fix version update issue due date in a similar way to how I did it below.
Is this a good plan?
What I'm trying to do..
Hi @Nathan Walker,
I would use JQLsearch in listener to fetch all issues affected by the event version/release
The listener should be mapped to "VersionUpdatedEvent"
And the below script will update all issues's Due Date with version's Release Date automatically
import com.atlassian.jira.event.project.VersionUpdatedEvent
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.issue.IssueService
import org.apache.log4j.Level
import org.apache.log4j.Logger
import com.atlassian.jira.event.type.EventDispatchOption
def appUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def searchService = ComponentAccessor.getComponent(SearchService.class)
def issueManager = ComponentAccessor.getIssueManager()
def log = Logger.getLogger("Jira Log")
log.setLevel(Level.DEBUG)
def name = event.getVersion().getName()
def date = event.getVersion().getReleaseDate()
def jqlSearch = "fixVersion = \"${name}\""
SearchService.ParseResult parseResult = searchService.parseQuery(appUser, jqlSearch)
if(parseResult.isValid())
{
def searchResult = searchService.search(appUser, parseResult.getQuery(), PagerFilter.getUnlimitedFilter())
def issues = searchResult.issues.collect {issueManager.getIssueObject(it.id)}
issues.each{ issue ->
issue.setDueDate(new java.sql.Timestamp(date.getTime()))
issueManager.updateIssue(appUser, issue, EventDispatchOption.ISSUE_UPDATED, false)
}
}else {
log.error("Invalid JQL: " + jqlSearch)
}
you can remove if there is any unwanted packages imported, I didn't check that
BR,
Leo
Thank you @Leo for the response!
I'm still learning some basics. I am looking through documentation trying to lean.
Am I even doing it in the right place? Can I run it in this window like this?
It is not finding the imports. I removed them and I still get a "unable to resolve class SearchService.ParseRusult error.
Thanks again.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
It's not accepting/importing "com.atlassian.jira.bc.issue.search.SearchService
And that's the reason you are getting this error. unfortunately I never worked on cloud version. but I don't think the packages are different from server to cloud
Maybe you can refer Adaptavist's cloud documentation
BR,
Leo
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thank you Leo.
It looks like the cloud version has less available functions at this time.
I'm still looking in to cloud documentation to see how I can update issue due dates when I update there version release date.
Here is another helpful link: The differences between ScriptRunner for Jira Server and Jira Cloud
Nathan
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@gary.lee There is probably a better way to do this but this is what I ended up doing.
// Nathan Walker 11/08/2019
// Update DueDate based on Version Releas Date.
// Before running Update the Version Date in Jira to what you want.
// Then replace this ---------v with the version you want to update.
def query = 'fixVersion = "Temp Test Version"'
//-Body----------------------------------------------
// Search for the issues with the given FixVersion
def searchReq = get("/rest/api/2/search")
.queryString("jql", query)
.queryString("fields", "Flagged")
.asObject(Map)
// Verify the search completed successfully
assert searchReq.status == 200
//get count of records
def issueCount = (searchReq.body.total).toInteger()
println issueCount
//only get the issues from the previous search results
def issues = searchReq.body.issues
// Use first issue to find the release versions release date.
def firstIssueKey = issues[0].key
String fixVReleasDate = get('/rest/api/2/issue/' + firstIssueKey).asObject(Map).body['fields']['fixVersions']['releaseDate']
fixVReleasDate = fixVReleasDate.replaceAll("\\[|\\]","")
println "Releas Date: " + fixVReleasDate
// for each issue, update the due date
def issueKey
for (i = 0; i < issueCount; i++){
println "in loop: " + i
println "issue Key: " + issues[i].key
issueKey = issues[i].key
def result = put("/rest/api/2/issue/${issueKey}")
.header('Content-Type', 'application/json')
.body([
fields: [
duedate: fixVReleasDate
]
])
.asString()
// Validate the issue updated correctly
if (result.status == 204) {
println "Success - The issue with the key of ${issueKey} has been updated to: ${fixVReleasDate}"
} else {
return "${result.status}: ${result.body}"
}
}
return "Success! " + issueCount + " issues updated with due date:" + fixVReleasDate
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Walker,
I'm new to JIRA scripting. I have a similar requirement too, but instead of declaring fix version static how can we use them dynamically?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Can you please modify above scripts to close issues (transition) when an Version Release Event is triggered using Scriptrunner for Jira custom listener for Jira server?
We are using 8.2.3 method has changed
def issues = searchResult.issues.collect {issueManager.getIssueObject(it.id)}
Thanks!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I'm just adding transition script here
def actionId = 41 //41 is my final state transition ID
issues.each { is ->
transitionValidationResult = issueService.validateTransition(currentUser, is.id, actionId,new IssueInputParametersImpl())
if (transitionValidationResult.isValid()) {
transitionResult = issueService.transition(currentUser, transitionValidationResult)
if (transitionResult.isValid())
{ log.warn("Transitioned issue $issue through action $actionId") }
else
{ log.warn("Transition result is not valid") }
}else{
log.warn("The transitionValidation is not valid")
}
}
I haven't tested out this script so may require some minor changes
BR,
Leo
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thank you, it worked!
With Jira 8.2.3, slight modifications:
import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.issue.IssueService
import org.apache.log4j.Level
import org.apache.log4j.Logger
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.search.SearchResults
import com.atlassian.jira.issue.IssueInputParametersImpl
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.workflow.JiraWorkflow
import com.atlassian.jira.workflow.WorkflowManager
import com.atlassian.jira.issue.MutableIssue;
def appUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def searchService = ComponentAccessor.getComponent(SearchService.class)
def issueManager = ComponentAccessor.getIssueManager()
def actionId = 151
IssueService issueService = ComponentAccessor.getIssueService()
def name = event.getVersion().getName()
def date = event.getVersion().getReleaseDate()
def jqlSearch = "fixVersion = \"${name}\""
List<Issue> issues = null
SearchService.ParseResult parseResult = searchService.parseQuery(appUser, jqlSearch)
if(parseResult.isValid())
{
def searchResult = searchService.search(appUser, parseResult.getQuery(), PagerFilter.getUnlimitedFilter())
//issues = searchResult.issues.collect {issueManager.getIssueObject(it.id)}
issues = searchResult.results
issues.each{ issue ->
def transitionValidationResult = issueService.validateTransition(appUser, issue.id, actionId, new IssueInputParametersImpl())
def transitionResult = issueService.transition(appUser, transitionValidationResult)
return transitionResult
}
}else {
log.error("Invalid JQL: " + jqlSearch)
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Atlassian Government Cloud has achieved FedRAMP Authorization at the Moderate level! Join our webinar to learn how you can accelerate mission success and move work forward faster in cloud, all while ensuring your critical data is secure.
Register NowOnline 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.