Hello community! Im Ignacio, Jira AdminTo give the context a bit, it's the following:
In a project A *, we will store issues of the "Deployment" type, these issues will have a custom field where a version number related to a project B * will be entered at the time of finalizing the issue.
In project B we will find issues of the types:
Task x
Task y
Task z
Task i
Our client requires that, for example, when entering the version number related to project B in our project A, it validates that the issue types contained in the version of project B are "Task x, Task y and Task z ", then the system must allow ending the issue of project A. For example, if it were the case that the validation will find only issues of the type" Task z, Task i ", should not let the transition take place.
I couldn't find anything like it in the community forums, your help would be greatly appreciated.
We have Scriptrunner!
Actually I Have This
Hello Gustavo! Look at this is what I have at the moment. I'm getting the version id saved in the "" Project / Releases "field. As a test, the id is being saved as a comment within the problem, to validate that the postfunction is working correctly. What I am having trouble with is how to get? With that "version id" obtained, go to find the topics it contains and validate if there are the issuetype that I require in order to advance in the transition. Do you know if it is possible to pass a variable in a JQL or SQL query in jira? Thank you very much for your help!
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.util.UserUtil
import org.apache.log4j.Level
import org.apache.log4j.Logger
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.comments.CommentManager
def log = Logger.getLogger("com.acme.workflows")
log.setLevel(Level.DEBUG)
def customField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Proyecto/Releases")
Issue issueKey = issue
// Get the current logged in user
def CurrentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()displayName
// Get access to the Jira comment and component manager
CommentManager commentManager = ComponentAccessor.getCommentManager()
ComponentManager componentManager = ComponentManager.getInstance()
def issueManager = ComponentAccessor.issueManager
// Get the last comment entered in on the issue to a String
def value = (String) issue.getCustomFieldValue(customField)
def comment = value
if(value !=null)
{
commentManager.create(issueKey, CurrentUser,comment, true)
}
log.info("the version selected is" + value)
Hi @Ignacio Flores
If I understood you , doing a jql like "project = B and fixVersion = version1" , would give you all the issues that have that version.
So, inside your code(from A) , you could execute a jql that will return you those issues. You could iterate the results, and check if all your issue types are present.
e.g. as a pseudocode
def version = someCustomFieldValue
results = executeJql("project = B and fixVersion = version")
boolean isTaskXPresent= false
boolean isTaskYPresent= false
boolean finalizeIssue = false;
for(Issue issue : results){
if(issue.type=="Task X "){
isTaskXPresent= true
}
else
if(issue.type=="Task Y "){
isTaskYPresent= true
}
if(isTaskXPresent&&isTaskYPresent)
finalizeIssue = true
break;
}
if(finalizeIssue){
issue.setVersion(version)
}else{
error
}
}
I'm not sure if this is the best way to do it ,but it's an idea to work with.
Hope that helps you.
@Gustavo Félix
Disculpa gustavo, eres chileno ? de ser asi podriamos intercambiar algunas palabras ? +569 64940994
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Ignacio Flores No soy chileno, pero cualquier duda me la puedes dejar por aquĂ .
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hola Gustavo!
De momento esto es lo que tengo:
Mediante el codigo obtengo el id de la versiĂłn guardado en el campo "Proyecto/Release".
Para probar que la postfunction esta trabajando correctamente, estoy guardando el "ID de la versiĂłn" en un comentario al momento de ejecutar el script.
ÂżComo puedo realizar una busqueda de los issues con ell "id de version" encontrado y asĂ verificar que issue types se encuentran dentro? ÂżSera posible usar variables de codigo en un JQL o SQL query ?
Muchas gracias por tu ayuda!
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.util.UserUtil
import org.apache.log4j.Level
import org.apache.log4j.Logger
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.comments.CommentManager
def log = Logger.getLogger("com.acme.workflows")
log.setLevel(Level.DEBUG)
def customField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Proyecto/Releases")
Issue issueKey = issue
// Get the current logged in user
def CurrentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()displayName
// Get access to the Jira comment and component manager
CommentManager commentManager = ComponentAccessor.getCommentManager()
ComponentManager componentManager = ComponentManager.getInstance()
def issueManager = ComponentAccessor.issueManager
// Get the last comment entered in on the issue to a String
def value = (String) issue.getCustomFieldValue(customField)
def comment = value
if(value !=null)
{
commentManager.create(issueKey, CurrentUser,comment, true)
}
log.info("the Version selected is" + value)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hola Gustavo!
De momento esto es lo que tengo:
Mediante el codigo obtengo el id de la versiĂłn guardado en el campo "Proyecto/Release".
Para probar que la postfunction esta trabajando correctamente, estoy guardando el "ID de la versiĂłn" en un comentario al momento de ejecutar el script.
ÂżComo puedo realizar una busqueda de los issues con ell "id de version" encontrado y asĂ verificar que issue types se encuentran dentro? ÂżSera posible usar variables de codigo en un JQL o SQL query ?
Muchas gracias por tu ayuda!
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.util.UserUtil
import org.apache.log4j.Level
import org.apache.log4j.Logger
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.comments.CommentManager
def log = Logger.getLogger("com.acme.workflows")
log.setLevel(Level.DEBUG)
def customField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Proyecto/Releases")
Issue issueKey = issue
// Get the current logged in user
def CurrentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()displayName
// Get access to the Jira comment and component manager
CommentManager commentManager = ComponentAccessor.getCommentManager()
ComponentManager componentManager = ComponentManager.getInstance()
def issueManager = ComponentAccessor.issueManager
// Get the last comment entered in on the issue to a String
def value = (String) issue.getCustomFieldValue(customField)
def comment = value
if(value !=null)
{
commentManager.create(issueKey, CurrentUser,comment, true)
}
log.info("the version selected is" + value)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
De momento esto es lo que tengo:
Mediante el codigo obtengo el id de la versiĂłn guardado en el campo "Proyecto/Release".
Para probar que la postfunction esta trabajando correctamente, estoy guardando el "ID de la versiĂłn" en un comentario al momento de ejecutar el script.
ÂżComo puedo realizar una busqueda de los issues con ell "id de version" encontrado y asĂ verificar que issue types se encuentran dentro? ÂżSera posible usar variables de codigo en un JQL o SQL query ?
Muchas gracias por tu ayuda!
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.user.util.UserUtil
import org.apache.log4j.Level
import org.apache.log4j.Logger
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.ComponentManager
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.comments.CommentManager
def log = Logger.getLogger("com.acme.workflows")
log.setLevel(Level.DEBUG)
def customField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Proyecto/Releases")
Issue issueKey = issue
// Get the current logged in user
def CurrentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()displayName
// Get access to the Jira comment and component manager
CommentManager commentManager = ComponentAccessor.getCommentManager()
ComponentManager componentManager = ComponentManager.getInstance()
def issueManager = ComponentAccessor.issueManager
// Get the last comment entered in on the issue to a String
def value = (String) issue.getCustomFieldValue(customField)
def comment = value
if(value !=null)
{
commentManager.create(issueKey, CurrentUser,comment, true)
}
log.info("the version selected is" + value)
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.
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.bc.issue.search.SearchService
Con este cĂłdigo deberĂas poder ejecutar el queryJql que necesites. Esto te devolverá una lista de issues ("results") que vas a iterar con el "each"
Espero te funcione.
def queryJql = "project= TuProyecto and fixVersion=TuVersion"
SearchService searchService = ComponentAccessor.getComponent(SearchService.class)
SearchService.ParseResult parseResult = searchService.parseQuery(user,queryJql)
def searchResult = searchService.search(user,parseResult.getQuery(),PagerFilter.getUnlimitedFilter())
List<Issue> results = searchResult.getResults()
results.each{ tempIssue ->
def issueType = issue.getIssueType().getName()
//AquĂ agregas lo que necesites validar con los issueTypes
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Gustavo muchas gracias por tu ayuda funciono perfectamente!
Ahora tengo algunas preguntas ?
Desde la siguiente lĂnea de cĂłdigo que va a rescatar los tipos de issues dentro de una version seleccionada:
def issueType = issue.getIssueType().getName()
if (issue.getIssueType().getName().equals("Modelo de Datos") || issue.getIssueType().getName().equals("Hacking etico"))
{
return true
}
else
{
return false
}
Para esta casuĂstica, estamos utilizando una version que contiene dentro 5 issues (1 de hacking etico/ 1 de Modelo de Datos/ 1 Historia usuario/ 2 Calidad TĂ©cnica).
El script me esta retornando los valores: [false, true, true, false, false] Lo cual esta correcto segĂşn el cĂłdigo mencionado.
Mi pregunta es, ÂżCĂłmo puedo condicionar que cuando el cĂłdigo me devuelva esos dos valores "true" (Tienen que ser los 2 true, no basta uno solo) se guarde en un campo que se llamara AprobaciĂłn con el valor: Aprobado? y en caso de que solo encuentre un "True" o ninguno, me guarde el valor: Sin tareas QA.
Te dejo el cĂłdigo completo, muchas gracias por tu ayuda ha sido demasiado util!
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.jql.parser.JqlQueryParser;
import com.atlassian.jira.issue.search.SearchProvider;
import com.atlassian.jira.web.bean.PagerFilter;
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.fields.config.FieldConfig
import com.atlassian.jira.issue.context.IssueContextImpl
import com.atlassian.jira.issue.customfields.manager.OptionsManager
import com.atlassian.jira.issue.customfields.option.Options
import com.atlassian.jira.issue.customfields.option.Option
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import org.apache.log4j.Level
import com.atlassian.jira.issue.Issue
import org.apache.log4j.Logger
def log = Logger.getLogger("com.acme.workflows")
log.setLevel(Level.DEBUG)
def findIssues(String jqlQuery) {
def issueManager = ComponentAccessor.issueManager
def user = ComponentAccessor.jiraAuthenticationContext.getLoggedInUser()
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class)
def query = jqlQueryParser.parseQuery(jqlQuery)
def results = searchProvider.search(query, user, PagerFilter.unlimitedFilter)
results.issues.collect {
issue -> issueManager.getIssueObject(issue.id)
def issueType = issue.getIssueType().getName()
if (issue.getIssueType().getName().equals("Modelo de Datos") || issue.getIssueType().getName().equals("Hacking etico"))
{
return true
}
else
{
return false
}
}
}
//def user = ComponentAccessor.jiraAuthenticationContext.userCustomField
CustomField cf1 = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Proyecto/Releases")
def jqlQuery = "fixVersion =11827"
def issues = findIssues(jqlQuery)
log.info(issues)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
A ver, si te entendĂ ...
boolean findIssues(String jqlQuery) {
...
...
...
int trueCount = 0;
if (issue.getIssueType().getName().equals("Modelo de Datos") || issue.getIssueType().getName().equals("Hacking etico"))
{
trueCount++;
}
else{...}
...
if (trueCount >=2){
return true;
}else{
return false
}
y ya en tu cĂłdigo,
if (findIssues(jqlQuery)){
//AquĂ haces lo que quieras con tu customfield
}else{
//Haces otra cosa
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Entendiste a la perfecciĂłn! jajaja
Pero el Ăşnico problema, es que siempre me esta retornando true, independientemente si este if se cumple o no
if (issue.getIssueType().getName().equals("Modelo de Datos") || issue.getIssueType().getName().equals("Hacking etico"))
Probando para ver que valores esta guardando, cambie nuevamente el boolean findIssues(String jqlQuery) por def y note que el if si esta funcionando bien, pero al declarar findIssues(String jqlQuery) como boolean siempre me los esta setendo en True
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
PodrĂas poner el cĂłdigo completo ?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Te dejo el cĂłdigo completo!
Por lo que estuve investigando al declarar un resultado collection como boolean, siempre va a devolver true cuando encuentre algo, independientemente si se cumple la condiciĂłn dentro o no. ÂżA que me refiero con esto?, cuando ejecuto el cĂłdigo y este valida la versiĂłn indicada en el JQL, si encuentra issues siempre devuelve TRUE independientemente si el IF se cumple o no, si no encuentra issues solo en ese caso devuelve FALSE
Version id 11827 (Contiene tickets de Hacking Etico y Modelo de datos) = TRUE
Version id 11828 (Contiene uno de Hacking Etico pero ningun de Modelo de datos) =TRUE --> AquĂ deberĂa dar FALSE.
Version id 11829 (No contiene tickets) = FALSE
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.jql.parser.JqlQueryParser;
import com.atlassian.jira.issue.search.SearchProvider;
import com.atlassian.jira.web.bean.PagerFilter;
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.fields.config.FieldConfig
import com.atlassian.jira.issue.context.IssueContextImpl
import com.atlassian.jira.issue.customfields.manager.OptionsManager
import com.atlassian.jira.issue.customfields.option.Options
import com.atlassian.jira.issue.customfields.option.Option
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import org.apache.log4j.Level
import com.atlassian.jira.issue.Issue
import org.apache.log4j.Logger
def log = Logger.getLogger("com.acme.workflows")
log.setLevel(Level.DEBUG)
boolean findIssues(String jqlQuery) {
def issueManager = ComponentAccessor.issueManager
def user = ComponentAccessor.jiraAuthenticationContext.getLoggedInUser()
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class)
def query = jqlQueryParser.parseQuery(jqlQuery)
def results = searchProvider.search(query, user, PagerFilter.unlimitedFilter)
results.issues.collect {
issue -> issueManager.getIssueObject(issue.id)
def issueType = issue.getIssueType().getName()
int trueCount = 0;
if (issue.getIssueType().getName().equals("Modelo de Datos") || issue.getIssueType().getName().equals("Hacking etico"))
{
trueCount++;
return true
}
else
{
return false
}
if (trueCount ==true)
{
return true;
}
else
{
return false;
}
}
}
//def user = ComponentAccessor.jiraAuthenticationContext.userCustomField
//CustomField cf1 = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Proyecto/Releases")
//def jqlQuery = "fixVersion =11827"
def jqlQuery = "fixVersion =11828"
boolean issues = findIssues(jqlQuery)
log.warn(issues)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Es que en esta parte
if (issue.getIssueType().getName().equals("Modelo de Datos") || issue.getIssueType().getName().equals("Hacking etico"))
{
trueCount++;
return true
}
else
{
return false
}
solo va a entrar una vez al primer if y va a regresar true, o sea, en esa parte no deberĂas poner return, porque se saldrá del mĂ©todo.
Solo quita los primeros returns y creo que deberĂa funcionar.
if (issue.getIssueType().getName().equals("Modelo de Datos") || issue.getIssueType().getName().equals("Hacking etico"))
{
trueCount++;
}
else
{
AquĂ tampoco irĂa return false, porque necesitas terminar de iterar primero todos los issues. AsĂ que si no necesitas agregar algo aquĂ, podrĂas quitar el else.
}
Espero te funcione.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hola Gustavo!
Probe quitando los return pero de igual manera, siempre me devuelve true si es que encuentra issues, independientemente del if, solo devuelve false si no encuentra nada.
Se te ocurre que puede ser ? ya me va a explotar la cabeza jajaja
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.jql.parser.JqlQueryParser;
import com.atlassian.jira.issue.search.SearchProvider;
import com.atlassian.jira.web.bean.PagerFilter;
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.fields.config.FieldConfig
import com.atlassian.jira.issue.context.IssueContextImpl
import com.atlassian.jira.issue.customfields.manager.OptionsManager
import com.atlassian.jira.issue.customfields.option.Options
import com.atlassian.jira.issue.customfields.option.Option
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import org.apache.log4j.Level
import com.atlassian.jira.issue.Issue
import org.apache.log4j.Logger
def log = Logger.getLogger("com.acme.workflows")
log.setLevel(Level.DEBUG)
boolean findIssues(String jqlQuery) {
def issueManager = ComponentAccessor.issueManager
def user = ComponentAccessor.jiraAuthenticationContext.getLoggedInUser()
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class)
def query = jqlQueryParser.parseQuery(jqlQuery)
def results = searchProvider.search(query, user, PagerFilter.unlimitedFilter)
results.issues.collect {
issue -> issueManager.getIssueObject(issue.id)
def issueType = issue.getIssueType().getName()
int trueCount = 0;
if (issue.getIssueType().getName().equals("Modelo de Datos") || issue.getIssueType().getName().equals("Hacking etico"))
{
trueCount++;
log.warn(trueCount)
}
}
}
//def user = ComponentAccessor.jiraAuthenticationContext.userCustomField
//CustomField cf1 = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Proyecto/Releases")
//def jqlQuery = "fixVersion =11827"
def jqlQuery = "fixVersion =11827"
def issues = findIssues(jqlQuery)
log.warn(issues)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Es que removiste cĂłdigo de más , asĂ deberĂa quedar:
results.issues.collect {
issue -> issueManager.getIssueObject(issue.id)
def issueType = issue.getIssueType().getName()
int trueCount = 0;
if (issue.getIssueType().getName().equals("Modelo de Datos") || issue.getIssueType().getName().equals("Hacking etico"))
{
trueCount++;
log.warn(trueCount)
}
}
if (trueCount >=2){ //Con esta parte validas si trueCount es >=2 , si encontró más de //dos issues de esos dos tipos. Si sà , regresa true, si no, false
return true;
}else{
return false
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Lo probé, pero sigue retornando true, te dejo imagen del resultado.
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.jql.parser.JqlQueryParser;
import com.atlassian.jira.issue.search.SearchProvider;
import com.atlassian.jira.web.bean.PagerFilter;
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.fields.config.FieldConfig
import com.atlassian.jira.issue.context.IssueContextImpl
import com.atlassian.jira.issue.customfields.manager.OptionsManager
import com.atlassian.jira.issue.customfields.option.Options
import com.atlassian.jira.issue.customfields.option.Option
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import org.apache.log4j.Level
import com.atlassian.jira.issue.Issue
import org.apache.log4j.Logger
def log = Logger.getLogger("com.acme.workflows")
log.setLevel(Level.DEBUG)
boolean findIssues(String jqlQuery) {
def issueManager = ComponentAccessor.issueManager
def user = ComponentAccessor.jiraAuthenticationContext.getLoggedInUser()
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class)
def query = jqlQueryParser.parseQuery(jqlQuery)
def results = searchProvider.search(query, user, PagerFilter.unlimitedFilter)
results.issues.collect {
issue -> issueManager.getIssueObject(issue.id)
def issueType = issue.getIssueType().getName()
int trueCount = 0;
if (issue.getIssueType().getName().equals("Modelo de Datos") || issue.getIssueType().getName().equals("Hacking etico"))
{
trueCount++;
log.warn(trueCount)
}
if (trueCount >=2)
{
log.warn(trueCount)
return true;
}
else
{
log.warn(trueCount)
return false
}
}
}def jqlQuery = "fixVersion =11828"
def issues = findIssues(jqlQuery)
log.warn(issues)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Bueno, es que el trueCount debe estar fuera de tu cuando estés iterando tu listado de issues. Igual , se estaba inicializando en 0 trueCount por cada vez que iterabas , entonces siempre iniciaba en 0 y no se acumulaba la cuenta.
Intenta de esta forma, igual agregué unos warns para ver qué va imprimiendo.
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.jql.parser.JqlQueryParser;
import com.atlassian.jira.issue.search.SearchProvider;
import com.atlassian.jira.web.bean.PagerFilter;
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.fields.config.FieldConfig
import com.atlassian.jira.issue.context.IssueContextImpl
import com.atlassian.jira.issue.customfields.manager.OptionsManager
import com.atlassian.jira.issue.customfields.option.Options
import com.atlassian.jira.issue.customfields.option.Option
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import org.apache.log4j.Level
import com.atlassian.jira.issue.Issue
import org.apache.log4j.Logger
def log = Logger.getLogger("com.acme.workflows")
log.setLevel(Level.DEBUG)
boolean findIssues(String jqlQuery) {
def issueManager = ComponentAccessor.issueManager
def user = ComponentAccessor.jiraAuthenticationContext.getLoggedInUser()
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class)
def query = jqlQueryParser.parseQuery(jqlQuery)
def results = searchProvider.search(query, user, PagerFilter.unlimitedFilter)
int trueCount = 0;
results.issues.collect {
issue -> issueManager.getIssueObject(issue.id)
def issueType = issue.getIssueType().getName()
log.warn(issueType)
if (issue.getIssueType().getName().equals("Modelo de Datos") || issue.getIssueType().getName().equals("Hacking etico"))
{
trueCount++;
}
}
log.warn(trueCount)
if (trueCount >=2)
{
return true;
}
else
{
return false
}
}
def jqlQuery = "fixVersion =11828"
def issues = findIssues(jqlQuery)
log.warn(issues)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Efectivamente ahora funciono a la perfecciĂłn! muchas muchas gracias por tu ayuda Gustavo.
Ahora debo seguir avanzando con algunas validaciones dentro del mismo codigo. ÂżSi surgen dudas te puedo seguir molestando?
Muchas gracias!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Claro, qué bueno que funcionó
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hola gustavo!
Estoy tratando de actualizar un campo personalizado en la misma postfunction, pero no esta haciendo nada. Como dato, lo ejecuta correctamente cuando estoy en la Script console, pero al ejecutar en una transiciĂłn con post function no esta actualizando el campo, este es el codigo que añadĂ:
pd: Como se ve en el log se esta ejecutando el cĂłdigo, pero no esta actualizando el campo, me falta algo ? un commit o algo asĂ ?
if(issues==true)
{
log.warn(issues)
def issueManager = ComponentAccessor.getIssueManager()
def issue = issueManager.getIssueObject(issue.id)
def String myval = "Aprobado"
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def textCf2 = customFieldManager.getCustomFieldObjects(issue).find {it.name == "AprobaciĂłn Release"}
if (textCf2) {
def changeHolder = new DefaultIssueChangeHolder()
textCf2.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(textCf2), myval),changeHolder)
log.warn(textCf2)
}
}
else
{
log.warn(issues)
def issueManager = ComponentAccessor.getIssueManager()
def issue = issueManager.getIssueObject(issue.id)
def String myval = "Faltan tareas para desplegar"
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def textCf2 = customFieldManager.getCustomFieldObjects(issue).find {it.name == "AprobaciĂłn Release"}
if (textCf2) {
def changeHolder = new DefaultIssueChangeHolder()
textCf2.updateValue(null, issue, new ModifiedValue(issue.getCustomFieldValue(textCf2), myval),changeHolder)
log.warn(textCf2)
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Bueno, algunas sospechas
1) Creo que issue deberĂa ser MutableIssue
MutableIssue issue = issueManager.getIssueObject(issue.id) as MutableIssue
2)En qué orden estás colocando la postfunction ?
Cuando agregas una postfunction, aparece
1.- Creates the issue originally
2.- Re index an issue to keep indexes...
3.- Fire a Issue Created
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Efectivamente como mencionabas, cambie a Mutable issue y funciono.
Ahora tengo una pregunta:
Esta postfuncion esta en una transiciĂłn obviamente. Âżcomo se podrĂa hacer, que al validar el "true" de mi codigo, se ejecute la transiciĂłn pero si es false, no se ejecute la transicion y me arroje algĂşn mensaje de alerta?
Muchas gracias!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Bueno, ahĂ creo que no es la mejor idea hacer eso.
Me parece que debes de meter un validator, que se ejecuta antes de la postfunction. Asà te aseguras que cuando llegue a la postfunction sà continuará. Eso , o creo que hay algunas "condition" , pero nunca he trabajado con ellas
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hola gustavo como estas?
queria perdirte ayuda con lo siguiente:
Necesito algĂşn consejo u ayuda con este problema que tengo.
Creamos un script que básicamente lo que hace es caputrarel id de un reléase asignado en un campo personalizado llamado “Celula/Release” mediante un JQL Query en el script:
def jqlQuery = "fixVersion in (${issue.getCustomFieldValue(cf1)})" ---⇒ el valor se guarda como “id” y no con el nombre del reléase.
Luego el script recorre los issues dentro del reléase, y valida algunas condiciones para poder avanzar en la transición.
El código funcionaba bien hasta que nos solicitaron cambiar el tipo de campo del campo “Celula/Release”, al tipo “Multi selección”.
Al probar que valores me está retornando el campo al seleccionar más de un relĂ©ase, retorna los id separados por “,” lo cual está bien, ya que el JQL deberĂa quedar algo asĂ:
def jqlQuery = "fixVersion in (13005,13006)" , ejecutando desde el script console el jql se ejecuta correctamente ya que ingresamos los valores directamente. Pero al llevar el cĂłdigo a la validaciĂłn de mi workflow, al ejecutar me aparece el siguiente error:
2020-12-14 11:04:25,887 ERROR [workflow.ScriptWorkflowFunction]: *************************************************************************************
2020-12-14 11:04:25,887 ERROR [workflow.ScriptWorkflowFunction]: Script function failed on issue: IMP-74, actionId: 11, file: <inline script>
com.atlassian.jira.jql.parser.JqlParseException: com.atlassian.jira.jql.parser.antlr.RuntimeRecognitionException: NoViableAltException(32@[])
at com.atlassian.jira.jql.parser.DefaultJqlQueryParser.parseClause(DefaultJqlQueryParser.java:110)
at com.atlassian.jira.jql.parser.DefaultJqlQueryParser.parseQuery(DefaultJqlQueryParser.java:33)
at com.atlassian.jira.jql.parser.JqlQueryParser$parseQuery.call(Unknown Source)
at Script236.findIssues(Script236.groovy:33)
at Script236.run(Script236.groovy:121)
Caused by: com.atlassian.jira.jql.parser.antlr.RuntimeRecognitionException: NoViableAltException(32@[])
Por favor su ayuda, les comparto el cĂłdigo completo.
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.jql.parser.JqlQueryParser;
import com.atlassian.jira.issue.search.SearchProvider;
import com.atlassian.jira.web.bean.PagerFilter;
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.fields.config.FieldConfig
import com.atlassian.jira.issue.context.IssueContextImpl
import com.atlassian.jira.issue.customfields.manager.OptionsManager
import com.atlassian.jira.issue.customfields.option.Options
import com.atlassian.jira.issue.customfields.option.Option
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import org.apache.log4j.Level
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.MutableIssue
import org.apache.log4j.Logger
import com.atlassian.jira.issue.customfields.option.LazyLoadedOption;
import com.atlassian.jira.issue.IssueManager
import com.opensymphony.workflow.InvalidInputException
import com.onresolve.scriptrunner.runner.util.UserMessageUtil
def log = Logger.getLogger("com.acme.workflows")
log.setLevel(Level.DEBUG)
def issue = issue as MutableIssue
Long issueId = issue.getId()
boolean findIssues(String jqlQuery) {
def issueManager = ComponentAccessor.issueManager
def user = ComponentAccessor.jiraAuthenticationContext.getLoggedInUser()
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class)
def query = jqlQueryParser.parseQuery(jqlQuery)
def results = searchProvider.search(query, user, PagerFilter.unlimitedFilter)
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def cf2 = customFieldManager.getCustomFieldObjects(issue).find {it.name == "Revisión Seguridad (QA Técnico)"}
def cf2val = issue.getCustomFieldValue(cf2)
def cf3 = customFieldManager.getCustomFieldObjects(issue).find {it.name == "RevisiĂłn Rendimiento"}
def cf3val = issue.getCustomFieldValue(cf3)
int trueCount = 0;
int trueCount2 =0;
if (cf2val==null || (((LazyLoadedOption)cf2val).getValue()=="Rechazado"))
{
trueCount2++
invalidInputException = new InvalidInputException(trueCount)
invalidInputException = new InvalidInputException("Revision de Seguridad 'Rechazado' o pendiente de completar, favor comunicarse con el equipo de seguridad para resolver esta revisiĂłn")
}
else if ((cf3val==null || (((LazyLoadedOption)cf3val).getValue()=="No")))
{
trueCount2++
invalidInputException = new InvalidInputException("Revision de rendimiento 'Rechazado' o 'No' o pendiente de completar, favor comunicarse con el equipo de rendimiento para resolver esta revisiĂłn")
}
else if((((LazyLoadedOption)cf2val).getValue()=="Aprobado") || (((LazyLoadedOption)cf2val).getValue()=="No Aplica") || (((LazyLoadedOption)cf2val).getValue()=="Autorizado") && (((LazyLoadedOption)cf3val).getValue()=="Si") )
{
trueCount++;
}
results.issues.collect {
issue -> issueManager.getIssueObject(issue.id)
def issueType = issue.getIssueType().getName()
def cf4 = customFieldManager.getCustomFieldObjects(issue).find {it.name == "Tipo Test Plan"}
def cf4val = issue.getCustomFieldValue(cf4)
if ((issue.getIssueType().getName().equals("Test Plan")) && (((LazyLoadedOption)cf4val).getValue()=="Release"))
{
trueCount++;
}
else if ((issue.getIssueType().getName().equals("Test Plan")==false) || (((LazyLoadedOption)cf4val).getValue()=="Historia Usuario"))
{
trueCount2++
invalidInputException = new InvalidInputException("No existe un test plan asociado en el Release o el mismo no esta asignado como Release")
invalidInputException = new InvalidInputException(trueCount)
}
}
log.warn(trueCount)
if (trueCount >=2)
{
return true;
}
else if(trueCount2 >=1)
{
return false;
}
}
CustomField cf1 = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Celula/Release")
def cf1val = issue.getCustomFieldValue(cf1)
log.warn(cf1val)
if (cf1val!=null)
{
def jqlQuery = "fixVersion in (${issue.getCustomFieldValue(cf1)})"
boolean issues = findIssues(jqlQuery)
}
else
{
invalidInputException = new InvalidInputException("Debe completar el campo 'Proyecto/Releases' para poder avanzar")
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
QuĂ© tal, pues truena en estas dos lĂneas
at Script236.findIssues(Script236.groovy:33)
at Script236.run(Script236.groovy:121)
la 121 me queda claro que es boolean issues = findIssues(jqlQuery)
pero la 33 , cuál serĂa? Es que por los saltos de lĂnea, me da una lĂnea del import, pero no creo que sea esa. En tu cĂłdigo, cuál lĂnea es la 33(en jira)? Ya con eso se puede saber dĂłnde truena y ver quĂ© podrĂa ser.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hola Gustavo! muchas gracias por responder!
la linea 33 es la siguiente: def query = jqlQueryParser.parseQuery(jqlQuery)
lo que se me occure que puede ser es que no este tomando bien el formato de entrada en la variable que se asigna en el JQL: def jqlQuery = "fixVersion in (${issue.getCustomFieldValue(cf1)})"
Ya que ahora el cf1 devuelve mas de un valor, por ejemplo: 10003, 10001, 10004
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Pues podrĂas intentar en
String cf1val = issue.getCustomFieldValue(cf1) as String
log.warn(cf1val)
if (cf1val!=null)
{
def jqlQuery = "fixVersion in (" + cf1val + ")"
asegurarte que sea String, quizá eso esté afectando
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Gustavo, lo resolvĂ de la siguiente forma:
def cf1val = issue.getCustomFieldValue(cf1) as List
cf1val.each{
if (cf1val!=null)
{
log.debug"id: $it"
def jqlQuery = "issuetype = 'Test Plan' and fixVersion = $it"
Ahora, tengo otra duda, como podria mostrar todos los mensajes de error de una vez y no uno por uno ?
Me explico, en la validacion se revisan 3 puntos: Revision QA/Revision Seguridad/Revision Release
Para cada uno de estos errores se ejecuta una excepciĂłn cuando se da el caso arrojando el mensaje de error.
te dejo el cĂłdigo completo:
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.jql.parser.JqlQueryParser;
import com.atlassian.jira.issue.search.SearchProvider;
import com.atlassian.jira.web.bean.PagerFilter;
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.fields.config.FieldConfig
import com.atlassian.jira.issue.context.IssueContextImpl
import com.atlassian.jira.issue.customfields.manager.OptionsManager
import com.atlassian.jira.issue.customfields.option.Options
import com.atlassian.jira.issue.customfields.option.Option
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
import org.apache.log4j.Level
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.MutableIssue
import org.apache.log4j.Logger
import com.atlassian.jira.issue.customfields.option.LazyLoadedOption;
import com.atlassian.jira.issue.IssueManager
import com.opensymphony.workflow.InvalidInputException
import com.onresolve.scriptrunner.runner.util.UserMessageUtil
def log = Logger.getLogger("com.acme.workflows")
log.setLevel(Level.DEBUG)
def issue = issue as MutableIssue
Long issueId = issue.getId()
boolean findIssues(String jqlQuery) {
def issueManager = ComponentAccessor.issueManager
def user = ComponentAccessor.jiraAuthenticationContext.getLoggedInUser()
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class)
def query = jqlQueryParser.parseQuery(jqlQuery)
def results = searchProvider.search(query, user, PagerFilter.unlimitedFilter)
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def cf2 = customFieldManager.getCustomFieldObjects(issue).find {it.name == "Revisión Seguridad (QA Técnico)"}
def cf2val = issue.getCustomFieldValue(cf2)
def cf3 = customFieldManager.getCustomFieldObjects(issue).find {it.name == "RevisiĂłn Rendimiento"}
def cf3val = issue.getCustomFieldValue(cf3)
int trueCount = 0;
int trueCount2 =0;
if (cf2val==null || (((LazyLoadedOption)cf2val).getValue()=="Rechazado"))
{
trueCount2++
invalidInputException = new InvalidInputException(trueCount)
invalidInputException = new InvalidInputException("Revision de Seguridad 'Rechazado' o pendiente de completar, favor comunicarse con el equipo de seguridad para resolver esta revisiĂłn")
}
else if ((cf3val==null || (((LazyLoadedOption)cf3val).getValue()=="No")))
{
trueCount2++
invalidInputException = new InvalidInputException("Revision de rendimiento 'Rechazado' o 'No' o pendiente de completar, favor comunicarse con el equipo de rendimiento para resolver esta revisiĂłn")
}
else if((((LazyLoadedOption)cf2val).getValue()=="Aprobado") || (((LazyLoadedOption)cf2val).getValue()=="No Aplica") || (((LazyLoadedOption)cf2val).getValue()=="Autorizado") && (((LazyLoadedOption)cf3val).getValue()=="Si") )
{
trueCount++;
}
results.issues.collect {
issue -> issueManager.getIssueObject(issue.id)
def issueType = issue.getIssueType().getName()
def cf4 = customFieldManager.getCustomFieldObjects(issue).find {it.name == "Tipo Test Plan"}
def cf4val = issue.getCustomFieldValue(cf4)
log.warn("el valor del campo Tipo Test Plan es:"+cf4val)
log.warn(issueType)
if (((LazyLoadedOption)cf4val).getValue()=="Release")
{
trueCount++;
log.warn("trueCount-primero:"+trueCount)
}
else if (((LazyLoadedOption)cf4val).getValue()=="Historia Usuario")
{
trueCount2++
invalidInputException = new InvalidInputException("No existe un test plan asociado en el Release o el mismo no esta asignado como Release")
log.warn("trueCount2-primero:"+trueCount2)
}
}
log.warn(trueCount)
if (trueCount >=2)
{
return true;
}
else if(trueCount2 >=1)
{
return false;
}
}
CustomField cf1 = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName("Celula/Release")
def cf1val = issue.getCustomFieldValue(cf1) as List
log.warn("el valor de Celula/Release es:"+cf1val)
cf1val.each{
if (cf1val!=null)
{
log.debug"id: $it"
def jqlQuery = "issuetype = 'Test Plan' and fixVersion = $it"
boolean issues = findIssues(jqlQuery)
log.debug(jqlQuery)
log.warn(cf1val)
}
else
{
invalidInputException = new InvalidInputException("Debe completar el campo 'Proyecto/Releases' para poder avanzar")
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Si te entendĂ bien, el problema es que tienes mĂşltiples invalidInputException, correcto ?
Si sĂ, pues podrĂas en vez de definir un invalidInputException cada que haya un error, ir concatenando un string de errores, o una lista de string por cada error.
Y ya al final ves si ese string no está vacĂo o esa lista no está vacĂa ( cero errores) , y ahĂ creas el invalid InputException.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hola Gustavo!
Me perdĂ un poco con lo que me comentas ... Me podrĂas dar un ejemplo básico ?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
String errores = "" //Esto lo defines al inicio de todo
y en vez de hacer invalidInputException("texto") en tus ifs, vas haciendo
errores = errores.concat("Revision de Seguridad ...")
y en el siguiente if , haces lo mismo
errores = errores.concat("Revision de rendimiento...")
Y ya al final,
if(errores == "") {
//No hubo errores
}else{
invalidInputException = new InvalidInputException(errores)
}
Y asĂ solo imprimirĂas un solo invalidInputException
Ahora, no sé si este era tu problema o lo entendà mal .
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.