Scriptrunner - Cannot Release and Edit Version in the same Script

Benjamin Walker July 10, 2017

Hi all,

I'm having a strange issue when I try to release a Version and edit that Version's release date in the same script (see code below). If I try to do one or the other the change takes place just fine, but if I try to do both, only the second change works.

I've tried using VersionManager.update(version) to no avail, I've tried pausing for 10 seconds between function calls, and I've even tried running the two updates concurrently; no dice.

import com.atlassian.jira.component.ComponentAccessor
import java.text.SimpleDateFormat

def project = ComponentAccessor.getProjectManager().getProjectByCurrentKey("project")
def versionManager = ComponentAccessor.getVersionManager()

def version = versionManager.getVersion(project.getId(), "3.4")

Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2017-07-10")

//these are the updates in question
versionManager.releaseVersion(version, true) //this update will not persist
versionManager.editVersionReleaseDate(version, date) //this update will persist

Any advice would be great, thanks,

Ben

2 answers

1 accepted

2 votes
Answer accepted
adammarkham
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
July 11, 2017

Hi Ben,

Your best off using VersionService to do this. It will do the validation for you and tell you exactly why you can't release or update a version.

Your script should look like the following which will release version "3.4" and set the release date as 2017-07-10.

 

import com.atlassian.jira.bc.project.version.VersionService
import com.atlassian.jira.component.ComponentAccessor

import java.text.SimpleDateFormat

def versionService = ComponentAccessor.getComponent(VersionService)
def projectManager = ComponentAccessor.getProjectManager()

def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

def project = projectManager.getProjectByCurrentKey("project")
def version = versionService.getVersionByProjectAndName(user, project, "3.4")

def releaseDate = new SimpleDateFormat("yyyy-MM-dd").parse("2017-07-10")

def result = versionService.validateReleaseVersion(user, version, releaseDate)

if (result.isValid()) {
    versionService.releaseVersion(result)
} else {
    log.error "Could not relase version '${version.name}' due to the following errors: $result.errorCollection.errors"
}

Hope this helps.

Thanks,
Adam

 

Benjamin Walker July 11, 2017

Thanks Adam, that worked perfectly for me!

-Ben

Darryl Hahn April 22, 2020

Adam,

Atlassian Support directed me to this page to solve the intermittent problem I was having using the   line

versionManager.releaseVersion(version, false)    

To unrelease a Version, if after my scriptrunner script determines the Version is not yet ready for release.  If it discovers an error it posts a pop up message to user and sends them an email message about, then marks the Version as unreleased again.

Instead I used your recommended solution to run these lines instead

ver result = versionService.validateUnreleaseVersion(currentUser, version, currentReleaseDate) 
if (result.isValid()) {
versionService.unreleaseVersion(result)
}

This method has the same intermittent problems as the prior one.

It generally worked when "Releasing" from Releases tab, but not from the "Manage Versions" tab using the add-on Version Manager for Jira.

Here is my full scriptrunner script below, including my previous commented out code that used to run the previous method.  I have removed the section that would check for a failed release step, that would indicate I have to unrelease the Version and post a message to the user.

Any help you can provide would be appreciated.

Darryl

package con.scriptrunner.SampleUnrelease;

import com.jibrok.jira.plugins.simplenotification.api.*
import com.onresolve.scriptrunner.runner.customisers.PluginModule
import com.onresolve.scriptrunner.runner.customisers.WithPlugin
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.event.issue.IssueEventManager
import com.atlassian.jira.event.project.AbstractVersionEvent
import com.atlassian.jira.event.project.VersionReleaseEvent
import com.atlassian.jira.event.issue.link.IssueLinkCreatedEvent
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.link.IssueLink
import com.atlassian.jira.issue.link.IssueLinkManager
import com.atlassian.jira.bc.project.version.VersionService
import com.atlassian.jira.component.ComponentAccessor
import java.text.SimpleDateFormat

import groovy.json.JsonBuilder
import com.atlassian.mail.Email
import com.atlassian.mail.server.MailServerManager
import com.atlassian.mail.server.SMTPMailServer
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.ContentType.*
import groovyx.net.http.ContentType
import static groovyx.net.http.Method.*
import groovy.json.JsonSlurper
import net.sf.json.groovy.JsonSlurper
import groovy.sql.Sql
import com.microsoft.sqlserver.jdbc.SQLServerDriver;
import com.atlassian.jira.user.ApplicationUser
import com.onresolve.scriptrunner.db.DatabaseUtil
import org.apache.log4j.Logger
import org.apache.log4j.Level

