JIRA - Delete all the attachments from all the issues in specific project on regular interval

atishayshukla August 1, 2018

Hi All,

First of all apologies that I am not able to provide with the solution that I have been trying as I do not have access to the environment currently and its a late requirement in sprint ( so I want the solution fast )

I want to periodically run a job which will delete all the attachments from all the issues under one project.

I tried using script console for the same and was able to get all the projects by using getProjects() from Project Manager.

However when I tried to get all the issues I couldnt get it even with using filter id as mentioned in some of the solutions.

An early response and any ideas about my problem statement would really be helpful.

Thanks

3 answers

1 accepted

3 votes
Answer accepted
Alexey Matveev
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.
August 1, 2018

Hello,

It would be like this:

ComponentAccessor.getProjectManager().getProjectObjects().each {project ->
ComponentAccessor.getIssueManager().getIssueIdsForProject(project.getId()).each { issueId ->
def issue = ComponentAccessor.getIssueManager().getIssueObject(issueId)
def attachments = ComponentAccessor.attachmentManager.getAttachments(issue)
attachments.each {attachment ->
attachmentManager.deleteAttachment(attachment)
}

}

}
atishayshukla August 1, 2018

Thanks a lot Alex...much appreciated..

Alexey Matveev
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.
August 1, 2018

You can go to coq item -> System -> Services. Then add your script as it is written in this article:

https://scriptrunner.adaptavist.com/5.4.12/jira/services.html

atishayshukla August 2, 2018

Thank i confirm that the script worked perfectly. Also one question is there a way l can get all issues in a project that got updated lets say before 90 days and then delete their attachment

Alexey Matveev
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.
August 2, 2018

Then your script should look this way:

mport com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.jql.parser.JqlQueryParser;
import com.atlassian.jira.issue.search.SearchProvider;
import com.atlassian.jira.web.bean.PagerFilter;


def findIssues(String jqlQuery) {
def issueManager = ComponentAccessor.issueManager
def user = ComponentAccessor.jiraAuthenticationContext.user
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class)

def query = jqlQueryParser.parseQuery(jqlQuery)
def results = searchProvider.search(query, user, PagerFilter.unlimitedFilter)
results.issues.collect
{ issue -> issueManager.getIssueObject(issue.id) }
}

def user = ComponentAccessor.jiraAuthenticationContext.user
def jqlQuery = "project = \"YOUR PROJJECT\" and updated > -90"
def issues = findIssues(jqlQuery)
issues.each{issue ->

  def attachments = ComponentAccessor.attachmentManager.getAttachments(issue)
     attachments.each {attachment ->
          attachmentManager.deleteAttachment(attachment)
     }

}
Like Polina Semykina likes this
atishayshukla August 3, 2018

Thanks a lot for your response. This works like a charm. But Scriptrunner services is not working. I placed my script in <JIRA_HOME>/Scripts folder on the server. I followed the document as it is and scheduled it to run, but it did not work. In admin.service.jelly.input field I put the name of the script RemoveAttachment.groovy, but it did not work.

I tried with the complete path of the file as well. It is the windows server.

Alexey Matveev
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.
August 3, 2018

Hello,

Try like this:

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.jql.parser.JqlQueryParser;
import com.atlassian.jira.issue.search.SearchProvider;
import com.atlassian.jira.web.bean.PagerFilter;

def userName = "your user name"

def findIssues(String jqlQuery) {
def issueManager = ComponentAccessor.issueManager
def user = ComponentAccessor.getUserManager().getUserByName(userName)
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class)

def query = jqlQueryParser.parseQuery(jqlQuery)
def results = searchProvider.search(query, user, PagerFilter.unlimitedFilter)
results.issues.collect
{ issue -> issueManager.getIssueObject(issue.id) }
}

def user =ComponentAccessor.getUserManager().getUserByName(userName)
def jqlQuery = "project = \"YOUR PROJJECT\" and updated > -90"
def issues = findIssues(jqlQuery)
issues.each{issue ->

  def attachments = ComponentAccessor.attachmentManager.getAttachments(issue)
     attachments.each {attachment ->
          attachmentManager.deleteAttachment(attachment)
     }

}
Like Polina Semykina likes this
atishayshukla August 3, 2018

Thanks, this Change will work to schedule the script from admin services?. I will try and let you know.

