KAFKA-18942: Add reviewers to PR body with committer-tools (#19168)

Allow `reviewers.py` to set the "Reviewers:" line in a PR body.

Reviewers: Chia-Ping Tsai <chia7712@gmail.com>, David Arthur <mumrah@gmail.com>
This commit is contained in:
Ming-Yen Chung 2025-03-12 21:41:05 +08:00 committed by GitHub
parent c07c59ad24
commit d964574ab9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 53 additions and 8 deletions

View File

@ -46,11 +46,13 @@ See: https://cli.github.com/
brew install gh brew install gh
``` ```
## Find Reviewers ## Find Reviewers and Update to PR body
The reviewers.py script is used to simplify the process of producing our "Reviewers:" The reviewers.py script is used to simplify the process of producing our "Reviewers:"
Git trailer. It parses the Git log to gather a set of "Authors" and "Reviewers". Git trailer to PR body. It parses the Git log to gather a set of "Authors" and "Reviewers".
Some simple string prefix matching is done to find candidates. Some simple string prefix matching is done to find candidates.
After entering the pull request number, the script updates the "Reviewers:" trailer accordingly.
If the PR body already contains a "Reviewers:" trailer, the script replaces it with the updated list of reviewers.
Usage: Usage:

View File

@ -1,6 +1,10 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import json
import shlex
import subprocess
import tempfile
# #
# Licensed to the Apache Software Foundation (ASF) under one or more # Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with # contributor license agreements. See the NOTICE file distributed with
@ -35,6 +39,42 @@ def prompt_for_user():
return clean_input return clean_input
def update_trailers(body, trailer):
with tempfile.NamedTemporaryFile() as fp:
fp.write(body.encode())
fp.flush()
cmd = f"git interpret-trailers --if-exists replace --trailer '{trailer}' {fp.name} "
p = subprocess.run(shlex.split(cmd), capture_output=True, text=True)
fp.close()
return p.stdout
def append_message_to_pr_body(pr: int , message: str):
try:
pr_url = f"https://github.com/apache/kafka/pull/{pr}"
cmd_get_pr = f"gh pr view {pr_url} --json title,body"
result = subprocess.run(shlex.split(cmd_get_pr), capture_output=True, text=True, check=True)
current_pr_body = json.loads(result.stdout).get("body", {}).strip() + "\n"
pr_title = json.loads(result.stdout).get("title", {})
updated_pr_body = update_trailers(current_pr_body, message)
except subprocess.CalledProcessError as e:
print("Failed to retrieve PR body:", e.stderr)
return
print(f"""New PR body will be:\n\n---\n{updated_pr_body}---\n""")
choice = input(f'Update the body of "{pr_title}"? (y/n): ').strip().lower()
if choice in ['n', 'no']:
return
try:
cmd_edit_body = f"gh pr edit {pr_url} --body {shlex.quote(updated_pr_body)}"
subprocess.run(shlex.split(cmd_edit_body), check=True)
print("PR body updated successfully!")
except subprocess.CalledProcessError as e:
print("Failed to update PR body:", e.stderr)
if __name__ == "__main__": if __name__ == "__main__":
print("Utility to help generate 'Reviewers' string for Pull Requests. Use Ctrl+D or Ctrl+C to exit") print("Utility to help generate 'Reviewers' string for Pull Requests. Use Ctrl+D or Ctrl+C to exit")
@ -87,9 +127,12 @@ if __name__ == "__main__":
continue continue
if selected_reviewers: if selected_reviewers:
out = "\n\nReviewers: " reviewer_message = "Reviewers: "
out += ", ".join([f"{name} <{email}>" for name, email, _ in selected_reviewers]) reviewer_message += ", ".join([f"{name} <{email}>" for name, email, _ in selected_reviewers])
out += "\n" print(f"\n\n{reviewer_message}\n")
print(out)
try:
pr_number = int(input("\nPull Request (Ctrl+D or Ctrl+C to skip): "))
append_message_to_pr_body(pr_number, reviewer_message)
except (EOFError, KeyboardInterrupt):
exit(0)