summaryrefslogtreecommitdiff
path: root/util/update_release_branch.py
diff options
context:
space:
mode:
Diffstat (limited to 'util/update_release_branch.py')
-rwxr-xr-xutil/update_release_branch.py354
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.**"
)
)