Alexey Matveev
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.
August 4, 2018

Try it first in the script console and then try in Service.

Also set the userName variable to the correct user. The problem is that a service is executed without any user, that is why the user must be explicitly set.

Sayan Kaiser December 18, 2019

Hi Alexey,

Would you be able to assist us, we are trying to run a script from the script console which will delete all attachments from a JQL, till now I am unable to confligure a right script 

3 votes
Mark Markov
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.
August 1, 2018

Hello @atishayshukla

Here is the script to run in script console that will delete attachments in project.

Just replace project key.

import com.atlassian.jira.component.ComponentAccessor

//here is your project key instead of "TEST"
def project = ComponentAccessor.getProjectManager().getProjectByCurrentKey("TEST")
def issueManager = ComponentAccessor.getIssueManager()
def attachmentManager = ComponentAccessor.getAttachmentManager()
def issuesIdsInProject = issueManager.getIssueIdsForProject(project.getId())

issuesIdsInProject.each {issueId ->
def issue = issueManager.getIssueObject(issueId)
def attachments = attachmentManager.getAttachments(issue)
attachments.each {attachment ->
attachmentManager.deleteAttachment(attachment)
}
}
atishayshukla August 1, 2018

Thanks a tonn Mark..

Mark Markov
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.
August 1, 2018

Be carefully, @Alexey Matveev script will delete all comments in all projects. Test it in staging environtment first.

atishayshukla August 1, 2018

Yes thanks Mark, You have any idea how can I run this as a scheduled job ( cron job )

Mark Markov
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.
August 1, 2018

Yes, you can use ScriptRunner Services for that.

atishayshukla August 1, 2018

Thanks Mark, I am new to this, any idea if I want to run delete attachments every week, how will I achieve it using Services. I will have the code for this in a file, but where exactly I put it on server, or how do I provide it inline. Sorry for being naive.

atishayshukla August 2, 2018

@Mark Markov - Can you help with the issues to be before certain update date say 90 days before basically which are not updated recently and then delete attachment from them? Thanks in advance

Sayan Kaiser December 17, 2019

Hi Mark,

I am trying to run similar script, but I do not want to delete all the comments. I would only like to run a script that will delete all attachements on a JQL. 

The JQL is returning 731 results at the moment, to test the script I can reduce the JQL size and try it on 50 issues on test 

Please assist me as I have tried numerous plugins and it doesn't work 

thanks,

Sayan

2 votes
Hung Nguyen March 4, 2020

Thanks to the responses posted here, I could successfully delete the attachments from the issues I need. The reason I post the revised code here is because the old ones above no longer work for 8.x, which is my case.

Here is the updated one with JQL search for resolved one with attachments > 10MB and not updated within 180 days, and delete the attachments

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.jql.parser.JqlQueryParser;
import com.atlassian.jira.issue.search.SearchQuery;
import com.atlassian.jira.issue.search.SearchResults;
import com.atlassian.jira.issue.search.SearchProvider;
import com.atlassian.jira.web.bean.PagerFilter;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.AttachmentManager;
import org.apache.log4j.Logger
import org.apache.log4j.Level

def logger = Logger.getLogger("com.acme.debug")
logger.setLevel(Level.DEBUG)

def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
def searchProvider = ComponentAccessor.getComponent(SearchProvider)
def issueManager = ComponentAccessor.getIssueManager()
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

def jqlQuery = "project = <YOURPROJECT> and resolution is not empty and attachments is not EMPTY  and updated < -180d"

def query = jqlQueryParser.parseQuery(jqlQuery)
def luceneQuery = SearchQuery.create(query, user)
def results = searchProvider.search(luceneQuery, PagerFilter.getUnlimitedFilter()).getResults()*.document
.collect{ComponentAccessor.issueManager.getIssueObject(it.getField('issue_id').stringValue().toLong())}
results.each {
issue ->
 
    def attachments = ComponentAccessor.attachmentManager.getAttachments(issue)
attachments.each {attachment ->
          if (attachment.getFilesize() > 10000000) {
          logger.warn(issue.getKey()+" "+attachment.getFilename()+":"+attachment.getFilesize().toString())
    ComponentAccessor.attachmentManager.deleteAttachment(attachment)
            }
      }
}

