Implement auto-roll script.

This script will (1) check if there is an active roll on rietveld (2) check if there is a trunk revision ready to be rolled and (3) call the chromium_roll script, creating a roll CL. The script will be called regularly through a cron job.

BUG=
R=jarin@chromium.org

Review URL: https://codereview.chromium.org/212983003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20422 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
machenbach@chromium.org 2014-04-02 06:59:25 +00:00
parent 6a97085961
commit 0b246776ec
3 changed files with 180 additions and 6 deletions

View File

@ -0,0 +1,107 @@
#!/usr/bin/env python
# Copyright 2014 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import argparse
import json
import os
import sys
import urllib
from common_includes import *
import chromium_roll
CR_DEPS_URL = 'http://src.chromium.org/svn/trunk/src/DEPS'
class CheckActiveRoll(Step):
MESSAGE = "Check active roll."
@staticmethod
def ContainsChromiumRoll(changes):
for change in changes:
if change["subject"].startswith("Update V8 to"):
return True
return False
def RunStep(self):
params = {
"closed": 3,
"owner": self._options.author,
"limit": 30,
"format": "json",
}
params = urllib.urlencode(params)
search_url = "https://codereview.chromium.org/search"
result = self.ReadURL(search_url, params, wait_plan=[5, 20])
if self.ContainsChromiumRoll(json.loads(result)["results"]):
print "Stop due to existing Chromium roll."
return True
class DetectLastPush(Step):
MESSAGE = "Detect commit ID of the last push to trunk."
def RunStep(self):
push_hash = self.FindLastTrunkPush()
self["last_push"] = self.GitSVNFindSVNRev(push_hash)
class DetectLastRoll(Step):
MESSAGE = "Detect commit ID of the last Chromium roll."
def RunStep(self):
# Interpret the DEPS file to retrieve the v8 revision.
Var = lambda var: '%s'
exec(self.ReadURL(CR_DEPS_URL))
last_roll = vars['v8_revision']
if last_roll >= self["last_push"]:
print("There is no newer v8 revision than the one in Chromium (%s)."
% last_roll)
return True
class RollChromium(Step):
MESSAGE = "Roll V8 into Chromium."
def RunStep(self):
if self._options.roll:
R = chromium_roll.ChromiumRoll
self._side_effect_handler.Call(
R(chromium_roll.CONFIG, self._side_effect_handler).Run,
["--author", self._options.author,
"--reviewer", self._options.reviewer,
"--chromium", self._options.chromium,
"--force"])
class AutoRoll(ScriptsBase):
def _PrepareOptions(self, parser):
group = parser.add_mutually_exclusive_group()
parser.add_argument("-c", "--chromium", required=True,
help=("The path to your Chromium src/ "
"directory to automate the V8 roll."))
parser.add_argument("--roll",
help="Make Chromium roll. Dry run if unspecified.",
default=False, action="store_true")
def _ProcessOptions(self, options): # pragma: no cover
if not options.reviewer:
print "A reviewer (-r) is required."
return False
if not options.author:
print "An author (-a) is required."
return False
return True
def _Steps(self):
return [
CheckActiveRoll,
DetectLastPush,
DetectLastRoll,
RollChromium,
]
if __name__ == "__main__": # pragma: no cover
sys.exit(AutoRoll(CONFIG).Run())

View File

@ -257,10 +257,11 @@ class Step(GitRecipesMixin):
return
print ">>> Step %d: %s" % (self._number, self._text)
self.RunStep()
# Persist state.
TextToFile(json.dumps(self._state), state_file)
try:
return self.RunStep()
finally:
# Persist state.
TextToFile(json.dumps(self._state), state_file)
def RunStep(self): # pragma: no cover
raise NotImplementedError
@ -555,7 +556,8 @@ class ScriptsBase(object):
steps.append(MakeStep(step_class, number, self._state, self._config,
options, self._side_effect_handler))
for step in steps[options.step:]:
step.Run()
if step.Run():
return 1
return 0
def Run(self, args=None):

View File

@ -34,6 +34,7 @@ import unittest
import auto_push
from auto_push import CheckLastPush
from auto_push import SETTINGS_LOCATION
import auto_roll
import common_includes
from common_includes import *
import merge_to_branch
@ -261,7 +262,7 @@ class SimpleMock(object):
# arguments.
if len(args) > len(expected_call['args']):
raise NoRetryException("When calling %s with arguments, the "
"expectations must consist of at least as many arguments.")
"expectations must consist of at least as many arguments." % name)
# Compare expected and actual arguments.
for (expected_arg, actual_arg) in zip(expected_call['args'], args):
@ -908,6 +909,70 @@ Performance and stability improvements on all platforms.""", commit)
auto_push.AutoPush(TEST_CONFIG, self).Run(AUTO_PUSH_ARGS)
self.assertRaises(Exception, RunAutoPush)
def testAutoRollExistingRoll(self):
self.ExpectReadURL([
URL("https://codereview.chromium.org/search",
"owner=author%40chromium.org&limit=30&closed=3&format=json",
("{\"results\": [{\"subject\": \"different\"},"
"{\"subject\": \"Update V8 to Version...\"}]}")),
])
result = auto_roll.AutoRoll(TEST_CONFIG, self).Run(
AUTO_PUSH_ARGS + ["-c", TEST_CONFIG[CHROMIUM]])
self.assertEquals(1, result)
# Snippet from the original DEPS file.
FAKE_DEPS = """
vars = {
"v8_revision": "123455",
}
deps = {
"src/v8":
(Var("googlecode_url") % "v8") + "/" + Var("v8_branch") + "@" +
Var("v8_revision"),
}
"""
def testAutoRollUpToDate(self):
self.ExpectReadURL([
URL("https://codereview.chromium.org/search",
"owner=author%40chromium.org&limit=30&closed=3&format=json",
("{\"results\": [{\"subject\": \"different\"}]}")),
URL("http://src.chromium.org/svn/trunk/src/DEPS",
self.FAKE_DEPS),
])
self.ExpectGit([
Git(("log -1 --format=%H --grep="
"\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]* (based\" "
"svn/trunk"), "push_hash\n"),
Git("svn find-rev push_hash", "123455\n"),
])
result = auto_roll.AutoRoll(TEST_CONFIG, self).Run(
AUTO_PUSH_ARGS + ["-c", TEST_CONFIG[CHROMIUM]])
self.assertEquals(1, result)
def testAutoRoll(self):
self.ExpectReadURL([
URL("https://codereview.chromium.org/search",
"owner=author%40chromium.org&limit=30&closed=3&format=json",
("{\"results\": [{\"subject\": \"different\"}]}")),
URL("http://src.chromium.org/svn/trunk/src/DEPS",
self.FAKE_DEPS),
])
self.ExpectGit([
Git(("log -1 --format=%H --grep="
"\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]* (based\" "
"svn/trunk"), "push_hash\n"),
Git("svn find-rev push_hash", "123456\n"),
])
result = auto_roll.AutoRoll(TEST_CONFIG, self).Run(
AUTO_PUSH_ARGS + ["-c", TEST_CONFIG[CHROMIUM], "--roll"])
self.assertEquals(0, result)
def testMergeToBranch(self):
TEST_CONFIG[ALREADY_MERGING_SENTINEL_FILE] = self.MakeEmptyTempFile()
TEST_CONFIG[DOT_GIT_LOCATION] = self.MakeEmptyTempFile()