Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in
Celebration

Earn badges and make progress

You're on your way to the next level! Join the Kudos program to earn points and save your progress.

Deleted user Avatar
Deleted user

Level 1: Seed

25 / 150 points

Next: Root

Avatar

1 badge earned

Collect

Participate in fun challenges

Challenges come and go, but your rewards stay with you. Do more to earn more!

Challenges
Coins

Gift kudos to your peers

What goes around comes around! Share the love by gifting kudos to your peers.

Recognition
Ribbon

Rise up in the ranks

Keep earning points to reach the top of the leaderboard. It resets every quarter so you always have a chance!

Leaderboard

How to find all JIRA filters that include JQL for a custom field value

Use case: I want to remove an old custom field value (or convert the old value into a new value). 

However, I need to see if that change would cause any JIRA filters including Board Quick Filter errors.

 

 

4 answers

1 accepted

3 votes
Answer accepted
Jonny Carter
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.
Feb 20, 2018

Bit late to the party, but wanted to provide an answer I'd cooked up for a similar question:

import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.search.SearchRequestEntity
import com.atlassian.jira.issue.search.SearchRequestManager
import com.atlassian.jira.util.Visitor

def filtersWithField = []
def myCustomFieldRegex = ~/(.*?Whatever You Call This Field.*?)|(.*?cf\[12345\].*?)/
def searchService = ComponentAccessor.getComponent(SearchService)
def searchRequestManager = ComponentAccessor.getComponent(SearchRequestManager)
searchRequestManager.visitAll(new Visitor<SearchRequestEntity>() {
@Override
void visit(SearchRequestEntity filter) {
def jql = filter.request
if (jql.findAll(myCustomFieldRegex)) {
/*
You don't have to get the search request object
as I am doing here. However, if you want to programatically
update search requests, you'll need to get the SearchRequest object itself, as I'm doing here. The SearchRequestEntity is a bit quicker to get, so I'm using that for this loop that iterates through the
entire list of saved filters.
*/
filtersWithField << searchRequestManager.getSearchRequestById(filter.id)
}
}
})
log.warn filtersWithField

You'll need to tweak the regular expression in the second line of code to match your custom field. Note that I've accounted for both the case where someone uses the custom field name in a query and where they reference it by ID.

The main difference between this and Daniel's is that instead of looping through the users and checking their owned filters, this uses the SearchRequestManager to loop through all saved searches directly.

I'm pretty sure the quick filters used on Jira Software Boards require their own treatment, but see the examples at https://scriptrunner.adaptavist.com/latest/jira/plugins/working-with-jira-agile.html for a starting point on looping through boards.

Hi All,

I trying the same script, but its not yielding any result, can you please help?

import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.search.SearchRequestEntity
import com.atlassian.jira.issue.search.SearchRequestManager
import com.atlassian.jira.util.Visitor

def filtersWithField = []
def myCustomFieldRegex = ~/(.Mobile OS.)|(.cf\[10801\].)/
def searchService = ComponentAccessor.getComponent(SearchService)
def searchRequestManager = ComponentAccessor.getComponent(SearchRequestManager)
searchRequestManager.visitAll(new Visitor<SearchRequestEntity>() {
@Override
void visit(SearchRequestEntity filter) {
def jql = filter.request
if (jql.findAll(myCustomFieldRegex)) {
filtersWithField << searchRequestManager.getSearchRequestById(filter.id)
}
}
})
log.warn filtersWithField

The following groovy script (run it in scriptrunner console) should help

 

import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.filter.SearchRequestService
import com.atlassian.jira.issue.search.SearchRequest
import com.atlassian.jira.bc.user.search.UserSearchParams
import com.atlassian.jira.bc.user.search.UserSearchService
import java.lang.StringBuilder

// Change these 2 constants to the values you want to search for
Integer CUSTOM_FIELD_ID = 12345
String CUSTOM_FIELD_NAME = 'My Custom Field'


SearchRequestService searchRequestService = ComponentAccessor.getComponent(SearchRequestService.class)
UserSearchService userSearchService = ComponentAccessor.getComponent(UserSearchService)
StringBuilder output = StringBuilder.newInstance()
output << "<pre>\n"

UserSearchParams userSearchParams = new UserSearchParams.Builder()
    .allowEmptyQuery(true)
    .ignorePermissionCheck(true)
    .maxResults(10000)
    .build()
