summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew McRae <amcrae@google.com>2022-11-09 16:32:52 +1100
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-11-15 03:28:44 +0000
commitc4c6efecf1c8787befe7eb0aaaec59ff0f115e76 (patch)
tree693f941a573eb1fd97695a377104a85ecd46cfc6
parent34c2f4848f64615fd4c70fb22aaa66025f6b3666 (diff)
downloadchrome-ec-c4c6efecf1c8787befe7eb0aaaec59ff0f115e76.tar.gz
update_release_branch: Add support for Zephyr based boards
Add support for Zephyr based projects: - Add srcbase option for source directory base (requires SDK) - Add multiple repo handling - Use appropriate defaults for Zephyr - Use correct branch name and remote branch names - Skip repo if no changes (cmsis doesn't change much) BUG=b:257145337 TEST=Run with nissa firmware branch BRANCH=none Signed-off-by: Andrew McRae <amcrae@google.com> Change-Id: I7070afd2dca11b9afe0891900d1f209b749b3525 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4015604 Reviewed-by: Aseda Aboagye <aaboagye@chromium.org> Code-Coverage: Zoss <zoss-cl-coverage@prod.google.com>
-rwxr-xr-xutil/update_release_branch.py338
1 files changed, 222 insertions, 116 deletions
diff --git a/util/update_release_branch.py b/util/update_release_branch.py
index 0a871724fe..591c833ea1 100755
--- a/util/update_release_branch.py
+++ b/util/update_release_branch.py
@@ -137,6 +137,8 @@ def get_relevant_commits(head, merge_head, fmt, relevant_paths):
A tuple containing the arguments passed to the git log command and
stdout.
"""
+ if not relevant_paths:
+ return "", ""
if fmt:
cmd = [
"git",
@@ -159,6 +161,128 @@ def get_relevant_commits(head, merge_head, fmt, relevant_paths):
return "".join(proc.args), proc.stdout
+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:
+ # 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)
+
+
def main(argv):
"""Generates a merge commit from ToT to a desired release branch.
@@ -186,7 +310,11 @@ def main(argv):
parser.add_argument("--baseboard")
parser.add_argument("--board")
parser.add_argument(
- "release_branch", help=("The name of the target release" " branch")
+ "release_branch",
+ help=(
+ "The name of the target release branch, "
+ "without the trailing '-main'."
+ ),
)
parser.add_argument(
"--remote_prefix",
@@ -197,6 +325,11 @@ 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 "
@@ -213,7 +346,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",
@@ -221,6 +354,12 @@ 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:])
@@ -228,17 +367,24 @@ 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:
- board_dir = os.path.relpath("board/" + 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(os.path.realpath(board_dir))
boards = [opts.board]
else:
- boards = []
+ # With no board or baseboard, not sure whether this should proceed
+ raise Exception("no board or baseboard specified")
print("Gathering relevant paths...")
relevant_paths = []
@@ -247,10 +393,12 @@ def main(argv):
elif opts.board:
relevant_paths.append(board_dir)
- for board in boards:
- relevant_paths.append("board/" + board)
+ if not opts.zephyr:
+ 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:
@@ -260,17 +408,9 @@ 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:
@@ -291,112 +431,78 @@ def main(argv):
for path in prunelist:
print(" " + path)
- 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 ""
- ),
- )
- cros_main = opts.remote_prefix + "/" + "main"
- arglist = [
+ # 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",
- "merge",
- "--no-ff",
- "--no-commit",
- cros_main,
- "-s",
- opts.merge_strategy,
+ "checkout",
+ "-B",
+ opts.release_branch,
+ opts.remote_prefix + "/" + opts.release_branch,
]
- 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.",
+ merge_repo(
+ os.path.join(opts.srcbase, "src/third_party/zephyr/main"),
+ cros_main,
+ cmd_checkout,
+ strategy,
+ cmd,
+ [],
+ [],
+ )
+ # 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,
+ cmd_checkout,
+ strategy,
+ cmd,
+ [],
+ [],
)
-
- 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 to see if it's to your "
+ "Finished! **Please review the commit(s) to see if they're to your "
"liking.**"
)
)