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.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I receive an error when attempting to run that script:
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
However, it appears to only scan system-based filters. Is it also possible to scan board quick filters too?
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.
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()
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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,
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Is there any way to do this without having scriptrunner? Or does anyone know of a feature request submitted to Atlassian for this ability?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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).
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.