Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

All tickets with fixVersion in a certain ticket's fixVersions

Exty Ypsilonty
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
November 9, 2023

Hello all,

I need inspiration. I'm looking for a JQL query (including ScriptRunner). We're currently developing several components which each have their own versioning. So each ticket that modifies a component gets a fixVersion like "compA_1.0". If two components are touched, it's "compA_1.0, compB_2.4". So far, so good.

Now we also have "Delivery"-type tickets which contain all fixVersions of all items belonging to a rollout as their own fixVersion: ""compA_1.0, compB_2.4, compC_3.0".

Now I know how to query for all tickets belonging to a certain fixVersion, but I don't want to handle that list of releases each time I run the query. Is there any way to get

"all the tickets which have a fixVersion that is in the fixVersions of the Delivery ticket with id=ABC"?

Thanks in advance

2 answers

1 accepted

0 votes
Answer accepted
PD Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 9, 2023

No, there are no JQL that can do this out of the box (including with scriptrunner).

If somehow there was an actual link between the delivery ticket and the fix tickets, then you could use that.

The JQL you are looking for would require a custom JQL function.

Here is a custom JQL function script that you can start with.

 

package com.onresolve.jira.groovy.jql

import com.atlassian.jira.JiraDataType
import com.atlassian.jira.JiraDataTypes
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.jql.operand.QueryLiteral
import com.atlassian.jira.jql.query.QueryCreationContext
import com.atlassian.jira.jql.validator.NumberOfArgumentsValidator
import com.atlassian.jira.project.version.Version
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.util.MessageSet
import com.atlassian.query.clause.TerminalClause
import com.atlassian.query.operand.FunctionOperand
import com.onresolve.jira.groovy.jql.entities.AbstractEntityFunction

class VersionsFromIssueFunction extends AbstractEntityFunction implements JqlValuesFunction {

@Override
List<String> getUnsupportedPredicates() {
return []
}

@Override
String getUsageMessage() {
return ""
}

@Override
String getAuthorFieldName() {
return null
}

@Override
String getCreatedFieldName() {
return null
}

@Override
protected String getCategory() {
return null
}

@Override
String getDescription() {
return "Find issues with version field matching one of the versions listed on the same field in another ticket"
}

@Override
String getFunctionName() {
return "versionsInIssue"
}

@Override
JiraDataType getDataType() {
JiraDataTypes.VERSION
}

@Override
MessageSet validate(ApplicationUser user, FunctionOperand operand, TerminalClause terminalClause) {
def messages = new NumberOfArgumentsValidator(1, 2, getI18n()).validate(operand)
def issueKey = operand.args[0].toUpperCase()
def issue = ComponentAccessor.issueManager.getIssueObject(issueKey)
if (!issue) {
messages.addMessage(MessageSet.Level.ERROR, "Issue '$issueKey' not found or not accessible by the current user")
}
def versionFieldMap = getVersionField(operand, terminalClause)
if (versionFieldMap.type == 'cf') {
def cf = versionFieldMap.cf as CustomField
if (!cf) {
messages.addMessage(MessageSet.Level.ERROR, "No custom field found matching '$versionFieldMap.name'. Use fixVersion, affectedVersion or a valid Version picker custom field")
} else {
def validCfKeys = ['customfieldtypes:version', 'customfieldtypes:multiversion']
if (!validCfKeys.any { cf.customFieldType.key.endsWith(it) }) {
messages.addMessage(MessageSet.Level.ERROR, "'$cf.name' is not a valid Version picker custom field.")
}
}
}
messages
}

@Override
List<Map> getArguments() {
[
[description: 'Issue key to lookup versions from.', optional: false],
[description: 'Version field to lookup version from. Uses the same field if not specified', optional: true]
]
}

Map getVersionField(FunctionOperand operand, TerminalClause terminalClause) {
def versionFieldMap = [name: terminalClause.name, type: 'cf']
if (operand.args.size() > 1) {
log.info "Second argument detected. Using ${ operand.args[1]} as the Version field to lookup"
versionFieldMap.name = operand.args[1]
}
if (versionFieldMap.name.toLowerCase() == 'fixversion') {
versionFieldMap.name = 'fixVersions'
versionFieldMap.type = 'system'
} else if (versionFieldMap.name.toLowerCase() == 'affectedversion') {
versionFieldMap.name = 'affectedVersions'
versionFieldMap.type = 'system'
} else {
if (versionFieldMap.name.startsWith('cf[')) {
def cfId = versionFieldMap.name.tokenize('[]')[1]
versionFieldMap.cf = ComponentAccessor.customFieldManager.getCustomFieldObject(cfId as Long)
} else {
versionFieldMap.cf = ComponentAccessor.customFieldManager.getCustomFieldObjectsByName(versionFieldMap.name)[0]
}
}
log.info "Version field Map = $versionFieldMap"
versionFieldMap
}

@Override
List<QueryLiteral> getValues(QueryCreationContext queryCreationContext, FunctionOperand operand, TerminalClause terminalClause) {
def issueKey = operand.args[0].toUpperCase()
def issue = ComponentAccessor.issueManager.getIssueObject(issueKey)

List<Version> versions = []

def versionFieldMap = getVersionField(operand, terminalClause)
if (versionFieldMap.type == 'system') {
versions = issue[versionFieldMap.name] as List<Version>
} else {
versions = issue.getCustomFieldValue(versionFieldMap.cf as CustomField) as List<Version>
}
log.info "Returning versions: $versions"
return versions.collect { new QueryLiteral(operand, it.id) }
}
}

You'll have to save that file as <jirahome>/com/onresolve/jira/groovy/jql/VersionsFromIssueFunction.groovy

Then go to <jiraBaseUrl>/plugins/servlet/scriptrunner/admin/jqlfunctions and click on "scan".

Exty Ypsilonty
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
November 12, 2023

Thanks for all the effort, but I'm at user/project admin level in our (Jira) organisation and can't implement custom scripts, just JQL queries. I guess I'll have to take your word for it that it isn't possible and convince our Jira admins that such a script might be useful.

0 votes
Derek Fields _RightStar_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
November 9, 2023

@Exty Ypsilonty Welcome to the community. If you are working in Data Center, then this sounds like a good candidate for a custom JQL function, which you can implement in ScriptRunner. 

I don't have a suggestion for you if you are in the Cloud.

Suggest an answer

Log in or Sign up to answer