|
| 1 | +from atlassian import Jira |
| 2 | +from atlassian import Stash |
| 3 | +from var import config |
| 4 | +import logging |
| 5 | +import time |
| 6 | + |
| 7 | +PROJECT_KEY = 'PROJ' |
| 8 | +REPOS = ['repo1', 'repo2'] |
| 9 | +ACCEPTED_ISSUE_STATUSES = ["Closed", "Verified"] |
| 10 | +EXCLUDE_REPO_RULES = config.exclude_parameters |
| 11 | +LAST_COMMIT_CONDITION_IN_DAYS = 75 |
| 12 | +ATLASSIAN_USER = config.JIRA_LOGIN |
| 13 | +ATLASSIAN_PASSWORD = config.JIRA_PASSWORD |
| 14 | + |
| 15 | +logging.basicConfig(level=logging.ERROR) |
| 16 | +jira = Jira( |
| 17 | + url=config.JIRA_URL, |
| 18 | + username=ATLASSIAN_USER, |
| 19 | + password=ATLASSIAN_PASSWORD) |
| 20 | + |
| 21 | +stash = Stash( |
| 22 | + url=config.STASH_URL, |
| 23 | + username=ATLASSIAN_USER, |
| 24 | + password=ATLASSIAN_PASSWORD |
| 25 | +) |
| 26 | + |
| 27 | +flag = True |
| 28 | +time_now = int(time.time()) * 1000 |
| 29 | +delta_for_time_ms = LAST_COMMIT_CONDITION_IN_DAYS * 24 * 60 * 60 * 1000 |
| 30 | +commit_info_key = "com.atlassian.bitbucket.server.bitbucket-branch:latest-commit-metadata" |
| 31 | +out_going_pull_request = "com.atlassian.bitbucket.server.bitbucket-ref-metadata:outgoing-pull-request-metadata" |
| 32 | +branch_related_issues = "com.atlassian.bitbucket.server.bitbucket-jira:branch-list-jira-issues" |
| 33 | + |
| 34 | + |
| 35 | +def is_can_removed_branch(branch_candidate): |
| 36 | + branch_id_name = branch_candidate.get('id') |
| 37 | + # Just exclude exist mainstream branches |
| 38 | + if any(x in branch_id_name for x in EXCLUDE_REPO_RULES): |
| 39 | + print(branch.get('displayId') + " in exclusion list") |
| 40 | + return False |
| 41 | + # skip default branch maybe DevOps made configs in ui |
| 42 | + if branch_candidate.get('isDefault'): |
| 43 | + print(branch.get('displayId') + " is default") |
| 44 | + return False |
| 45 | + pull_request_info = ((branch_candidate.get('metadata') or {}).get(out_going_pull_request) or {}) |
| 46 | + if pull_request_info.get('pullRequest') is not None or (pull_request_info.get('open') or 0) > 0: |
| 47 | + print(branch.get('displayId') + " has open PR") |
| 48 | + return False |
| 49 | + # skip branches without pull request info |
| 50 | + if pull_request_info is None or len(pull_request_info) == 0: |
| 51 | + print(branch.get('displayId') + " without pull request info") |
| 52 | + # return False |
| 53 | + |
| 54 | + author_time_stamp = branch_candidate.get('metadata').get(commit_info_key).get('authorTimestamp') |
| 55 | + # check latest commit info |
| 56 | + if time_now - author_time_stamp < delta_for_time_ms: |
| 57 | + print(branch.get('displayId') + " is too early to remove") |
| 58 | + return False |
| 59 | + |
| 60 | + # check issues statuses |
| 61 | + exclude = False |
| 62 | + issues_in_metadata = branch_candidate.get('metadata').get(branch_related_issues) |
| 63 | + for issue in issues_in_metadata: |
| 64 | + if jira.get_issue_status(issue.get('key')) not in ACCEPTED_ISSUE_STATUSES: |
| 65 | + print(branch.get('displayId') + " related issue has not Resolution ") |
| 66 | + return False |
| 67 | + # so branch can be removed |
| 68 | + return True |
| 69 | + |
| 70 | + |
| 71 | +if __name__ == '__main__': |
| 72 | + DRY_RUN = False |
| 73 | + log = open("candidate_to_remove.csv", "w") |
| 74 | + log.write("'Branch name', 'Latest commit', 'Related issues has Resolution'\n") |
| 75 | + for repository in REPOS: |
| 76 | + step = 0 |
| 77 | + limit = 10 |
| 78 | + while flag: |
| 79 | + branches = stash.get_branches(PROJECT_KEY, repository, start=step * limit, limit=limit, |
| 80 | + order_by='ALPHABETICAL') |
| 81 | + if len(branches) == 0: |
| 82 | + flag = False |
| 83 | + break |
| 84 | + for branch in branches: |
| 85 | + display_id = branch['displayId'] |
| 86 | + committer_time_stamp = branch.get('metadata').get(commit_info_key).get('committerTimestamp') / 1000 |
| 87 | + last_date_commit = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(committer_time_stamp)) |
| 88 | + if is_can_removed_branch(branch): |
| 89 | + if not DRY_RUN: |
| 90 | + stash.delete_branch(project=PROJECT_KEY, repository=repository, name=display_id, |
| 91 | + end_point=branch['latestCommit']) |
| 92 | + log.write("{},{},{}\n".format(display_id, last_date_commit, True)) |
| 93 | + step += 1 |
| 94 | + log.close() |
| 95 | + print("Done") |
0 commit comments