class SampleUnrelease
{
//Class members
def currentVersion = event.version
def currentVersionName = event.version.name
def currentVersionId = event.version.id
def currentProject = event.version.project.name
def currentReleaseDate = event.version.releaseDate

def private Logger log = Logger.getLogger("com.scriptrunner.SampleUnrelease")
def private ApplicationUser currentUser

//Managers
def private CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager()
def private IssueManager issueManager = ComponentAccessor.getIssueManager()
def private IssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager()
def private IssueEventManager issueEventManager = ComponentAccessor.getIssueEventManager()
def private SMTPMailServer mailServer = ComponentAccessor.getMailServerManager().getDefaultSMTPMailServer()

//Fields we are interested in
def private CustomField capabilityField

def private String emailbody = "NOTICE: Attempt to Unrelease a Version."

//Notifier tool
@WithPlugin("com.jibrok.jira.plugins.simple-notifications-for-jira")
@PluginModule
NotificationQueue notificationQueue

//Constructors
def private SampleUnrelease(VersionReleaseEvent event)
{
//Setup logging
log.setLevel(Level.DEBUG)

//get Released Versions id and name
currentVersion = event.version
currentVersionName = event.version.name
currentVersionId = event.version.id
currentProject = event.version.project.name
currentReleaseDate = event.version.releaseDate

//Get current user
currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
log.info("currentUser: " + currentUser.username)
log.info("Current Version Release Event: " + currentVersionId + " " + currentVersionName + " released on " + currentReleaseDate + " on Project " + currentProject)
emailbody = emailbody.concat("\n on Release event of Jira Version: \n VersionID: " + currentVersionId + "\n VersionName: " + currentVersionName + "\n Released on " + currentReleaseDate + "\n on Project " + currentProject )

def emailAddr = currentUser.getEmailAddress()
def subject = "NOTICE: Attempt to Unrelease - $emailAddr"
emailbody = emailbody.concat("\n\nUnrelease status: \n" + "Current Version Release Event: " + currentVersionId + " " + currentVersionName + " released on " + currentReleaseDate + " on Project " + currentProject)

sendEmail(emailAddr, subject, emailbody)
log.info("Notice emailed to user $emailAddr")

//Force Unrelease of Releasing of the Jira Version
def vermgr = ComponentAccessor.versionManager
def version = event.version
def versionService = ComponentAccessor.getComponent(VersionService)
def projectManager = ComponentAccessor.getProjectManager()
log.info("Release info: " + version.released + " " + version.name);
//while (version.released) {
// log.info("Attempt to unrelease VersionName: " + currentVersionName + "\n on Project " + currentProject )
// vermgr.releaseVersion(event.version, false)
// version = vermgr.getVersion(version.id)
// log.info("Release info: " + version.released + " " + version.name);
// }
//def result = versionService.validateReleaseVersion(currentUser, version, currentReleaseDate)
def result = versionService.validateUnreleaseVersion(currentUser, version, currentReleaseDate)
log.info("result : " + result )
if (result.isValid()) {
versionService.unreleaseVersion(result)
log.info("Attempt to unrelease VersionName: " + currentVersionName + "\n on Project " + currentProject )
}
else {
log.info("Failed to unrelease VersionName: " + currentVersionName + "\n on Project " + currentProject )
log.error "Could not release version '${version.name}' due to the following errors: $result.errorCollection.errors"
}

def failureDetails = "Attempted to unrelease Version: " + currentVersionName
notificationQueue.add(currentUser, "NOTICE: ", failureDetails, NotificationType.error, NotificationClose.manual)
log.info("Attempt to show pop up message to current user")


log.info("Listener script ending")
}

//Sends email to passed in email address, generally for error reporting
def private void sendEmail(String emailAddr,String subject,String emailbody)
{
Email email = new Email(emailAddr)
email.setSubject(subject)
email.setBody(emailbody)

mailServer.send(email)
}


}

//Start of script
new SampleUnrelease(event);













JiBrok
Marketplace Partner
Marketplace Partners provide apps and integrations available on the Atlassian Marketplace that extend the power of Atlassian products.
April 24, 2020

Hello! I noticed that you are sending notifications using Simple notifications for Jira

Please check, perhaps for this page you need to enable the module which shows notifications on the admin pages - How enable notifications for all pages?

2 votes
Christina Jenks May 11, 2020

Thought I'd point out (in case those y'all don't want to use all the boilerplate in the VersionService) that you need to be chaining the updates. 

If you're doing something like this:

Version updateResult = versionManager.editVersionDetails(existingVersion, 
sourceVersion.getName(),
sourceVersion.getDescription());

versionManager.editVersionStartDate(existingVersion,
sourceVersion.getStartDate());

versionManager.editVersionReleaseDate(existingVersion,
sourceVersion.getReleaseDate());

versionManager.releaseVersion(existingVersion,
sourceVersion.isReleased());

versionManager.archiveVersion(existingVersion,
sourceVersion.isArchived());

Then it won't work because (I suspect) the Version object you're passing is being passed by value and not by reference. This is kinda hinted in the API by the fact that versionManager returns a Version object rather than void (like in Jira 6).

E.G., I suspect the API isn't mutating the Version directly but is instead building a new Version DTO from the one you provided (and merged with the release, name, etc. info) and then passing that directly to the DB. Like how Spring Boot Data Repositories work, I suspect (but don't quote me, I am not sure they use that or not ... but I doubt at least they're using a Active Record pattern for internal Jira objects, unlike for plugins)

So, what you need to ACTUALLY do is this:

Version updateResult = versionManager.editVersionDetails(existingVersion,      
sourceVersion.getName(),
sourceVersion.getDescription());

updateResult = versionManager.editVersionStartDate(updateResult,
sourceVersion.getStartDate());

updateResult = versionManager.editVersionReleaseDate(updateResult,
sourceVersion.getReleaseDate());

updateResult = versionManager.releaseVersion(updateResult,
sourceVersion.isReleased());

updateResult = versionManager.archiveVersion(updateResult,
sourceVersion.isArchived());

 This way you pass the updated result into each subsequent update.

Björn Gullander
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 11, 2022

Perfect, this helped me a lot!

Suggest an answer

Log in or Sign up to answer