git_jira_fix_version_check.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #!/usr/bin/env python3
  2. ############################################################################
  3. #
  4. # Licensed to the Apache Software Foundation (ASF) under one
  5. # or more contributor license agreements. See the NOTICE file
  6. # distributed with this work for additional information
  7. # regarding copyright ownership. The ASF licenses this file
  8. # to you under the Apache License, Version 2.0 (the
  9. # "License"); you may not use this file except in compliance
  10. # with the License. You may obtain a copy of the License at
  11. #
  12. # http://www.apache.org/licenses/LICENSE-2.0
  13. #
  14. # Unless required by applicable law or agreed to in writing, software
  15. # distributed under the License is distributed on an "AS IS" BASIS,
  16. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. # See the License for the specific language governing permissions and
  18. # limitations under the License.
  19. #
  20. ############################################################################
  21. """An application to assist Release Managers with ensuring that histories in
  22. Git and fixVersions in JIRA are in agreement. See README.md for a detailed
  23. explanation.
  24. """
  25. import os
  26. import re
  27. import subprocess
  28. from jira import JIRA
  29. jira_project_name = input("JIRA Project Name (default: HADOOP): ") \
  30. or "HADOOP"
  31. # Define project_jira_keys with - appended. e.g for HADOOP Jiras,
  32. # project_jira_keys should include HADOOP-, HDFS-, YARN-, MAPREDUCE-
  33. project_jira_keys = [jira_project_name + '-']
  34. if jira_project_name == 'HADOOP':
  35. project_jira_keys.append('HDFS-')
  36. project_jira_keys.append('YARN-')
  37. project_jira_keys.append('MAPREDUCE-')
  38. first_exclude_commit_hash = input("First commit hash to start excluding commits from history: ")
  39. fix_version = input("Fix Version: ")
  40. jira_server_url = input(
  41. "Jira server url (default: https://issues.apache.org/jira): ") \
  42. or "https://issues.apache.org/jira"
  43. jira = JIRA(server=jira_server_url)
  44. local_project_dir = input("Path of project's working dir with release branch checked-in: ")
  45. os.chdir(local_project_dir)
  46. GIT_STATUS_MSG = subprocess.check_output(['git', 'status']).decode("utf-8")
  47. print('\nCheck git status output and verify expected branch\n')
  48. print(GIT_STATUS_MSG)
  49. print('\nJira/Git commit message diff starting: ##############################################')
  50. issue_set_from_commit_msg = set()
  51. for commit in subprocess.check_output(['git', 'log', '--pretty=oneline']).decode(
  52. "utf-8").splitlines():
  53. if commit.startswith(first_exclude_commit_hash):
  54. print("Found first commit hash after which git history is redundant. commit: "
  55. + first_exclude_commit_hash)
  56. print("Exiting successfully")
  57. break
  58. if re.search('revert', commit, re.IGNORECASE):
  59. print("Commit seems reverted. \t\t\t Commit: " + commit)
  60. continue
  61. ACTUAL_PROJECT_JIRA = None
  62. matches = re.findall('|'.join(project_jira_keys), commit)
  63. if matches:
  64. ACTUAL_PROJECT_JIRA = matches[0]
  65. if not ACTUAL_PROJECT_JIRA:
  66. print("WARN: Jira not found. \t\t\t Commit: " + commit)
  67. continue
  68. JIRA_NUM = ''
  69. for c in commit.split(ACTUAL_PROJECT_JIRA)[1]:
  70. if c.isdigit():
  71. JIRA_NUM = JIRA_NUM + c
  72. else:
  73. break
  74. issue = jira.issue(ACTUAL_PROJECT_JIRA + JIRA_NUM)
  75. EXPECTED_FIX_VERSION = False
  76. for version in issue.fields.fixVersions:
  77. if version.name == fix_version:
  78. EXPECTED_FIX_VERSION = True
  79. break
  80. if not EXPECTED_FIX_VERSION:
  81. print("Jira not present with version: " + fix_version + ". \t Commit: " + commit)
  82. continue
  83. if issue.fields.status is None or issue.fields.status.name not in ('Resolved', 'Closed'):
  84. print("Jira is not resolved yet? \t\t Commit: " + commit)
  85. else:
  86. # This means Jira corresponding to current commit message is resolved with expected
  87. # fixVersion.
  88. # This is no-op by default, if needed, convert to print statement.
  89. issue_set_from_commit_msg.add(ACTUAL_PROJECT_JIRA + JIRA_NUM)
  90. print('Jira/Git commit message diff completed: ##############################################')
  91. print('\nAny resolved Jira with fixVersion ' + fix_version
  92. + ' but corresponding commit not present')
  93. print('Starting diff: ##############################################')
  94. all_issues_with_fix_version = jira.search_issues(
  95. 'project=' + jira_project_name + ' and status in (Resolved,Closed) and fixVersion='
  96. + fix_version)
  97. for issue in all_issues_with_fix_version:
  98. if issue.key not in issue_set_from_commit_msg:
  99. print(issue.key + ' is marked resolved with fixVersion ' + fix_version
  100. + ' but no corresponding commit found')
  101. print('Completed diff: ##############################################')