JIRA - bulk delete attachments

Leos Junek
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.
July 31, 2014

Is there any way to safely delete attachments from several JIRA issues? Attachments of issues in our JIRA take a lot of space on disk. To save some space my boss asked me to delete attachments of older issues of one specific project in that way JIRA is not damaged. The problem is there are hundreds of issues whose attachments should be erased and it would take ages to do it one-by-one.

I've been looking for an hour for solution, but JIRA seems not to support bulk deletion of attachments. I may manage to do it with Run CLI Actions in JIRA, however I am not sure about the solution

  1. Search for issues in JIRA (specific project, specific update time), export the list of issue keys to Excel. Open XLS file and save it as CSV. Only column is Key.
  2. Use Run CLI Actions in JIRA, functions runFromCsv and getAttachmentList to list Issue and attachments ID's. Save output to another CSV.
  3. Use Run CLI Actions in JIRA, functions runFromCsv and removeAttachment to remove attachments from all desired tasks.

Is that right workaround? What about Closed issues? Will JIRA allow to erase attachments from them?

Leos

4 answers

1 accepted

3 votes
Answer accepted
Leos Junek
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 12, 2014

Finaly I got it. Here's my workaround. (Project and domain names are fictional.)

There are some conditions that form a subset of affected issues:

- issues of specific project (here LIBFREX)

- closed issues

- issues that were resolved before 1.1.2013 (i.e. on 13 Aug 2014 it's 588 days ago)

- only attachments with extensions zip, 7z, log

1) Ensure sufficient permission

- User who is going to perform deletion must be allowed to do "Delete All Attachments" in Permission scheme of project LIBFREX

- There must be no property "jira.issue.editable=false" for Closed Issues in Workflow of project LIBFREX

2) Listing of all attachments of issues specified above

Auxiliary JQL queries designed by try-and-error principle to produce less than 1000 results (larger results could not be shown)

project = LIBFREX AND status = Closed AND resolved >= -900d AND resolved <= -588d" --common "--action getAttachmentList --issue @issue@" > JIRA_LIBFREX_900-588.1

project = LIBFREX AND status = Closed AND resolved >= -1000d AND resolved <= -901d" --common "--action getAttachmentList --issue @issue@" > JIRA_LIBFREX_1100-901.1

project = LIBFREX AND status = Closed AND resolved >= -1200d AND resolved <= -1001d" --common "--action getAttachmentList --issue @issue@" > JIRA_LIBFREX_1400-1101.1

project = LIBFREX AND status = Closed AND resolved >= -1500d AND resolved <= -1201d" --common "--action getAttachmentList --issue @issue@" > JIRA_LIBFREX_1700-1401.1

project = LIBFREX AND status = Closed AND resolved >= -1800d AND resolved <= -1501d" --common "--action getAttachmentList --issue @issue@" > JIRA_LIBFREX_3000-1701.1

project = LIBFREX AND status = Closed AND resolved >= -2700d AND resolved <= -1801d" --common "--action getAttachmentList --issue @issue@" > JIRA_LIBFREX_3000-1701.1

Command of Atlassian JIRA CLI

/opt/programs/jiraCLI/atlassian-cli-3.9.0/jira.sh -a runFromIssueList --search "project = LIBFREX AND status = Closed AND resolved >= -900d AND resolved <= -588d" --common "--action getAttachmentList --issue @issue@" > JIRA_LIBFREX_900-588.1

/opt/programs/jiraCLI/atlassian-cli-3.9.0/jira.sh -a runFromIssueList --search "project = LIBFREX AND status = Closed AND resolved >= -1000d AND resolved <= -901d" --common "--action getAttachmentList --issue @issue@" > JIRA_LIBFREX_1000-901.1

/opt/programs/jiraCLI/atlassian-cli-3.9.0/jira.sh -a runFromIssueList --search "project = LIBFREX AND status = Closed AND resolved >= -1200d AND resolved <= -1001d" --common "--action getAttachmentList --issue @issue@" > JIRA_LIBFREX_1200-1001.1

/opt/programs/jiraCLI/atlassian-cli-3.9.0/jira.sh -a runFromIssueList --search "project = LIBFREX AND status = Closed AND resolved >= -1500d AND resolved <= -1201d" --common "--action getAttachmentList --issue @issue@" > JIRA_LIBFREX_1500-1201.1

/opt/programs/jiraCLI/atlassian-cli-3.9.0/jira.sh -a runFromIssueList --search "project = LIBFREX AND status = Closed AND resolved >= -1800d AND resolved <= -1501d" --common "--action getAttachmentList --issue @issue@" > JIRA_LIBFREX_1800-1501.1

/opt/programs/jiraCLI/atlassian-cli-3.9.0/jira.sh -a runFromIssueList --search "project = LIBFREX AND status = Closed AND resolved >= -2700d AND resolved <= -1801d" --common "--action getAttachmentList --issue @issue@" > JIRA_LIBFREX_2700-1801.1

========== first 26 lines of file JIRA_LIBFREX_900-578.1 ==========

Run: --action getAttachmentList --issue LIBFREX-5500
4 attachments for issue: LIBFREX-5500
"Id","Name","MIME Type","Size","Date Created","Author"
"45687","SERVISNI_ZASAH_OKCTAB-OKC_(okcdt)_2012-12-28_14-52-28.LOG","text/plain","15421","12/28/12 2:53 PM","dunaj"
"45682","SERVISNI_ZASAH_OKCTAB-OKC_(sdsok.datcen.isacoon.cz)_2012-12-28_14-14-29.LOG","text/plain","15436","12/28/12 2:25 PM","dunaj"
"45683","SERVISNI_ZASAH_OKCTAB-OKCZ_(okcdz)_2012-12-28_14-21-08.LOG","text/plain","15421","12/28/12 2:25 PM","dunaj"
"45686","SERVISNI_ZASAH_OKCTAB_SKOL-OKCS_(okcds)_2012-12-28_14-29-19.LOG","text/plain","15426","12/28/12 2:53 PM","dunaj"


Run: --action getAttachmentList --issue LIBFREX-5499
0 attachments for issue: LIBFREX-5499


Run: --action getAttachmentList --issue LIBFREX-5498
1 attachments for issue: LIBFREX-5498
"Id","Name","MIME Type","Size","Date Created","Author"
"45653","upgrade_615.log","text/plain","834","12/27/12 7:05 PM","dunaj"


Run: --action getAttachmentList --issue LIBFREX-5496
4 attachments for issue: LIBFREX-5496
"Id","Name","MIME Type","Size","Date Created","Author"
"45630","SERVISNI_ZASAH_OKCTAB-OKCT2_(dbcentrumtest.isacoon.local)_2012-12-21_12-22-23.LOG","text/plain","89260","12/21/12 12:27 PM","dunaj"
"45639","SERVISNI_ZASAH_OKCTAB_PROD-OKCV10_(exadata3.isacoon.local)_2012-12-21_12-23-07.LOG","text/plain","89109","12/21/12 2:16 PM","dunaj"
"45632","SERVISNI_ZASAH_OKCTAB_PROD-OKCV2_(exadata4.isacoon.local)_2012-12-21_11-13-24.LOG","text/plain","89108","12/21/12 12:46 PM","dunaj"
"45631","SERVISNI_ZASAH_OKCTAB_VYVOJ_1-OKCV3_(hpbl22db.isacoon.local)_2012-12-21_12-24-43.LOG","text/plain","89510","12/21/12 12:27 PM","dunaj"

========== END of example lines from JIRA_LIBFREX_900-578.1 ==========

For each auxiliary JQL query perform that command and produce JIRA_LIBFREX_xxx-yyy.1 file. Perform steps 3-6 for each produced file.

3) Restriction to files with specified extensions

- ZIP/zip

- 7Z/7z

- LOG/log

grep -Ei 'LIBFREX-|.LOG"|.7z"|.zip"' JIRA_LIBFREX_900-588.1 | grep -v 'Run:' > JIRA_LIBFREX_900-588.2
grep -Ei 'LIBFREX-|.LOG"|.7z"|.zip"' JIRA_LIBFREX_1000-901.1 | grep -v 'Run:' > JIRA_LIBFREX_1000-901.2
etc.

========== first 26 lines of file JIRA_LIBFREX_900-578.2 ==========

4 attachments for issue: LIBFREX-5500
"45687","SERVISNI_ZASAH_OKCTAB-OKC_(okcdt)_2012-12-28_14-52-28.LOG","text/plain","15421","12/28/12 2:53 PM","dunaj"
"45682","SERVISNI_ZASAH_OKCTAB-OKC_(sdsok.datcen.isacoon.cz)_2012-12-28_14-14-29.LOG","text/plain","15436","12/28/12 2:25 PM","dunaj"
"45683","SERVISNI_ZASAH_OKCTAB-OKCZ_(okcdz)_2012-12-28_14-21-08.LOG","text/plain","15421","12/28/12 2:25 PM","dunaj"
"45686","SERVISNI_ZASAH_OKCTAB_SKOL-OKCS_(okcds)_2012-12-28_14-29-19.LOG","text/plain","15426","12/28/12 2:53 PM","dunaj"
0 attachments for issue: LIBFREX-5499
1 attachments for issue: LIBFREX-5498
"45653","upgrade_615.log","text/plain","834","12/27/12 7:05 PM","dunaj"
4 attachments for issue: LIBFREX-5496
"45630","SERVISNI_ZASAH_OKCTAB-OKCT2_(dbcentrumtest.isacoon.local)_2012-12-21_12-22-23.LOG","text/plain","89260","12/21/12 12:27 PM","dunaj"
"45639","SERVISNI_ZASAH_OKCTAB_PROD-OKCV10_(exadata3.isacoon.local)_2012-12-21_12-23-07.LOG","text/plain","89109","12/21/12 2:16 PM","dunaj"
"45632","SERVISNI_ZASAH_OKCTAB_PROD-OKCV2_(exadata4.isacoon.local)_2012-12-21_11-13-24.LOG","text/plain","89108","12/21/12 12:46 PM","dunaj"
"45631","SERVISNI_ZASAH_OKCTAB_VYVOJ_1-OKCV3_(hpbl22db.isacoon.local)_2012-12-21_12-24-43.LOG","text/plain","89510","12/21/12 12:27 PM","dunaj"
0 attachments for issue: LIBFREX-5495
0 attachments for issue: LIBFREX-5493
4 attachments for issue: LIBFREX-5492
"45620","UPG_DB-215_OKCTAB_SKOL-OKCS_(okcds)_2012-12-21_06-27-32.7z","application/octet-stream","984648","12/21/12 7:12 AM","brozek"
"45609","UPG_DB-220_OKCTAB_SKOL-OKCS_(okcds)_2012-12-20_15-24-53.LOG","text/plain","3291","12/20/12 3:27 PM","bernhard"
"45621","UPG_DB-220_OKCTAB_SKOL-OKCS_(okcds)_2012-12-21_07-14-59.7z","application/octet-stream","1158490","12/21/12 7:57 AM","brozek"
"45623","UPG_DB-230_OKCTAB_SKOL-OKCS_(okcds)_2012-12-21_07-56-54.7z","application/octet-stream","1089864","12/21/12 8:46 AM","brozek"
2 attachments for issue: LIBFREX-5491
"45618","UPG_DB-220_OKCTAB_PROD-OKCV2_(exadata4.isacoon.local)_2012-12-20_15-38-55.7z","application/octet-stream","2191306","12/21/12 6:13 AM","brozek"
"45619","UPG_DB-230_OKCTAB_PROD-OKCV2_(exadata4.isacoon.local)_2012-12-21_06-17-01.7z","application/octet-stream","1083761","12/21/12 7:04 AM","brozek"
0 attachments for issue: LIBFREX-5490
0 attachments for issue: LIBFREX-5489

========== END of example lines from JIRA_LIBFREX_900-578.2 ==========

4) Modification of JIRA CLI output to sufficient form for other usage

=== script modifyAttachList.sh ===

#!/bin/bash
# Converts output file of Atlassian CLI to another format

inputFile=$1
outputFile=$2
inputFileLength=$(wc -l $inputFile | cut -d ' ' -f 1);
headString='attachments for issue:'
projectCode="LIBFREX-"
line=""
issueKey=""
idAttachment=""

echo "Issue, Id" > $outputFile

for ((i=1; i<=$inputFileLength; i++)); do
  line=$(head -n ${i} $inputFile | tail -n 1)  # Get current line
  if echo $line | grep -q "$headString"; then
    issueKey=$(echo $line | sed 's/.*\('$projectCode'[0-9]*\)/\1/')
  else
    idAttachment=$(echo $line | cut -d '"' -f 2);
    echo "$issueKey, $idAttachment" >> $outputFile
  fi
done

=== END of script modifyAttachList.sh ===

Commands

./modifyAttachList.sh JIRA_LIBFREX_900-588.2   JIRA_LIBFREX_900-588.3
./modifyAttachList.sh JIRA_LIBFREX_1000-901.2  JIRA_LIBFREX_1000-901.3
etc.

Example of a few lines from outputfile JIRA_LIBFREX_900-588.3

Issue, Id
LIBFREX-5500, 45687
LIBFREX-5500, 45682
LIBFREX-5500, 45683
LIBFREX-5500, 45686
LIBFREX-5498, 45653
LIBFREX-5496, 45630
LIBFREX-5496, 45639
LIBFREX-5496, 45632
LIBFREX-5496, 45631

5) Deletion of attachments

Ensure, that attachment folder $JIRA_HOME/data/attachments is recursively RW accessible by user running Tomcat.

Perform commands

/opt/programs/jiraCLI/atlassian-cli-3.9.0/jira.sh -a runFromCSV --common "--action removeAttachment" --file JIRA_LIBFREX_900-588.3
/opt/programs/jiraCLI/atlassian-cli-3.9.0/jira.sh -a runFromCSV --common "--action removeAttachment" --file JIRA_LIBFREX_1000-901.3
etc.

Example output
Run: --action removeAttachment --issue "LIBFREX-5500" --id "45687"
Attachment with id 45687 removed from issue LIBFREX-5500.

Run: --action removeAttachment --issue "LIBFREX-5500" --id "45682"
Attachment with id 45682 removed from issue LIBFREX-5500.

6) (optional) Add comment to each affected issue

Modify bash script to create a list of comments - add those lines

outputFileComment=$3
echo "Issue, Comment" > $outputFileComment
comment=$(echo $line | cut -d '"' -f 4);
echo "$issueKey, File \"$comment\" was deleted because of ..." >> $outputFileComment

Then run script

./modifyAttachList.sh JIRA_LIBFREX_900-578.2 JIRA_LIBFREX_900-578.del JIRA_LIBFREX_900-588.com

and perform Atlassian CLI command (both for each subset, as noticed above in step 2)

/opt/programs/jiraCLI/atlassian-cli-3.9.0/jira.sh -a runFromCSV --common "--action addComment" --file JIRA_LIBFREX_900-588.com

WARN: Do not forget to disable outgoing mail or to disable notification about issue updates before running this command.

7) Change permission back to original settings

If some permisssion was modified at step 1) just for this case of deletion attachments, now its the right time to take it back and restore original settings.

8 votes
Vadim Rutkevich
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.
February 8, 2015

Hi, all.

You can try Smart Attachments. It allows you to remove a bulk of attachments from one issue. In plans we have your feature too.

Other features also include categorization of attachments, access permissions per category, drag-n-drop upload of files to the category and other improvements.

Best Regards,

Vadim Rutkevich

2 votes
Alexey_Rjeutski__Polontech_
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.
July 31, 2014

1. instead of atlassian CLI you can run a script with script runner and do the deletion during search

2. If you cannot edit closed issues manually (try to delete attachment from one of them) - that means that the Closed status is not editable inside your workflow. You should change the workflow and remove edit restriction from the Closed status on the time of script execution.

Leos Junek
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.
July 31, 2014

Hello Alexey. Thanks for your suggestion. I have not any experience with writing Groovy scripts, till today I only used build-in ones. It would take me too much time to learn it and to create appropriate script to find & delete attachments. That's way using Atlassian CLI would be easier for me.

Good comment on closed issues - yes, it must be set by workflow settings.

Alexey_Rjeutski__Polontech_
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.
July 31, 2014
I think you can do the same with atlassian cli - search for issues and process response immediately without convertation to Csv. But in general - any automation script is good solution of this problem.
0 votes
Vadim Rutkevich
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.
September 23, 2019

Hi Leos!

Please try Delete Bulk Attachments for Jira. No need to wait for request completion. The app is completely free. You can get more bulk operations in Smart Attachments for Jira.

Thanks.


Sincerely, Vadim

Suggest an answer

Log in or Sign up to answer