userSearchService.findUsers("", userSearchParams).each{ApplicationUser filter_owner ->
    searchRequestService.getOwnedFilters(filter_owner).each{SearchRequest filter->
        String jql = filter.getQuery().toString()
        if (jql.contains(CUSTOM_FIELD_NAME) || jql.contains("cf[${CUSTOM_FIELD_ID}]")) {
            output << "${filter_owner.displayName}, ${filter.name}, ${filter.getPermissions().isPrivate() ? 'Private' : 'Shared'}, ${jql}\n"
        }
    }
}

output << "</pre>"
output.toString()

It isn't perfect as it would also match filters with your field name in search string (e.g. description ~ "my custom field is awesome") but for most purposes it should do what you want

I receive an error when attempting to run that script:

ScriptConsole.jpg

I was able to execute the following script (via Jonny Carter):

import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.search.SearchRequestEntity
import com.atlassian.jira.issue.search.SearchRequestManager
import com.atlassian.jira.util.Visitor

def filtersWithField = []
def myCustomFieldRegex = ~/(.*?Whatever You Call This Field.*?)|(.*?cf\[12345\].*?)/
def searchService = ComponentAccessor.getComponent(SearchService)
def searchRequestManager = ComponentAccessor.getComponent(SearchRequestManager)
searchRequestManager.visitAll(new Visitor<SearchRequestEntity>() {
    @Override
    void visit(SearchRequestEntity filter) {
        def jql = filter.request
        if (jql.findAll(myCustomFieldRegex)) {
            /*
            You don't have to get the search request object
            as I am doing here. However, if you want to programatically
            update search requests, you'll need to get the SearchRequest object itself, as I'm doing here. The SearchRequestEntity is a bit quicker to get, so I'm using that for this loop that iterates through the
            entire list of saved filters.
             */
            filtersWithField << searchRequestManager.getSearchRequestById(filter.id)
        }
    }
})
log.warn filtersWithField

However, it appears to only scan system-based filters.  Is it also possible to scan board quick filters too?

It looks like a permission problem to me

This version should be more robust and will display what it can. It will also tell you which users it is having trouble with

import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.bc.filter.SearchRequestService
import com.atlassian.jira.issue.search.SearchRequest
import com.atlassian.jira.bc.user.search.UserSearchParams
import com.atlassian.jira.bc.user.search.UserSearchService
import java.lang.StringBuilder

// Change these 2 constants to the values you want to search for
Integer CUSTOM_FIELD_ID = 12345
String CUSTOM_FIELD_NAME = 'Field name'


SearchRequestService searchRequestService = ComponentAccessor.getComponent(SearchRequestService.class)
UserSearchService userSearchService = ComponentAccessor.getComponent(UserSearchService)
StringBuilder output = StringBuilder.newInstance()
output << "<pre>\n"

UserSearchParams userSearchParams = new UserSearchParams.Builder()
    .allowEmptyQuery(true)
    .ignorePermissionCheck(true)
    .maxResults(10000)
    .build()
userSearchService.findUsers("", userSearchParams).each{ApplicationUser filter_owner ->
    try {
        searchRequestService.getOwnedFilters(filter_owner).each{SearchRequest filter->
            String jql = filter.getQuery().toString()
            if (jql.contains(CUSTOM_FIELD_NAME) || jql.contains("cf[${CUSTOM_FIELD_ID}]")) {
                output << "${filter_owner.displayName}, ${filter.name}, ${filter.getPermissions().isPrivate() ? 'Private' : 'Shared'}, ${jql}\n"
            }
        }
    } catch (Exception e) {
           output << "Unable to get filters for ${filter_owner.displayName} due to ${e}"     
    }
}

output << "</pre>"
output.toString()
Like arama mihai likes this

Others may know, but we needed this capability for Components and the simple change worked great:

if (jql.contains(CUSTOM_FIELD_NAME) || jql.contains("cf[${CUSTOM_FIELD_ID}]"))

to 

if (jql.contains('component/s') || jql.contains("component entry")) {

 We are using JIRA v7.4.4 and Script Runner v5.3.5, 

Hi Daniel,

 

Can this script be adapted to list all the workflows where a custom filed is mentioned (eg there is a post function having the field as mandatory)?

 

Thank you

Is there any way to do this without having scriptrunner? Or does anyone know of a feature request submitted to Atlassian for this ability?

For anyone still interested in this functionality:

The Subscriptions for Jira app allows Jira admin to find all filters by a piece of JQL (almost like a regular text search but within JQL-queries).

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events