diff options
Diffstat (limited to 'util/update_release_branch.py')
-rwxr-xr-x | util/update_release_branch.py | 354 |
1 files changed, 121 insertions, 233 deletions
diff --git a/util/update_release_branch.py b/util/update_release_branch.py index 939d572dc4..0a871724fe 100755 --- a/util/update_release_branch.py +++ b/util/update_release_branch.py @@ -42,11 +42,11 @@ def git_commit_msg(cros_main, branch, head, merge_head, rel_paths, cmd): A String containing the git commit message with the exception of the Signed-Off-By field and Change-ID field. """ - relevant_commits_cmd, relevant_commits, relevant_hdr = get_relevant_commits( + relevant_commits_cmd, relevant_commits = get_relevant_commits( head, merge_head, "--oneline", rel_paths ) - _, relevant_bugs, _ = get_relevant_commits(head, merge_head, "", rel_paths) + _, relevant_bugs = get_relevant_commits(head, merge_head, "", rel_paths) relevant_bugs = set(re.findall("BUG=(.*)", relevant_bugs)) # Filter out "none" from set of bugs filtered = [] @@ -65,7 +65,7 @@ Merge remote-tracking branch {CROS_MAIN} into {BRANCH} Generated by: {COMMAND_LINE} -{RELEVANT_COMMITS_HEADER} +Relevant changes: {RELEVANT_COMMITS_CMD} @@ -93,7 +93,6 @@ Force-Relevant-Builds: all BRANCH=branch, RELEVANT_COMMITS_CMD=relevant_commits_cmd, RELEVANT_COMMITS=relevant_commits, - RELEVANT_COMMITS_HEADER=relevant_hdr, BUG_FIELD=bug_field, COMMAND_LINE=cmd, ) @@ -136,10 +135,8 @@ def get_relevant_commits(head, merge_head, fmt, relevant_paths): Returns: A tuple containing the arguments passed to the git log command and - stdout, and the header for the message + stdout. """ - if not relevant_paths: - return "", "", "" if fmt: cmd = [ "git", @@ -159,129 +156,7 @@ def get_relevant_commits(head, merge_head, fmt, relevant_paths): proc = subprocess.run( cmd, stdout=subprocess.PIPE, encoding="utf-8", check=True, shell=True ) - return "".join(proc.args), proc.stdout, "Relevant changes:" - - -def merge_repo( - base, cros_main, cmd_checkout, strategy, cmd, prunelist, relevant_paths -): - """Merge changes from ToT into this repo's branch. - - For this repo, merge the changes from ToT to the branch set - in the merge command. - - Args: - base: String indicating the Source directory of repo. - cros_main: String indicating the origin branch name - cmd_checkout: String list containing the checkout command to use. - strategy: String list containing the merge strategy, - cmd: String containing the command line - prunelist: String list containing the files to remove. - relevant_paths: String containing all the relevant paths for this - particular baseboard or board. - """ - # Change directory to the repo being merged - print('Starting merge in "%s"' % base) - print('Checkout command: "%s"' % " ".join(cmd_checkout)) - os.chdir(base) - # Check if we are already in merge process - result = subprocess.run( - ["git", "rev-parse", "--quiet", "--verify", "MERGE_HEAD"], - stdout=subprocess.DEVNULL, - stderr=subprocess.DEVNULL, - check=False, - ) - - if result.returncode: - # Let's perform the merge - print("Updating remote...") - subprocess.run(["git", "remote", "update"], check=True) - subprocess.run(cmd_checkout, check=True) - cmd_merge = [ - "git", - "merge", - "--no-ff", - "--no-commit", - cros_main, - "-s", - ] - cmd_merge.extend(strategy) - print('Merge command: "%s"' % " ".join(cmd_merge)) - try: - subprocess.run(cmd_merge, check=True) - except subprocess.CalledProcessError: - # We've likely encountered a merge conflict due to new OWNERS file - # modifications. If we're removing the owners, we'll delete them. - if prunelist: - # Find the unmerged files - unmerged = ( - subprocess.run( - ["git", "diff", "--name-only", "--diff-filter=U"], - stdout=subprocess.PIPE, - encoding="utf-8", - check=True, - ) - .stdout.rstrip() - .split() - ) - - # Prune OWNERS files - for file in unmerged: - if file in prunelist: - subprocess.run(["git", "rm", file], check=False) - unmerged.remove(file) - - print("Removed non-root OWNERS files.") - if unmerged: - print( - "Unmerged files still exist! You need to manually resolve this." - ) - print("\n".join(unmerged)) - sys.exit(1) - else: - raise - else: - print( - "We have already started merge process.", - "Attempt to generate commit.", - ) - # Check whether any commit is needed. - changes = subprocess.run( - ["git", "status", "--porcelain"], - stdout=subprocess.PIPE, - encoding="utf-8", - check=True, - ).stdout.rstrip() - if not changes: - print("No changes have been found, skipping commit.") - return - - print("Generating commit message...") - branch = subprocess.run( - ["git", "rev-parse", "--abbrev-ref", "HEAD"], - stdout=subprocess.PIPE, - encoding="utf-8", - check=True, - ).stdout.rstrip() - head = subprocess.run( - ["git", "rev-parse", "--short", "HEAD"], - stdout=subprocess.PIPE, - encoding="utf-8", - check=True, - ).stdout.rstrip() - merge_head = subprocess.run( - ["git", "rev-parse", "--short", "MERGE_HEAD"], - stdout=subprocess.PIPE, - encoding="utf-8", - check=True, - ).stdout.rstrip() - - print("Typing as fast as I can...") - commit_msg = git_commit_msg( - cros_main, branch, head, merge_head, relevant_paths, cmd - ) - subprocess.run(["git", "commit", "--signoff", "-m", commit_msg], check=True) - subprocess.run(["git", "commit", "--amend"], check=True) + return "".join(proc.args), proc.stdout def main(argv): @@ -311,11 +186,7 @@ def main(argv): parser.add_argument("--baseboard") parser.add_argument("--board") parser.add_argument( - "release_branch", - help=( - "The name of the target release branch, " - "without the trailing '-main'." - ), + "release_branch", help=("The name of the target release" " branch") ) parser.add_argument( "--remote_prefix", @@ -326,11 +197,6 @@ def main(argv): default="cros", ) parser.add_argument( - "--srcbase", - help=("The base directory where the src tree exists."), - default="/mnt/host/source/", - ) - parser.add_argument( "--relevant_paths_file", help=( "A path to a text file which includes other " @@ -347,7 +213,7 @@ def main(argv): parser.add_argument( "--strategy_option", "-X", - help=("The strategy option for the chosen merge strategy"), + help=("The strategy option for the chosen merge " "strategy"), ) parser.add_argument( "--remove_owners", @@ -355,12 +221,6 @@ def main(argv): action=("store_true"), help=("Remove non-root OWNERS level files if present"), ) - parser.add_argument( - "--zephyr", - "-z", - action=("store_true"), - help=("If set, treat the board as a Zephyr based program"), - ) opts = parser.parse_args(argv[1:]) @@ -368,24 +228,17 @@ def main(argv): board_dir = "" if opts.baseboard: - # If a zephyr board, no baseboard allowed - if opts.zephyr: - raise Exception("--baseboard not allowed for Zephyr boards") # Dereference symlinks so "git log" works as expected. baseboard_dir = os.path.relpath("baseboard/" + opts.baseboard) baseboard_dir = os.path.relpath(os.path.realpath(baseboard_dir)) boards = get_relevant_boards(opts.baseboard) elif opts.board: - if opts.zephyr: - board_dir = os.path.relpath("zephyr/program/" + opts.board) - else: - board_dir = os.path.relpath("board/" + opts.board) + board_dir = os.path.relpath("board/" + opts.board) board_dir = os.path.relpath(os.path.realpath(board_dir)) boards = [opts.board] else: - # With no board or baseboard, not sure whether this should proceed - raise Exception("no board or baseboard specified") + boards = [] print("Gathering relevant paths...") relevant_paths = [] @@ -394,12 +247,10 @@ def main(argv): elif opts.board: relevant_paths.append(board_dir) - if not opts.zephyr: - for board in boards: - relevant_paths.append("board/" + board) + for board in boards: + relevant_paths.append("board/" + board) # Check for the existence of a file that has other paths of interest. - # Also check for 'relevant-paths.txt' in the board directory if opts.relevant_paths_file and os.path.exists(opts.relevant_paths_file): with open(opts.relevant_paths_file, "r") as relevant_paths_file: for line in relevant_paths_file: @@ -409,9 +260,17 @@ def main(argv): relevant_paths.append("util/getversion.sh") relevant_paths = " ".join(relevant_paths) + # Check if we are already in merge process + result = subprocess.run( + ["git", "rev-parse", "--quiet", "--verify", "MERGE_HEAD"], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + check=False, + ) + # Prune OWNERS files if desired - prunelist = [] if opts.remove_owners: + prunelist = [] for root, dirs, files in os.walk("."): for name in dirs: if "build" in name: @@ -432,83 +291,112 @@ def main(argv): for path in prunelist: print(" " + path) - # Create the merge and checkout commands to use. - cmd_checkout = [ - "git", - "checkout", - "-B", - opts.release_branch, - opts.remote_prefix + "/" + opts.release_branch, - ] - if opts.merge_strategy == "recursive" and not opts.strategy_option: - opts.strategy_option = "theirs" - print( - 'Using "%s" merge strategy' % opts.merge_strategy, - ( - "with strategy option '%s'" % opts.strategy_option - if opts.strategy_option - else "" - ), - ) - cros_main = opts.remote_prefix + "/" + "main" - strategy = [ - opts.merge_strategy, - ] - if opts.strategy_option: - strategy.append("-X" + opts.strategy_option) - cmd = " ".join(argv) - - # Merge each of the repos - merge_repo( - os.path.join(opts.srcbase, "src/platform/ec"), - cros_main, - cmd_checkout, - strategy, - cmd, - prunelist, - relevant_paths, - ) - if opts.zephyr: - # Strip off any trailing -main or -master from branch name - if opts.release_branch.endswith("-main"): - opts.release_branch = opts.release_branch[:-5] - if opts.release_branch.endswith("-master"): - opts.release_branch = opts.release_branch[:-7] - cmd_checkout = [ - "git", - "checkout", - "-B", - opts.release_branch, - opts.remote_prefix + "/" + opts.release_branch, - ] - prunelist = [] - if opts.remove_owners: - # Remove the top level OWNERS file from the list - # to avoid any conflict with the modified branch file. - prunelist.append("OWNERS") - merge_repo( - os.path.join(opts.srcbase, "src/third_party/zephyr/main"), - cros_main, - cmd_checkout, - strategy, - cmd, - prunelist, - [], + if result.returncode: + # Let's perform the merge + print("Updating remote...") + subprocess.run(["git", "remote", "update"], check=True) + subprocess.run( + [ + "git", + "checkout", + "-B", + opts.release_branch, + opts.remote_prefix + "/" + opts.release_branch, + ], + check=True, + ) + print("Attempting git merge...") + if opts.merge_strategy == "recursive" and not opts.strategy_option: + opts.strategy_option = "theirs" + print( + 'Using "%s" merge strategy' % opts.merge_strategy, + ( + "with strategy option '%s'" % opts.strategy_option + if opts.strategy_option + else "" + ), ) - # cmsis repo has different remote - cros_main = opts.remote_prefix + "/" + "chromeos-main" - merge_repo( - os.path.join(opts.srcbase, "src/third_party/zephyr/cmsis"), + cros_main = opts.remote_prefix + "/" + "main" + arglist = [ + "git", + "merge", + "--no-ff", + "--no-commit", cros_main, - cmd_checkout, - strategy, - cmd, - prunelist, - [], + "-s", + opts.merge_strategy, + ] + if opts.strategy_option: + arglist.append("-X" + opts.strategy_option) + try: + subprocess.run(arglist, check=True) + except: + # We've likely encountered a merge conflict due to new OWNERS file + # modifications. If we're removing the owners, we'll delete them. + if opts.remove_owners and prunelist: + # Find the unmerged files + unmerged = ( + subprocess.run( + ["git", "diff", "--name-only", "--diff-filter=U"], + stdout=subprocess.PIPE, + encoding="utf-8", + check=True, + ) + .stdout.rstrip() + .split() + ) + + # Prune OWNERS files + for file in unmerged: + if file in prunelist: + subprocess.run(["git", "rm", file], check=False) + unmerged.remove(file) + + print("Removed non-root OWNERS files.") + if unmerged: + print( + "Unmerged files still exist! You need to manually resolve this." + ) + print("\n".join(unmerged)) + sys.exit(1) + else: + raise + else: + print( + "We have already started merge process.", + "Attempt to generate commit.", ) + + print("Generating commit message...") + branch = subprocess.run( + ["git", "rev-parse", "--abbrev-ref", "HEAD"], + stdout=subprocess.PIPE, + encoding="utf-8", + check=True, + ).stdout.rstrip() + head = subprocess.run( + ["git", "rev-parse", "--short", "HEAD"], + stdout=subprocess.PIPE, + encoding="utf-8", + check=True, + ).stdout.rstrip() + merge_head = subprocess.run( + ["git", "rev-parse", "--short", "MERGE_HEAD"], + stdout=subprocess.PIPE, + encoding="utf-8", + check=True, + ).stdout.rstrip() + + cmd = " ".join(argv) + print("Typing as fast as I can...") + commit_msg = git_commit_msg( + cros_main, branch, head, merge_head, relevant_paths, cmd + ) + subprocess.run(["git", "commit", "--signoff", "-m", commit_msg], check=True) + subprocess.run(["git", "commit", "--amend"], check=True) print( ( - "Finished! **Please review the commit(s) to see if they're to your " + "Finished! **Please review the commit to see if it's to your " "liking.**" ) ) |