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

Come for the products,
stay for the community

The Atlassian Community can help you and your team get more value out of Atlassian products and practices.

Atlassian Community about banner
4,643,336
Community Members
 
Community Events
196
Community Groups

Continuous cleanup for Jira. Part 2.

Hi awesome community! 

 

This is the second iteration from series of article about Continuous Jira cleanup which I have tried to implement automation scripts for my Jira instance. (first one here)

Today, I would like to share a few scripts related to clean up configuration of the project. 

 

Disclaimer,  as usual, everything should be tested in the test-environment first.

Also, I'll be happy if you share or provide advice for the related small scripts. All scripts were tested and executed on Jira 7 Server releases (7.6.10, 7.13.0).

Well, you can use for execute groovy on Jira one of these apps (add-ons) - Scriptrunner for Jira (commercial) , MyGroovy (Opensource BSD-2) , Groovioli (Opensource BSD-2)

 

And scripts based on this scheme

image.png

 

Well, let's next step is cleanup our Jira instance.

 

1. Cleanup UnAssociated Issue Type

boolean isPreview = true

import
com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.config.IssueTypeManager
import org.apache.log4j.Logger
import org.apache.log4j.Level

def log = Logger.getLogger("com.gonchik.scripts.groovy.cleanupUnAssociatedIssueType")
log.setLevel(Level.DEBUG)

// Cleanup of the cleanupUnAssociatedIssueType
def issueTypeManager = ComponentAccessor.getComponent(IssueTypeManager)
def sb = new StringBuilder()

sb.append("Deleted issue type schemes with no associated projects:<br/><br/>\n")
issueTypeManager.issueTypes.each {
try {
if (!issueTypeManager.hasAssociatedIssues(it)) {
sb.append("${it.name}<br/>\n")
if (!isPreview) {
// Set the Default of Task Id
String replaceIssueTypeId = "1"
if (it.isSubTask()){
// Id of Sub-Task
replaceIssueTypeId = "5"
}
issueTypeManager.removeIssueType(it.id, replaceIssueTypeId)
}
}
}
catch (Exception e) {
sb.append("Error: " + e + "<br/>\n")
}
}

return sb.toString()

 

2. Cleanup unused Issue Type Schemes.

boolean isPreview = false
import com.atlassian.jira.component.ComponentAccessor
import org.apache.log4j.Logger
import org.apache.log4j.Level

def log = Logger.getLogger("com.gonchik.scripts.groovy.cleanupUsUsedIssueTypeSchemes")
log.setLevel(Level.DEBUG)

def schemeManager = ComponentAccessor.issueTypeSchemeManager
def sb = new StringBuilder()

sb.append("Deleted issue type schemes with no associated projects:<br/><br/>\n")
schemeManager.allSchemes.each {
if (schemeManager.isDefaultIssueTypeScheme(it)){
return
}
try {
if (it.associatedProjectIds.size() == 0) {
sb.append("${it.name}<br/>\n")
if (!isPreview) {
schemeManager.deleteScheme(it)
}
}
}
catch (Exception e) {
sb.append("Error: " + e + "<br/>\n")
}
}

return sb.toString()

 

3. Cleanup Issue Type Screen Schemes.

boolean isPreview = true
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.fields.screen.issuetype.IssueTypeScreenSchemeManager
import org.apache.log4j.Logger
import org.apache.log4j.Level

def log = Logger.getLogger("com.gonchik.scripts.groovy.cleanupUsUsedIssueTypeScreenManager")
log.setLevel(Level.DEBUG)

def schemeManager = ComponentAccessor.issueTypeScreenSchemeManager
def sb = new StringBuilder()

sb.append("Deleted issue type screen schemes with no associated projects:<br/><br/>\n")
schemeManager.issueTypeScreenSchemes.each {
if (it.isDefault()) {
return
}
try {
if (schemeManager.getProjects(it).size() < 1) {
sb.append("${it.name}<br/>\n")
if (!isPreview) {
schemeManager.removeIssueTypeScreenScheme(it)
}
}
}
catch (Exception e) {
sb.append("Error: " + e + "<br/>\n")
}
}

return sb.toString()

 

4. Cleanup Un Associated Issue Type Screen

boolean isPreview = true

import
com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.fields.screen.issuetype.IssueTypeScreenSchemeManager
import org.apache.log4j.Logger
import org.apache.log4j.Level

def log = Logger.getLogger("com.gonchik.scripts.groovy.cleanupUnAssociatedIssueTypeScreen")
log.setLevel(Level.DEBUG)

def schemeManager = ComponentAccessor.issueTypeScreenManager
def sb = new StringBuilder()

sb.append("Deleted issue type screen schemes with no associated projects:<br/><br/>\n")
schemeManager.issueTypeScreenSchemes.each {
if (it.isDefault()) {
return
}
try {
if (schemeManager.getProjects(it).size() == 0) {
sb.append("${it.name}<br/>\n")
if (!isPreview) {
schemeManager.removeIssueTypeScreenScheme(it)
}
}
}
catch (Exception e) {
sb.append("Error: " + e + "<br/>\n")
}
}

return sb.toString()

 

5. Cleanup unused Field Screens.

boolean isPreview = true

import
com.atlassian.jira.component.ComponentAccessor
import org.apache.log4j.Logger
import org.apache.log4j.Level

