Commit 06bfc842 authored by hablich's avatar hablich Committed by Commit bot

[Release] Update merge script to leverage auto-tag bot

The auto-tag bot removes the need to handle version changes
in each merge individually. As a result this 'feature' is
removed.

BUG=v8:4408
R=machenbach@chromium.org
LOG=N
NOTRY=true

Review-Url: https://codereview.chromium.org/1398033003
Cr-Commit-Position: refs/heads/master@{#37972}
parent ba092fb0
......@@ -242,6 +242,10 @@ class GitRecipesMixin(object):
self.Git(
"cl land -f --bypass-hooks", retry_on=lambda x: x is None, **kwargs)
def GitCLAddComment(self, message, **kwargs):
args = ["cl", "comments", "-a", Quoted(message)]
self.Git(MakeArgs(args), **kwargs)
def GitDiff(self, loc1, loc2, **kwargs):
return self.Git(MakeArgs(["diff", loc1, loc2]), **kwargs)
......
......@@ -47,10 +47,8 @@ class Preparation(Step):
open(self.Config("ALREADY_MERGING_SENTINEL_FILE"), "a").close()
self.InitialEnvironmentChecks(self.default_cwd)
if self._options.branch:
self["merge_to_branch"] = self._options.branch
else: # pragma: no cover
self.Die("Please specify a branch to merge to")
self["merge_to_branch"] = self._options.branch
self.CommonPrepare()
self.PrepareBranch()
......@@ -74,7 +72,7 @@ class SearchArchitecturePorts(Step):
for revision in self["full_revision_list"]:
# Search for commits which matches the "Port XXX" pattern.
git_hashes = self.GitLog(reverse=True, format="%H",
grep="Port %s" % revision,
grep="^[Pp]ort %s" % revision,
branch=self.vc.RemoteMasterBranch())
for git_hash in git_hashes.splitlines():
revision_title = self.GitLog(n=1, format="%s", git_hash=git_hash)
......@@ -99,6 +97,12 @@ class SearchArchitecturePorts(Step):
class CreateCommitMessage(Step):
MESSAGE = "Create commit message."
def _create_commit_description(self, commit_hash):
patch_merge_desc = self.GitLog(n=1, format="%s", git_hash=commit_hash)
description = "Merged: " + patch_merge_desc + "\n"
description += "Revision: " + commit_hash + "\n\n"
return description
def RunStep(self):
# Stringify: ["abcde", "12345"] -> "abcde, 12345"
......@@ -107,17 +111,23 @@ class CreateCommitMessage(Step):
if not self["revision_list"]: # pragma: no cover
self.Die("Revision list is empty.")
action_text = "Merged %s"
msg_pieces = []
# The commit message title is added below after the version is specified.
msg_pieces = [
"\n".join(action_text % s for s in self["full_revision_list"]),
]
msg_pieces.append("\n\n")
if len(self["full_revision_list"]) > 1:
self["commit_title"] = "Merged: Squashed multiple commits."
for commit_hash in self["full_revision_list"]:
msg_pieces.append(self._create_commit_description(commit_hash))
else:
commit_hash = self["full_revision_list"][0]
full_description = self._create_commit_description(commit_hash).split("\n")
for commit_hash in self["full_revision_list"]:
patch_merge_desc = self.GitLog(n=1, format="%s", git_hash=commit_hash)
msg_pieces.append("%s\n\n" % patch_merge_desc)
#Truncate title because of code review tool
title = full_description[0]
if len(title) > 100:
title = title[:96] + " ..."
self["commit_title"] = title
msg_pieces.append(full_description[1] + "\n\n")
bugs = []
for commit_hash in self["full_revision_list"]:
......@@ -128,6 +138,8 @@ class CreateCommitMessage(Step):
if bug_aggregate:
msg_pieces.append("BUG=%s\nLOG=N\n" % bug_aggregate)
msg_pieces.append("NOTRY=true\nNOPRESUBMIT=true\nNOTREECHECKS=true\n")
self["new_commit_msg"] = "".join(msg_pieces)
......@@ -144,49 +156,26 @@ class ApplyPatches(Step):
if self._options.patch:
self.ApplyPatch(self._options.patch)
class PrepareVersion(Step):
MESSAGE = "Prepare version file."
def RunStep(self):
# This is used to calculate the patch level increment.
self.ReadAndPersistVersion()
class IncrementVersion(Step):
MESSAGE = "Increment version number."
def RunStep(self):
new_patch = str(int(self["patch"]) + 1)
if self.Confirm("Automatically increment V8_PATCH_LEVEL? (Saying 'n' will "
"fire up your EDITOR on %s so you can make arbitrary "
"changes. When you're done, save the file and exit your "
"EDITOR.)" % VERSION_FILE):
text = FileToText(os.path.join(self.default_cwd, VERSION_FILE))
text = MSub(r"(?<=#define V8_PATCH_LEVEL)(?P<space>\s+)\d*$",
r"\g<space>%s" % new_patch,
text)
TextToFile(text, os.path.join(self.default_cwd, VERSION_FILE))
else:
self.Editor(os.path.join(self.default_cwd, VERSION_FILE))
self.ReadAndPersistVersion("new_")
self["version"] = "%s.%s.%s.%s" % (self["new_major"],
self["new_minor"],
self["new_build"],
self["new_patch"])
class CommitLocal(Step):
MESSAGE = "Commit to local branch."
def RunStep(self):
# Add a commit message title.
self["commit_title"] = "Version %s (cherry-pick)" % self["version"]
self["new_commit_msg"] = "%s\n\n%s" % (self["commit_title"],
self["new_commit_msg"])
TextToFile(self["new_commit_msg"], self.Config("COMMITMSG_FILE"))
self.GitCommit(file_name=self.Config("COMMITMSG_FILE"))
class AddInformationalComment(Step):
MESSAGE = 'Show additional information.'
def RunStep(self):
message = ("NOTE: This script will no longer automatically "
"update include/v8-version.h "
"and create a tag. This is done automatically by the autotag bot. "
"Please call the merge_to_branch.py with --help for more information.")
self.GitCLAddComment(message)
class CommitRepository(Step):
MESSAGE = "Commit to the repository."
......@@ -197,24 +186,12 @@ class CommitRepository(Step):
self.GitPresubmit()
self.vc.CLLand()
class TagRevision(Step):
MESSAGE = "Create the tag."
def RunStep(self):
print "Creating tag %s" % self["version"]
self.vc.Tag(self["version"],
self.vc.RemoteBranch(self["merge_to_branch"]),
self["commit_title"])
class CleanUp(Step):
MESSAGE = "Cleanup."
def RunStep(self):
self.CommonCleanup()
print "*** SUMMARY ***"
print "version: %s" % self["version"]
print "branch: %s" % self["merge_to_branch"]
if self["revision_list"]:
print "patches: %s" % self["revision_list"]
......@@ -223,7 +200,9 @@ class CleanUp(Step):
class MergeToBranch(ScriptsBase):
def _Description(self):
return ("Performs the necessary steps to merge revisions from "
"master to other branches, including candidates.")
"master to release branches like 4.5. This script does not "
"version the commit. See http://goo.gl/9ke2Vw for more "
"information.")
def _PrepareOptions(self, parser):
group = parser.add_mutually_exclusive_group(required=True)
......@@ -250,6 +229,11 @@ class MergeToBranch(ScriptsBase):
# CC ulan to make sure that fixes are merged to Google3.
options.cc = "ulan@chromium.org"
if len(options.branch.split('.')) > 2:
print ("This script does not support merging to roll branches. "
"Please use tools/release/roll_merge.py for this use case.")
return False
# Make sure to use git hashes in the new workflows.
for revision in options.revisions:
if (IsSvnNumber(revision) or
......@@ -276,12 +260,10 @@ class MergeToBranch(ScriptsBase):
SearchArchitecturePorts,
CreateCommitMessage,
ApplyPatches,
PrepareVersion,
IncrementVersion,
CommitLocal,
UploadStep,
AddInformationalComment,
CommitRepository,
TagRevision,
CleanUp,
]
......
#!/usr/bin/env python
# Copyright 2014 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import argparse
from collections import OrderedDict
import sys
from common_includes import *
def IsSvnNumber(rev):
return rev.isdigit() and len(rev) < 8
class Preparation(Step):
MESSAGE = "Preparation."
def RunStep(self):
if os.path.exists(self.Config("ALREADY_MERGING_SENTINEL_FILE")):
if self._options.force:
os.remove(self.Config("ALREADY_MERGING_SENTINEL_FILE"))
elif self._options.step == 0: # pragma: no cover
self.Die("A merge is already in progress")
open(self.Config("ALREADY_MERGING_SENTINEL_FILE"), "a").close()
self.InitialEnvironmentChecks(self.default_cwd)
if self._options.branch:
self["merge_to_branch"] = self._options.branch
else: # pragma: no cover
self.Die("Please specify a branch to merge to")
self.CommonPrepare()
self.PrepareBranch()
class CreateBranch(Step):
MESSAGE = "Create a fresh branch for the patch."
def RunStep(self):
self.GitCreateBranch(self.Config("BRANCHNAME"),
self.vc.RemoteBranch(self["merge_to_branch"]))
class SearchArchitecturePorts(Step):
MESSAGE = "Search for corresponding architecture ports."
def RunStep(self):
self["full_revision_list"] = list(OrderedDict.fromkeys(
self._options.revisions))
port_revision_list = []
for revision in self["full_revision_list"]:
# Search for commits which matches the "Port XXX" pattern.
git_hashes = self.GitLog(reverse=True, format="%H",
grep="Port %s" % revision,
branch=self.vc.RemoteMasterBranch())
for git_hash in git_hashes.splitlines():
revision_title = self.GitLog(n=1, format="%s", git_hash=git_hash)
# Is this revision included in the original revision list?
if git_hash in self["full_revision_list"]:
print("Found port of %s -> %s (already included): %s"
% (revision, git_hash, revision_title))
else:
print("Found port of %s -> %s: %s"
% (revision, git_hash, revision_title))
port_revision_list.append(git_hash)
# Do we find any port?
if len(port_revision_list) > 0:
if self.Confirm("Automatically add corresponding ports (%s)?"
% ", ".join(port_revision_list)):
#: 'y': Add ports to revision list.
self["full_revision_list"].extend(port_revision_list)
class CreateCommitMessage(Step):
MESSAGE = "Create commit message."
def RunStep(self):
# Stringify: ["abcde", "12345"] -> "abcde, 12345"
self["revision_list"] = ", ".join(self["full_revision_list"])
if not self["revision_list"]: # pragma: no cover
self.Die("Revision list is empty.")
action_text = "Merged %s"
# The commit message title is added below after the version is specified.
msg_pieces = [
"\n".join(action_text % s for s in self["full_revision_list"]),
]
msg_pieces.append("\n\n")
for commit_hash in self["full_revision_list"]:
patch_merge_desc = self.GitLog(n=1, format="%s", git_hash=commit_hash)
msg_pieces.append("%s\n\n" % patch_merge_desc)
bugs = []
for commit_hash in self["full_revision_list"]:
msg = self.GitLog(n=1, git_hash=commit_hash)
for bug in re.findall(r"^[ \t]*BUG[ \t]*=[ \t]*(.*?)[ \t]*$", msg, re.M):
bugs.extend(s.strip() for s in bug.split(","))
bug_aggregate = ",".join(sorted(filter(lambda s: s and s != "none", bugs)))
if bug_aggregate:
msg_pieces.append("BUG=%s\nLOG=N\n" % bug_aggregate)
self["new_commit_msg"] = "".join(msg_pieces)
class ApplyPatches(Step):
MESSAGE = "Apply patches for selected revisions."
def RunStep(self):
for commit_hash in self["full_revision_list"]:
print("Applying patch for %s to %s..."
% (commit_hash, self["merge_to_branch"]))
patch = self.GitGetPatch(commit_hash)
TextToFile(patch, self.Config("TEMPORARY_PATCH_FILE"))
self.ApplyPatch(self.Config("TEMPORARY_PATCH_FILE"))
if self._options.patch:
self.ApplyPatch(self._options.patch)
class PrepareVersion(Step):
MESSAGE = "Prepare version file."
def RunStep(self):
# This is used to calculate the patch level increment.
self.ReadAndPersistVersion()
class IncrementVersion(Step):
MESSAGE = "Increment version number."
def RunStep(self):
new_patch = str(int(self["patch"]) + 1)
if self.Confirm("Automatically increment V8_PATCH_LEVEL? (Saying 'n' will "
"fire up your EDITOR on %s so you can make arbitrary "
"changes. When you're done, save the file and exit your "
"EDITOR.)" % VERSION_FILE):
text = FileToText(os.path.join(self.default_cwd, VERSION_FILE))
text = MSub(r"(?<=#define V8_PATCH_LEVEL)(?P<space>\s+)\d*$",
r"\g<space>%s" % new_patch,
text)
TextToFile(text, os.path.join(self.default_cwd, VERSION_FILE))
else:
self.Editor(os.path.join(self.default_cwd, VERSION_FILE))
self.ReadAndPersistVersion("new_")
self["version"] = "%s.%s.%s.%s" % (self["new_major"],
self["new_minor"],
self["new_build"],
self["new_patch"])
class CommitLocal(Step):
MESSAGE = "Commit to local branch."
def RunStep(self):
# Add a commit message title.
self["commit_title"] = "Version %s (cherry-pick)" % self["version"]
self["new_commit_msg"] = "%s\n\n%s" % (self["commit_title"],
self["new_commit_msg"])
TextToFile(self["new_commit_msg"], self.Config("COMMITMSG_FILE"))
self.GitCommit(file_name=self.Config("COMMITMSG_FILE"))
class CommitRepository(Step):
MESSAGE = "Commit to the repository."
def RunStep(self):
self.GitCheckout(self.Config("BRANCHNAME"))
self.WaitForLGTM()
self.GitPresubmit()
self.vc.CLLand()
class TagRevision(Step):
MESSAGE = "Create the tag."
def RunStep(self):
print "Creating tag %s" % self["version"]
self.vc.Tag(self["version"],
self.vc.RemoteBranch(self["merge_to_branch"]),
self["commit_title"])
class CleanUp(Step):
MESSAGE = "Cleanup."
def RunStep(self):
self.CommonCleanup()
print "*** SUMMARY ***"
print "version: %s" % self["version"]
print "branch: %s" % self["merge_to_branch"]
if self["revision_list"]:
print "patches: %s" % self["revision_list"]
class RollMerge(ScriptsBase):
def _Description(self):
return ("Performs the necessary steps to merge revisions from "
"master to other branches, including candidates and roll branches.")
def _PrepareOptions(self, parser):
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("--branch", help="The branch to merge to.")
parser.add_argument("revisions", nargs="*",
help="The revisions to merge.")
parser.add_argument("-f", "--force",
help="Delete sentinel file.",
default=False, action="store_true")
parser.add_argument("-m", "--message",
help="A commit message for the patch.")
parser.add_argument("-p", "--patch",
help="A patch file to apply as part of the merge.")
def _ProcessOptions(self, options):
if len(options.revisions) < 1:
if not options.patch:
print "Either a patch file or revision numbers must be specified"
return False
if not options.message:
print "You must specify a merge comment if no patches are specified"
return False
options.bypass_upload_hooks = True
# CC ulan to make sure that fixes are merged to Google3.
options.cc = "ulan@chromium.org"
# Make sure to use git hashes in the new workflows.
for revision in options.revisions:
if (IsSvnNumber(revision) or
(revision[0:1] == "r" and IsSvnNumber(revision[1:]))):
print "Please provide full git hashes of the patches to merge."
print "Got: %s" % revision
return False
return True
def _Config(self):
return {
"BRANCHNAME": "prepare-merge",
"PERSISTFILE_BASENAME": "/tmp/v8-merge-to-branch-tempfile",
"ALREADY_MERGING_SENTINEL_FILE":
"/tmp/v8-merge-to-branch-tempfile-already-merging",
"TEMPORARY_PATCH_FILE": "/tmp/v8-prepare-merge-tempfile-temporary-patch",
"COMMITMSG_FILE": "/tmp/v8-prepare-merge-tempfile-commitmsg",
}
def _Steps(self):
return [
Preparation,
CreateBranch,
SearchArchitecturePorts,
CreateCommitMessage,
ApplyPatches,
PrepareVersion,
IncrementVersion,
CommitLocal,
UploadStep,
CommitRepository,
TagRevision,
CleanUp,
]
if __name__ == "__main__": # pragma: no cover
sys.exit(RollMerge().Run())
......@@ -40,13 +40,14 @@ from common_includes import *
import create_release
from create_release import CreateRelease
import merge_to_branch
from merge_to_branch import *
from merge_to_branch import MergeToBranch
import push_to_candidates
from push_to_candidates import *
import releases
from releases import Releases
from auto_tag import AutoTag
import roll_merge
from roll_merge import RollMerge
TEST_CONFIG = {
"DEFAULT_CWD": None,
......@@ -528,7 +529,7 @@ class ScriptTest(unittest.TestCase):
self._state["version"] = "tag_name"
self._state["commit_title"] = "Title"
self.assertRaises(Exception,
lambda: self.RunStep(MergeToBranch, TagRevision, args))
lambda: self.RunStep(RollMerge, TagRevision, args))
def testReadAndPersistVersion(self):
self.WriteFakeVersionFile(build=5)
......@@ -1175,7 +1176,7 @@ deps = {
self.assertEquals("abc123", state["candidate"])
def testMergeToBranch(self):
def testRollMerge(self):
TEST_CONFIG["ALREADY_MERGING_SENTINEL_FILE"] = self.MakeEmptyTempFile()
TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
self.WriteFakeVersionFile(build=5)
......@@ -1299,6 +1300,377 @@ LOG=N
Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
])
# ab12345 and ab34567 are patches. ab23456 (included) and ab45678 are the
# MIPS ports of ab12345. ab56789 is the MIPS port of ab34567.
args = ["-f", "-p", extra_patch, "--branch", "candidates",
"ab12345", "ab23456", "ab34567"]
# The first run of the script stops because of git being down.
self.assertRaises(GitFailedException,
lambda: RollMerge(TEST_CONFIG, self).Run(args))
# Test that state recovery after restarting the script works.
args += ["-s", "4"]
RollMerge(TEST_CONFIG, self).Run(args)
def testReleases(self):
c_hash1_commit_log = """Update V8 to Version 4.2.71.
Cr-Commit-Position: refs/heads/master@{#5678}
"""
c_hash2_commit_log = """Revert something.
BUG=12345
Reason:
> Some reason.
> Cr-Commit-Position: refs/heads/master@{#12345}
> git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12345 003-1c4
Review URL: https://codereview.chromium.org/12345
Cr-Commit-Position: refs/heads/master@{#4567}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4567 0039-1c4b
"""
c_hash3_commit_log = """Simple.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3456 0039-1c4b
"""
c_hash_234_commit_log = """Version 3.3.1.1 (cherry-pick).
Merged abc12.
Review URL: fake.com
Cr-Commit-Position: refs/heads/candidates@{#234}
"""
c_hash_123_commit_log = """Version 3.3.1.0
git-svn-id: googlecode@123 0039-1c4b
"""
c_hash_345_commit_log = """Version 3.4.0.
Cr-Commit-Position: refs/heads/candidates@{#345}
"""
c_hash_456_commit_log = """Version 4.2.71.
Cr-Commit-Position: refs/heads/4.2.71@{#1}
"""
c_deps = "Line\n \"v8_revision\": \"%s\",\n line\n"
json_output = self.MakeEmptyTempFile()
csv_output = self.MakeEmptyTempFile()
self.WriteFakeVersionFile()
TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory()
chrome_dir = TEST_CONFIG["CHROMIUM"]
chrome_v8_dir = os.path.join(chrome_dir, "v8")
os.makedirs(chrome_v8_dir)
def ResetVersion(major, minor, build, patch=0):
return lambda: self.WriteFakeVersionFile(major=major,
minor=minor,
build=build,
patch=patch)
self.Expect([
Cmd("git status -s -uno", ""),
Cmd("git checkout -f origin/master", ""),
Cmd("git fetch", ""),
Cmd("git branch", " branch1\n* branch2\n"),
Cmd("git new-branch %s" % TEST_CONFIG["BRANCHNAME"], ""),
Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
Cmd("git rev-list --max-age=395200 --tags",
"bad_tag\nhash_234\nhash_123\nhash_345\nhash_456\n"),
Cmd("git describe --tags bad_tag", "3.23.42-1-deadbeef"),
Cmd("git describe --tags hash_234", "3.3.1.1"),
Cmd("git describe --tags hash_123", "3.21.2"),
Cmd("git describe --tags hash_345", "3.22.3"),
Cmd("git describe --tags hash_456", "4.2.71"),
Cmd("git diff --name-only hash_234 hash_234^", VERSION_FILE),
Cmd("git checkout -f hash_234 -- %s" % VERSION_FILE, "",
cb=ResetVersion(3, 3, 1, 1)),
Cmd("git branch -r --contains hash_234", " branch-heads/3.3\n"),
Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log),
Cmd("git log -1 --format=%s hash_234", ""),
Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log),
Cmd("git log -1 --format=%ci hash_234", "18:15"),
Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
cb=ResetVersion(3, 22, 5)),
Cmd("git diff --name-only hash_123 hash_123^", VERSION_FILE),
Cmd("git checkout -f hash_123 -- %s" % VERSION_FILE, "",
cb=ResetVersion(3, 21, 2)),
Cmd("git branch -r --contains hash_123", " branch-heads/3.21\n"),
Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log),
Cmd("git log -1 --format=%s hash_123", ""),
Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log),
Cmd("git log -1 --format=%ci hash_123", "03:15"),
Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
cb=ResetVersion(3, 22, 5)),
Cmd("git diff --name-only hash_345 hash_345^", VERSION_FILE),
Cmd("git checkout -f hash_345 -- %s" % VERSION_FILE, "",
cb=ResetVersion(3, 22, 3)),
Cmd("git branch -r --contains hash_345", " origin/candidates\n"),
Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log),
Cmd("git log -1 --format=%s hash_345", ""),
Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log),
Cmd("git log -1 --format=%ci hash_345", ""),
Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
cb=ResetVersion(3, 22, 5)),
Cmd("git diff --name-only hash_456 hash_456^", VERSION_FILE),
Cmd("git checkout -f hash_456 -- %s" % VERSION_FILE, "",
cb=ResetVersion(4, 2, 71)),
Cmd("git branch -r --contains hash_456", " origin/4.2.71\n"),
Cmd("git log -1 --format=%B hash_456", c_hash_456_commit_log),
Cmd("git log -1 --format=%H 4.2.71", "hash_456"),
Cmd("git log -1 --format=%s hash_456", "Version 4.2.71"),
Cmd("git log -1 --format=%H hash_456^", "master_456"),
Cmd("git log -1 --format=%B master_456",
"Cr-Commit-Position: refs/heads/master@{#456}"),
Cmd("git log -1 --format=%B hash_456", c_hash_456_commit_log),
Cmd("git log -1 --format=%ci hash_456", "02:15"),
Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
cb=ResetVersion(3, 22, 5)),
Cmd("git fetch origin +refs/heads/*:refs/remotes/origin/* "
"+refs/branch-heads/*:refs/remotes/branch-heads/*", "",
cwd=chrome_dir),
Cmd("git fetch origin", "", cwd=chrome_v8_dir),
Cmd("git log --format=%H --grep=\"V8\" origin/master -- DEPS",
"c_hash1\nc_hash2\nc_hash3\n",
cwd=chrome_dir),
Cmd("git show c_hash1:DEPS", c_deps % "hash_456", cwd=chrome_dir),
Cmd("git log -1 --format=%B c_hash1", c_hash1_commit_log,
cwd=chrome_dir),
Cmd("git show c_hash2:DEPS", c_deps % "hash_345", cwd=chrome_dir),
Cmd("git log -1 --format=%B c_hash2", c_hash2_commit_log,
cwd=chrome_dir),
Cmd("git show c_hash3:DEPS", c_deps % "deadbeef", cwd=chrome_dir),
Cmd("git log -1 --format=%B c_hash3", c_hash3_commit_log,
cwd=chrome_dir),
Cmd("git branch -r", " weird/123\n branch-heads/7\n", cwd=chrome_dir),
Cmd("git show refs/branch-heads/7:DEPS", c_deps % "hash_345",
cwd=chrome_dir),
URL("http://omahaproxy.appspot.com/all.json", """[{
"os": "win",
"versions": [{
"version": "2.2.2.2",
"v8_version": "22.2.2.2",
"current_reldate": "04/09/15",
"os": "win",
"channel": "canary",
"previous_version": "1.1.1.0"
}]
}]"""),
URL("http://omahaproxy.appspot.com/v8.json?version=1.1.1.0", """{
"chromium_version": "1.1.1.0",
"v8_version": "11.1.1.0"
}"""),
Cmd("git rev-list -1 11.1.1", "v8_previous_version_hash"),
Cmd("git rev-list -1 22.2.2.2", "v8_version_hash"),
Cmd("git checkout -f origin/master", ""),
Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], "")
])
args = ["-c", TEST_CONFIG["CHROMIUM"],
"--json", json_output,
"--csv", csv_output,
"--max-releases", "1"]
Releases(TEST_CONFIG, self).Run(args)
# Check expected output.
csv = ("4.2.71,4.2.71,1,5678,\r\n"
"3.22.3,candidates,345,4567:5677,\r\n"
"3.21.2,3.21,123,,\r\n"
"3.3.1.1,3.3,234,,abc12\r\n")
self.assertEquals(csv, FileToText(csv_output))
expected_json = {"chrome_releases":{
"canaries": [
{
"chrome_version": "2.2.2.2",
"os": "win",
"release_date": "04/09/15",
"v8_version": "22.2.2.2",
"v8_version_hash": "v8_version_hash",
"v8_previous_version": "11.1.1.0",
"v8_previous_version_hash": "v8_previous_version_hash"
}]},
"releases":[
{
"revision": "1",
"revision_git": "hash_456",
"master_position": "456",
"master_hash": "master_456",
"patches_merged": "",
"version": "4.2.71",
"chromium_revision": "5678",
"branch": "4.2.71",
"review_link": "",
"date": "02:15",
"chromium_branch": "",
# FIXME(machenbach): Fix revisions link for git.
"revision_link": "https://code.google.com/p/v8/source/detail?r=1",
},
{
"revision": "345",
"revision_git": "hash_345",
"master_position": "",
"master_hash": "",
"patches_merged": "",
"version": "3.22.3",
"chromium_revision": "4567:5677",
"branch": "candidates",
"review_link": "",
"date": "",
"chromium_branch": "7",
"revision_link": "https://code.google.com/p/v8/source/detail?r=345",
},
{
"revision": "123",
"revision_git": "hash_123",
"patches_merged": "",
"master_position": "",
"master_hash": "",
"version": "3.21.2",
"chromium_revision": "",
"branch": "3.21",
"review_link": "",
"date": "03:15",
"chromium_branch": "",
"revision_link": "https://code.google.com/p/v8/source/detail?r=123",
},
{
"revision": "234",
"revision_git": "hash_234",
"patches_merged": "abc12",
"master_position": "",
"master_hash": "",
"version": "3.3.1.1",
"chromium_revision": "",
"branch": "3.3",
"review_link": "fake.com",
"date": "18:15",
"chromium_branch": "",
"revision_link": "https://code.google.com/p/v8/source/detail?r=234",
},],
}
self.assertEquals(expected_json, json.loads(FileToText(json_output)))
def testMergeToBranch(self):
TEST_CONFIG["ALREADY_MERGING_SENTINEL_FILE"] = self.MakeEmptyTempFile()
TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
self.WriteFakeVersionFile(build=5)
os.environ["EDITOR"] = "vi"
extra_patch = self.MakeEmptyTempFile()
def VerifyPatch(patch):
return lambda: self.assertEquals(patch,
FileToText(TEST_CONFIG["TEMPORARY_PATCH_FILE"]))
info_msg = ("NOTE: This script will no longer automatically "
"update include/v8-version.h "
"and create a tag. This is done automatically by the autotag bot. "
"Please call the merge_to_branch.py with --help for more information.")
msg = """Merged: Squashed multiple commits.
Merged: Title4
Revision: ab12345
Merged: Title2
Revision: ab23456
Merged: Title3
Revision: ab34567
Merged: Title1
Revision: ab45678
Merged: Revert \"Something\"
Revision: ab56789
BUG=123,234,345,456,567,v8:123
LOG=N
NOTRY=true
NOPRESUBMIT=true
NOTREECHECKS=true
"""
def VerifyLand():
commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"])
self.assertEquals(msg, commit)
self.Expect([
Cmd("git status -s -uno", ""),
Cmd("git checkout -f origin/master", ""),
Cmd("git fetch", ""),
Cmd("git branch", " branch1\n* branch2\n"),
Cmd("git new-branch %s --upstream refs/remotes/origin/candidates" %
TEST_CONFIG["BRANCHNAME"], ""),
Cmd(("git log --format=%H --grep=\"^[Pp]ort ab12345\" "
"--reverse origin/master"),
"ab45678\nab23456"),
Cmd("git log -1 --format=%s ab45678", "Title1"),
Cmd("git log -1 --format=%s ab23456", "Title2"),
Cmd(("git log --format=%H --grep=\"^[Pp]ort ab23456\" "
"--reverse origin/master"),
""),
Cmd(("git log --format=%H --grep=\"^[Pp]ort ab34567\" "
"--reverse origin/master"),
"ab56789"),
Cmd("git log -1 --format=%s ab56789", "Title3"),
RL("Y"), # Automatically add corresponding ports (ab34567, ab56789)?
# Simulate git being down which stops the script.
Cmd("git log -1 --format=%s ab12345", None),
# Restart script in the failing step.
Cmd("git log -1 --format=%s ab12345", "Title4"),
Cmd("git log -1 --format=%s ab23456", "Title2"),
Cmd("git log -1 --format=%s ab34567", "Title3"),
Cmd("git log -1 --format=%s ab45678", "Title1"),
Cmd("git log -1 --format=%s ab56789", "Revert \"Something\""),
Cmd("git log -1 ab12345", "Title4\nBUG=123\nBUG=234"),
Cmd("git log -1 ab23456", "Title2\n BUG = v8:123,345"),
Cmd("git log -1 ab34567", "Title3\nLOG=n\nBUG=567, 456"),
Cmd("git log -1 ab45678", "Title1\nBUG="),
Cmd("git log -1 ab56789", "Revert \"Something\"\nBUG=none"),
Cmd("git log -1 -p ab12345", "patch4"),
Cmd(("git apply --index --reject \"%s\"" %
TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
"", cb=VerifyPatch("patch4")),
Cmd("git log -1 -p ab23456", "patch2"),
Cmd(("git apply --index --reject \"%s\"" %
TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
"", cb=VerifyPatch("patch2")),
Cmd("git log -1 -p ab34567", "patch3"),
Cmd(("git apply --index --reject \"%s\"" %
TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
"", cb=VerifyPatch("patch3")),
Cmd("git log -1 -p ab45678", "patch1"),
Cmd(("git apply --index --reject \"%s\"" %
TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
"", cb=VerifyPatch("patch1")),
Cmd("git log -1 -p ab56789", "patch5\n"),
Cmd(("git apply --index --reject \"%s\"" %
TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
"", cb=VerifyPatch("patch5\n")),
Cmd("git apply --index --reject \"%s\"" % extra_patch, ""),
Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], ""),
RL("reviewer@chromium.org"), # V8 reviewer.
Cmd("git cl upload --send-mail -r \"reviewer@chromium.org\" "
"--bypass-hooks --cc \"ulan@chromium.org\"", ""),
Cmd("git cl comments -a \"%s\"" % info_msg, ""),
Cmd("git checkout -f %s" % TEST_CONFIG["BRANCHNAME"], ""),
RL("LGTM"), # Enter LGTM for V8 CL.
Cmd("git cl presubmit", "Presubmit successfull\n"),
Cmd("git cl land -f --bypass-hooks", "Closing issue\n",
cb=VerifyLand),
Cmd("git checkout -f origin/master", ""),
Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
])
# ab12345 and ab34567 are patches. ab23456 (included) and ab45678 are the
# MIPS ports of ab12345. ab56789 is the MIPS port of ab34567.
args = ["-f", "-p", extra_patch, "--branch", "candidates",
......@@ -1558,6 +1930,8 @@ Cr-Commit-Position: refs/heads/4.2.71@{#1}
self.assertEquals(expected_json, json.loads(FileToText(json_output)))
class SystemTest(unittest.TestCase):
def testReload(self):
options = ScriptsBase(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment