Skip to content

Instantly share code, notes, and snippets.

@perfecto25
Last active January 11, 2019 18:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save perfecto25/633170c049ad1db8fdf5165a2fcf7171 to your computer and use it in GitHub Desktop.
Save perfecto25/633170c049ad1db8fdf5165a2fcf7171 to your computer and use it in GitHub Desktop.
Deletes Pull Requests and Branches from a given repository in BitBucket
#!/usr/bin/env python
# coding=utf-8
# Deletes all branches and pull requests from a Repo unless its 'master' or 'production'
# TO BE USED ON DEV BITBUCKET INSTANCE ONLY!!!
from __future__ import print_function
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
import json
import os
import sys
# !!!!!!!!!!!!!!!!!
# MAKE SURE NOT TO RUN THIS SCRIPT IN PRODUCTION INSTANCE!!
# !!!!!!!!!!!!!!!!
bb_host = 'bitbucket.test.com'
bb_user = 'user'
bb_pw = 'pw'
bb_proj = 'PRJ'
bb_repo = 'my_repo'
branch_blacklist = ['master', 'production'] # branches that should not be deleted
def curl(method, url, user=None, pw=None, data=None, header=None):
''' make a Curl request to URL, returns a JSON '''
if not header: header = {'Content-Type':'application/json'}
# check method
if method == 'get':
if user:
req = requests.get(url, auth=(user, pw), verify=False)
else:
req = requests.get(url, verify=False)
if method is 'post':
req = requests.post(url, auth=(user, pw), data=data, headers=header, verify=False)
if method is 'delete':
req = requests.delete(url, auth=(user, pw), data=data, headers=header, verify=False)
req.raise_for_status() # raise error if HTTP return code is not 200, 201 or 202
try:
return req.json()
except ValueError:
return 'ok'
def delete_all_PRs():
''' get ID of each PR, delete PR using ID '''
# get all Pull Requests
url = 'https://'+bb_host+'/rest/api/1.0/projects/'+bb_proj+'/repos/'+bb_repo+'/pull-requests'
pullreqs = curl('get', url, bb_user, bb_pw)
# for each PR get PR ID number
for val in pullreqs['values']:
try:
pr_id = str(val['links']['self'][0]).rsplit('/', 1)[1].replace("'}", "")
except (KeyError, AttributeError, IndexError) as e:
print('error cannot get PR ID: %s ' % str(e))
continue
# get latest version # of PR
if pr_id:
url = 'https://'+bb_host+'/rest/api/1.0/projects/'+bb_proj+'/repos/'+bb_repo+'/pull-requests/'+pr_id
pr = curl('get', url, bb_user, bb_pw)
# get Version
try:
version = pr['version']
except (KeyError, AttributeError, IndexError) as e:
print('error cannot get PR version for pull request ID: %s ' % str(pr_id))
continue
# delete PR using PR ID and Version
url = 'https://'+bb_host+'/rest/api/1.0/projects/'+bb_proj+'/repos/'+bb_repo+'/pull-requests/'+pr_id+'/decline?version='+str(version)
try:
curl('post', url, bb_user, bb_pw)
except Exception as e:
print('error deleting pull request %s : %s' % (pr_id, str(e)))
continue
print('deleted Pull Request # %s ' % pr_id)
def delete_branches():
''' deletes branches in a repository '''
# get all branches
url = 'https://'+bb_host+'/rest/api/1.0/projects/'+bb_proj+'/repos/'+bb_repo+'/branches'
branches = curl('get', url, bb_user, bb_pw)
for branch in branches['values']:
try:
branch_id = branch['id']
except (KeyError, ValueError, AttributeError) as e:
print('error getting branch ID %s') % str(e)
continue
branch_name = branch_id.rsplit('/', 1)[1]
if branch_name in branch_blacklist:
break
# delete branch
url = 'https://'+bb_host+'/rest/branch-utils/1.0/projects/'+bb_proj+'/repos/'+bb_repo+'/branches'
data = '{"name": "%s"}' % branch_id
print('deleting branch: %s' % branch_name)
curl('delete', url, bb_user, bb_pw, data)
if __name__ == "__main__":
prompt = raw_input('this script will delete all Pull Requests and Branches in your Bitbucket instance: %s\ntype "yes" to proceed: ' % bb_host)
if prompt == 'yes':
delete_all_PRs()
delete_branches()
else:
print('\nexiting script')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment