in dev/bk-merge-pr3.py [0:0]
def main():
global original_head
if not GITHUB_OAUTH_KEY:
print("OAuth key is needed for merging bookkeeper pull requests.")
print("If environment variable 'GITHUB_OAUTH_KEY' is not defined,")
print("then requests will be unauthenticated.")
print("You can create an OAuth key at https://github.com/settings/tokens")
print("and set it to the environment variable 'GITHUB_OAUTH_KEY'.")
print("(This token only needs the 'public_repo' scope permissions)")
exit(-1)
# 0. get the current state so we can go back
original_head = get_current_branch()
# 1. retrieve milestones, labels, branches
milestones = get_milestones()
labels = get_all_labels()
branches = get_json("%s/branches" % GITHUB_API_BASE)
branch_names = list(filter(lambda x: x.startswith(RELEASE_BRANCH_PREFIX), [x['name'] for x in branches]))
# Assumes branch names can be sorted lexicographically
latest_branch = sorted(branch_names, reverse=True)[0]
# 2. retrieve the details for a given pull request
pr_num = input("Which pull request would you like to merge? (e.g. 34): ")
pr = get_json("%s/pulls/%s" % (GITHUB_API_BASE, pr_num))
pr_events = get_json("%s/issues/%s/events" % (GITHUB_API_BASE, pr_num))
pr_reviewers = get_reviewers(pr_num)
check_ci_status(pr)
url = pr["url"]
# 3. repair the title for commit message
pr_title = pr["title"]
commit_title = input("Commit title [%s]: " % pr_title)
if commit_title == "":
commit_title = pr_title
# Decide whether to use the modified title or not
modified_title, github_issue_ids = standardize_issue_ref(commit_title)
if modified_title != commit_title:
print("I've re-written the title as follows to match the standard format:")
print("Original: %s" % commit_title)
print("Modified: %s" % modified_title)
result = input("Would you like to use the modified title? (y/n): ")
if result.lower() == "y":
commit_title = modified_title
print("Using modified title:")
else:
print("Using original title:")
print(commit_title)
body = pr["body"]
modified_body = ""
for line in body.split('\n'):
if line.startswith('>'):
continue
modified_body = modified_body + line + "\n"
modified_body = modified_body[:-1]
if modified_body != body:
print("I've re-written the body as follows to match the standard formats:")
print("Original: ")
print(body)
print("Modified: ")
print(modified_body)
result = input("Would you like to use the modified body? (y/n): ")
if result.lower() == "y":
body = modified_body
print("Using modified body.")
else:
print("Using original body.")
target_ref = pr["base"]["ref"]
user_login = pr["user"]["login"]
base_ref = pr["head"]["ref"]
pr_repo_desc = "%s/%s" % (user_login, base_ref)
# append pr num to the github issues - we need to attach label and milestone to them
github_issue_ids.append(pr_num)
#
# 4. attach milestone, area, type and release to github issues
#
# get issue labels
issue_labels = get_github_issue_labels(pr_num)
# ask for fix milestone, area and type
fix_milestone, fix_milestone_number, fix_areas, fix_types = \
ask_updates_for_github_issues(milestones, labels, issue_labels, target_ref == "master")
# update issues with fix milestone, are and type
other_labels = list(filter(lambda x: not x.startswith("area"), issue_labels))
all_issue_labels = update_github_issues( \
github_issue_ids, \
fix_milestone_number, \
fix_milestone, \
fix_areas, \
fix_types, \
other_labels)
# add the pr author to the assignees
add_assignees_to_github_issues(github_issue_ids, [ user_login ])
if target_ref != "master":
branch_version = target_ref.split('-')[1]
# add releases
fix_releases = ask_release_for_github_issues(branch_version, labels)
if len(fix_releases) > 0:
all_issue_labels = add_release_to_github_issues(github_issue_ids, all_issue_labels, fix_releases[0])
#
# 5. Process the merge
#
# Merged pull requests don't appear as merged in the GitHub API;
# Instead, they're closed by asfgit.
merge_commits = \
[e for e in pr_events if e["actor"]["login"] == "asfgit" and e["event"] == "closed"]
if merge_commits:
merge_hash = merge_commits[0]["commit_id"]
message = get_json("%s/commits/%s" % (GITHUB_API_BASE, merge_hash))["commit"]["message"]
print("Pull request %s has already been merged, assuming you want to backport" % pr_num)
commit_is_downloaded = run_cmd(['git', 'rev-parse', '--quiet', '--verify',
"%s^{commit}" % merge_hash]).strip() != ""
if not commit_is_downloaded:
fail("Couldn't find any merge commit for #%s, you may need to update HEAD." % pr_num)
print("Found commit %s:\n%s" % (merge_hash, message))
cherry_pick(pr_num, merge_hash, ask_for_branch(latest_branch))
sys.exit(0)
if not bool(pr["mergeable"]):
msg = "Pull request %s is not mergeable in its current form.\n" % pr_num + \
"You may need to rebase the PR."
fail(msg)
print("\n=== Pull Request #%s ===" % pr_num)
print("PR title\t%s\nCommit title\t%s\nSource\t\t%s\nTarget\t\t%s\nURL\t\t%s" % (
pr_title, commit_title, pr_repo_desc, target_ref, url))
continue_maybe("Proceed with merging pull request #%s?" % pr_num)
merged_refs = [target_ref]
# proceed with the merge
merge_hash, merge_commit_log = merge_pr(pr_num, target_ref, commit_title, body, pr_reviewers, pr_repo_desc)
# once the pr is merged, refresh the local repo
run_cmd("git fetch %s" % PR_REMOTE_NAME)
pick_prompt = "Would you like to pick %s into another branch?" % merge_hash
while input("\n%s (y/n): " % pick_prompt).lower() == "y":
pick_ref = ask_for_branch(latest_branch)
branch_version = pick_ref.split('-')[1]
# add releases
fix_releases = ask_release_for_github_issues(branch_version, labels)
if len(fix_releases) > 0:
all_issue_labels = add_release_to_github_issues(github_issue_ids, all_issue_labels, fix_releases[0])
merged_refs = merged_refs + [cherry_pick(pr_num, merge_hash, pick_ref)]