H Experts,
I'm looking for JQL that will bring back a list of Parent issue that have a status at a lower level than their children.
EG
Epic at Backlog that has stories in progress
Epic in progress with all children in done
We have ScriptRunner and Portfolio for JIra options
Hi @Rob Crick
here are a few ideas you could try using ScriptRunner.
Epic at Backlog that has stories in progress
The query implies "backlog" translates to a status of "Open" - you could adapt it according to your needs.
It will show you Epics which have at least an issue in it of status "In Progress".
type = Epic AND status = Open AND issueFunction in epicsOf("status = 'In Progress'")
Epic in progress with all children in done
status != Done and issueFunction in linkedIssuesOf("status = Done", "has epic") and not issueFunction in linkedIssuesOf("status != Done", "has epic")
This was taken from here (Filter: all Epics that are incomplete but only have Stories that are complete) and could probably give you an idea on what to build upon for further requirements.
Regards,
Daniel
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello there :)
First of all, this is NOT the answer you're looking for (sorry about that) but maybe it can point you in the right direction.
Some time ago I also needed a custom JQL. In my case it was something that returned any task or subtask matching a JQL expression, and also any subtask whose parent matched the expression (regardless if the subtask itself matches it or not). I'm not a programmer but I took several things from here and there and came up with this, maybe you can tweak it (as I tweaked many other code examples to get here). Best of luck.
import com.atlassian.jira.JiraDataType
import com.atlassian.jira.JiraDataTypes
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.search.SearchProvider
import com.atlassian.jira.issue.search.SearchQuery
import com.atlassian.jira.jql.operand.QueryLiteral
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.jql.query.IssueIdCollector
import com.atlassian.jira.jql.query.QueryCreationContext
import com.atlassian.jira.jql.validator.NumberOfArgumentsValidator
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.util.MessageSet
import com.atlassian.jira.util.MessageSetImpl
import com.atlassian.query.clause.TerminalClause
import com.atlassian.query.operand.FunctionOperand
import ru.mail.jira.plugins.groovy.api.jql.ScriptedJqlValuesFunction
class DemoFunction implements ScriptedJqlValuesFunction {
@Override
public JiraDataType getDataType() {
return JiraDataTypes.ISSUE;
}
@Override
public MessageSet validate(ApplicationUser searcher, FunctionOperand operand, TerminalClause terminalClause) {
def i18n = ComponentAccessor.getI18nHelperFactory().getInstance(searcher)
def numberValidMessage = new NumberOfArgumentsValidator(1i, i18n).validate(operand);
if (numberValidMessage.hasAnyErrors()) {
return numberValidMessage
}
def messageSet = new MessageSetImpl();
JqlQueryParser jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
try {
def query = jqlQueryParser.parseQuery(operand.getArgs().get(0))
} catch (any) {
messageSet.addErrorMessage("not valid jql:${operand.getArgs().get(0)}");
messageSet.addErrorMessage("${any}");
}
return messageSet
}
List<QueryLiteral> getValues(QueryCreationContext queryCreationContext, FunctionOperand functionOperand, TerminalClause terminalClause) {
final List<QueryLiteral> literals = new LinkedList<>();
String jql = functionOperand.getArgs().get(0)
getIssuesByJQL(jql, queryCreationContext.getApplicationUser()).each { issue ->
literals << new QueryLiteral(functionOperand, issue.key)
issue.getSubTaskObjects().each { subTask ->
literals << new QueryLiteral(functionOperand, subTask.key)
}
}
return literals
}
private Collection<MutableIssue> getIssuesByJQL(String jql, ApplicationUser user) {
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
def searchProvider = ComponentAccessor.getComponent(SearchProvider)
def query = jqlQueryParser.parseQuery(jql)
SearchQuery searchQuery = SearchQuery.create(query, user)
IssueIdCollector collector = new IssueIdCollector()
searchProvider.search(searchQuery, collector)
return collector.getIssueIds().collect { getIssue(it as Long) }
}
private MutableIssue getIssue(Long id) {
ComponentAccessor.issueManager.getIssueObject(id)
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
If this is using script runner's custom JQL functions, the link below might be of additionnal help :
Custom JQL Functions
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Atlassian Government Cloud has achieved FedRAMP Authorization at the Moderate level! Join our webinar to learn how you can accelerate mission success and move work forward faster in cloud, all while ensuring your critical data is secure.
Register NowOnline forums and learning are now in one easy-to-use experience.
By continuing, you accept the updated Community Terms of Use and acknowledge the Privacy Policy. Your public name, photo, and achievements may be publicly visible and available in search engines.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.