get_contributors.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. from github import Github
  2. from subprocess import check_output
  3. import shlex
  4. from tqdm import tqdm
  5. import click
  6. from collections import defaultdict
  7. import sys
  8. def _find_pr_number(line: str) -> str:
  9. start = line.find("(#")
  10. if start < 0:
  11. return ""
  12. end = line.find(")", start + 2)
  13. if end < 0:
  14. return ""
  15. return line[start + 2 : end]
  16. @click.command()
  17. @click.option(
  18. "--access-token",
  19. required=True,
  20. help="""
  21. Github Access token that has repo:public_repo and user:read:user permission.
  22. Create them at https://github.com/settings/tokens/new
  23. """,
  24. )
  25. @click.option(
  26. "--prev-release-commit",
  27. required=True,
  28. help="Last commit SHA of the previous release.",
  29. )
  30. @click.option(
  31. "--curr-release-commit",
  32. required=True,
  33. help="Last commit SHA of the current release.",
  34. )
  35. def run(access_token, prev_release_commit, curr_release_commit):
  36. print("Writing commit descriptions to 'commits.txt'...")
  37. commits = check_output(
  38. [
  39. "git",
  40. "log",
  41. f"{prev_release_commit}..{curr_release_commit}",
  42. "--pretty=format:'%s'",
  43. ],
  44. stderr=sys.stderr,
  45. ).decode()
  46. with open("commits.txt", "w") as file:
  47. file.write(commits)
  48. # Generate command
  49. cmd = []
  50. cmd.append(
  51. (
  52. f"git log {prev_release_commit}..{curr_release_commit} "
  53. f'--pretty=format:"%s" '
  54. f' | grep -Eo "#(\d+)"'
  55. )
  56. )
  57. joined = " && ".join(cmd)
  58. cmd = f"bash -c '{joined}'"
  59. cmd = shlex.split(cmd)
  60. print("Executing", cmd)
  61. lines = commits.split("\n")
  62. pr_numbers = []
  63. for line in lines:
  64. pr_number = _find_pr_number(line)
  65. if pr_number:
  66. pr_numbers.append(int(pr_number))
  67. # Sort the PR numbers
  68. print("PR numbers", pr_numbers)
  69. # Use Github API to fetch the
  70. g = Github(access_token)
  71. ray_repo = g.get_repo("ray-project/ray")
  72. logins = set()
  73. for num in tqdm(pr_numbers):
  74. try:
  75. logins.add(ray_repo.get_pull(num).user.login)
  76. except Exception as e:
  77. print(e)
  78. print()
  79. print("Here's the list of contributors")
  80. print("=" * 10)
  81. print()
  82. print("@" + ", @".join(logins))
  83. print()
  84. print("=" * 10)
  85. # Organize commits
  86. NO_CATEGORY = "[NO_CATEGORY]"
  87. def get_category(line):
  88. if line[0] == "[":
  89. return (line.split("]")[0].strip(" ") + "]").upper()
  90. else:
  91. return NO_CATEGORY
  92. commits = defaultdict(list)
  93. with open("commits.txt") as file:
  94. for line in file.readlines():
  95. commits[get_category(line)].append(line.strip())
  96. with open("commits.txt", "a") as file:
  97. for category, commit_msgs in commits.items():
  98. file.write("\n{}\n".format(category))
  99. for commit_msg in commit_msgs:
  100. file.write("{}\n".format(commit_msg))
  101. if __name__ == "__main__":
  102. run()