Hello community! Im Ignacio, Jira Admin
To 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.
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.