def log = Logger.getLogger("com.gonchik.scripts.groovy.cleanupUnUsedFieldScreens")
log.setLevel(Level.DEBUG)

def schemeManager = ComponentAccessor.fieldScreenSchemeManager
def sb = new StringBuilder()

sb.append("Deleted issue type screen schemes with no associated projects:<br/><br/>\n")
schemeManager.fieldScreenSchemes().each {
if (it.isDefault()) {
return
}
try {
if (schemeManager.getProjects(it).size() == 0) {
sb.append("${it.name}<br/>\n")
if (!isPreview) {
schemeManager.removeFieldScreenScheme(it)
}
}
}
catch (Exception e) {
sb.append("Error: " + e + "<br/>\n")
}
}

return sb.toString()

 

 

 

And last one is cleanup un associated workflow schemes and workflows:

boolean isPreview = true
import com.atlassian.jira.component.ComponentAccessor
import org.apache.log4j.Logger
import org.apache.log4j.Level


def log = Logger.getLogger("com.gonchik.scripts.groovy.deleteUnUsedWorkflows")
log.setLevel(Level.DEBUG)

def workflowManager = ComponentAccessor.workflowManager
def schemeManager = ComponentAccessor.workflowSchemeManager
def sb = new StringBuilder()

// Review workflow schemes
schemeManager.schemeObjects.each {
try {
if (schemeManager.getProjectsUsing(schemeManager.getWorkflowSchemeObj(it.id)).size() == 0) {
sb.append("${it.name}<br/>\n")
if (!isPreview) {
log.info("Deleting workflow scheme: ${it.name}")
schemeManager.deleteScheme(it.id)
}
}
}
catch (Exception e) {
log.error('Something wrong, ' + e)
sb.append("Error: " + e + "<br/>\n")
}
}

// review Workflows
workflowManager.workflows.each {
if (!it.systemWorkflow) {
def schemes = schemeManager.getSchemesForWorkflow(it)
if (schemes.size() == 0) {
sb.append("${it.name}<br/>\n")
if (!isPreview) {
log.info("Deleting workflow: ${it.displayName}")
workflowManager.deleteWorkflow(it)
}
}
}
}

return sb.toString()

  

I hope these short scripts will reduce your manual work.

Have a nice experiments. :)

P.S. All related code you can find bitbucket repo or github repo

P.S.S Next article will related to the comparing the configs. 

P.S.S.S. After that I will show how to find same configs with predefined distance of next configs. (Levenshtein distance)  

 

Cheers,

Gonchik Tsymzhitov

13 comments

Craig Castle-Mead
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 03, 2019

Hey Gonchik,

Great work on both parts of your articles - will be trying them out.

Wondering if you may consider a part 3 with any of the following:

- removing users/groups from a project role where that role does nothing (no permissions, notifications, use in workflow conditions etc)

- identifying use of groups (if a group is to be deprecated or renamed etc). There’s so many locations used within core/software/JSD, let alone the marketplace apps

 

CCM

Tom Lister
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
Feb 09, 2019

Hi @Gonchik Tsymzhitov

this could save me many hours as I’ve inherited a Jira instance at my new job with dozens and dozens of orphaned schemes.

will definitely be looking into open source groovy runners too.

Like Gonchik Tsymzhitov likes this
Gonchik Tsymzhitov
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
Feb 09, 2019

Hi @Tom Lister

I am happy if it helps you and feel free fork and time to time provide Pull Request:))

 

Cheers,

Gonchik Tsymzhitov

Tom Lister
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
Feb 13, 2019

Hi

In 4. Cleanup Un Associated Issue Type Screen

I had to change this line 

def schemeManager = ComponentAccessor.issueTypeScreenSchemeManager

Like Gonchik Tsymzhitov likes this
Tom Lister
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
Feb 13, 2019

Ignore the above, versions in github are good

Like Gonchik Tsymzhitov likes this
Deleted user Mar 04, 2019

After reading Part 1, I had to find the other.  I've bookmarked both articles for future reference.  Thank you for sharing!

Like Gonchik Tsymzhitov likes this
Gonchik Tsymzhitov
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
Mar 31, 2019

Welcome to use it :) 

Hi @Gonchik Tsymzhitov 

Thanks for sharing scripts :)

I need to do the same for Confluence, any idea?

Like Gonchik Tsymzhitov likes this

Hi @Gonchik Tsymzhitov 

 

Could you please provide a script to remove the  inactive status in jira, i tried a lot but it doesn't seems to be working as expected.

Thanks

Gonchik Tsymzhitov
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
May 06, 2021

@Ahmed Trabelsi Yes, I will add a few things into repo

Gonchik Tsymzhitov
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
May 06, 2021

@PK_KP Please, check out the latest one from github 

Hi @Gonchik Tsymzhitov ,

Appreciate the effort in providing the community with the part1 and 2 article. 
Is there any way we could have a cleanup for field configurations and field configuration schemes too.

Thanking in advance.

Like Gonchik Tsymzhitov likes this
Gonchik Tsymzhitov
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
Oct 09, 2022

Hi @Mohammed Siyad , 

Let me think about that. 

For now I don't have any actual script. 

But actual info I keep there:

https://github.com/gonchik/cleanup-scripts

Like Mohammed Siyad likes this

Comment

Log in or Sign up to comment
TAGS
AUG Leaders

Atlassian Community Events