I used Script Console from ScriptRunner, and manually executed this code to bring down my attachment space.

Hope that helps someone who is doing the similar things

ViswanathanR July 6, 2020

It works on JRA 8. However on Jira 7, I'm getting into errors

this is both @Mark Markov script - the error

java.lang.NullPointerException: Cannot invoke method getId() on null object at Script84.run(Script84.groovy:7)

 

@Alexey Matveev script

{code}

No signature of method: org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.mport() is applicable for argument types: (java.lang.Class) values: [class com.atlassian.jira.component.ComponentAccessor] Possible solutions: split(groovy.lang.Closure), wait(), every(), wait(long), get(java.lang.String), put(java.lang.String, java.lang.Object)

{code}

Link Group IT August 16, 2020

Hi @Hung Nguyen ,

This script isn't working on JIRA 7.3.8 as most of the classes are not available.

Could you please create/guide one which works on JIRA 7.3.8 and scriptrunner  5.5.9 ?

 

Regards,

Noby Stephen

ViswanathanR August 17, 2020

Try this

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.jql.parser.JqlQueryParser;
import com.atlassian.jira.issue.search.SearchProvider;
import com.atlassian.jira.web.bean.PagerFilter;
import com.atlassian.jira.user.ApplicationUser 
def userName = "<username>"
#Your admin username 
def issueManager = ComponentAccessor.issueManager
def user =(ApplicationUser)ComponentAccessor.userManager.getUserByName(userName) 
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
def searchProvider = ComponentAccessor.getComponent(SearchProvider.class) 
def jqlQuery = "project = \"<projectname>\" and updated > -180"
#this is subject to projects requirement 
def query = jqlQueryParser.parseQuery(jqlQuery)
def results = searchProvider.search(query, user, PagerFilter.unlimitedFilter) results.issues.each{issue ->        
log.warn "issue: "+issue.key       
def attachmentManager = ComponentAccessor.attachmentManager           
def attachments = attachmentManager.getAttachments(issue)            
attachments.each {attachment ->          
log.warn "attachment: "+attachment.getFilename()         
attachmentManager.deleteAttachment(attachment)     }}

 

 

Hung Nguyen August 17, 2020

Hi Noby Stephen,

My script was the adapt from what Alexey Matveev _cPrime_ responded on Aug,03 2018

If you are using JIRA 7, you could use what Alexey posted there instead.

 

ViswanathanR,

Please note that due to copy and paste, the first letter from the the very first response from Alexey Matveev _cPrime on Aug 2, 2018 was missing, causing 'import' became 'mport' and would cause the error you reported above. Just need to make sure you correct that syntax error first.

ViswanathanR August 17, 2020

Thanks @Hung Nguyen 

it worked for me, I used the script above. 

 

if the format didn't copy/paste here correctly, I don't know what I'm doing wrong.

Link Group IT August 17, 2020

Thanks @ViswanathanR and @Hung Nguyen for the reply.

I have tried most of the scripts in this doc. But one or the other I get a class missing error.

Below I have attached the script shared by Viswanathan. Unfortunately such classes are not available in JIRA 7.3.8. Am I looking at the correct doc?

FYi @Alexey Matveev 

Missing_Class.jpg

Regards,

Noby Stephen

Hung Nguyen August 18, 2020

@Link Group IT What is the error when you tried my version of script for 8.x instead?

From the error above, I think 7.3.8 should use my version instead.

And if the first error is resolved, I think the second one would follow correctly. 

Link Group IT August 18, 2020

@Hung Nguyen ,

When I use your script, it complains about com.atlassian.jira.issue.search.SearchQuery class. If I remove it every script after line 22 errors. Do we have a similar SearchQuery class that I could use on JIRA 7.3.8 Data Center version?

 

Version8_script_error.jpg

Regards,

Noby Stephen

Hung Nguyen August 19, 2020

Change the 3rd line to

import com.atlassian.jira.bc.issue.search.SearchQuery;

Link Group IT August 19, 2020

Hi @Hung Nguyen 

I get the same unable to resolve class error when I try  with com.atlassian.jira.bc.issue.search.SearchQuery package

I have also tried com.atlassian.jira.issue.search and com.atlassian.jira.issue.search.providers packages but no luck.

Do we have any jar which I can load in lib directory to enable this class?

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events