1af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org#!/usr/bin/env python 2af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# Copyright 2013 the V8 project authors. All rights reserved. 3af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# Redistribution and use in source and binary forms, with or without 4af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# modification, are permitted provided that the following conditions are 5af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# met: 6af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# 7af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# * Redistributions of source code must retain the above copyright 8af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# notice, this list of conditions and the following disclaimer. 9af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# * Redistributions in binary form must reproduce the above 10af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# copyright notice, this list of conditions and the following 11af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# disclaimer in the documentation and/or other materials provided 12af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# with the distribution. 13af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# * Neither the name of Google Inc. nor the names of its 14af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# contributors may be used to endorse or promote products derived 15af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# from this software without specific prior written permission. 16af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# 17af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 29f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgimport argparse 309cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.orgimport json 319cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.orgimport os 32af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgimport re 33af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgimport sys 3426ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.orgimport urllib 35af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 36af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgfrom common_includes import * 3743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.orgimport push_to_trunk 38af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 39a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgPUSH_MESSAGE_RE = re.compile(r".* \(based on bleeding_edge revision r(\d+)\)$") 40a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org 41af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgclass Preparation(Step): 4290dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org MESSAGE = "Preparation." 43af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 44af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org def RunStep(self): 45a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org self.InitialEnvironmentChecks(self.default_cwd) 46af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org self.CommonPrepare() 47af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 48af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 49a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgclass CheckAutoPushSettings(Step): 509cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org MESSAGE = "Checking settings file." 519cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 529cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org def RunStep(self): 5306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org settings_file = os.path.realpath(self.Config("SETTINGS_LOCATION")) 549cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org if os.path.exists(settings_file): 559cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org settings_dict = json.loads(FileToText(settings_file)) 569cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org if settings_dict.get("enable_auto_roll") is False: 579cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org self.Die("Push to trunk disabled by auto-roll settings file: %s" 589cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org % settings_file) 599cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 609cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 619cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.orgclass CheckTreeStatus(Step): 629cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org MESSAGE = "Checking v8 tree status message." 639cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 649cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org def RunStep(self): 659cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org status_url = "https://v8-status.appspot.com/current?format=json" 669cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org status_json = self.ReadURL(status_url, wait_plan=[5, 20, 300, 300]) 67f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org self["tree_message"] = json.loads(status_json)["message"] 68f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if re.search(r"nopush|no push", self["tree_message"], flags=re.I): 69f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org self.Die("Push to trunk disabled by tree state: %s" 70f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org % self["tree_message"]) 719cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 729cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 73a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgclass FetchLKGR(Step): 74a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org MESSAGE = "Fetching V8 LKGR." 75af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 76af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org def RunStep(self): 77a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org lkgr_url = "https://v8-status.appspot.com/lkgr" 78a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org # Retry several times since app engine might have issues. 79a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org self["lkgr"] = self.ReadURL(lkgr_url, wait_plan=[5, 20, 300, 300]) 80af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 81af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 82113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.orgclass CheckLastPush(Step): 83113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org MESSAGE = "Checking last V8 push to trunk." 84113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org 85113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org def RunStep(self): 86a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org last_push = self.FindLastTrunkPush() 87a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org 88a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org # Retrieve the bleeding edge revision of the last push from the text in 89a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org # the push commit message. 90a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org last_push_title = self.GitLog(n=1, format="%s", git_hash=last_push) 91a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org last_push_be = PUSH_MESSAGE_RE.match(last_push_title).group(1) 92a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org 93a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org if not last_push_be: # pragma: no cover 94a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org self.Die("Could not retrieve bleeding edge revision for trunk push %s" 95a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org % last_push) 96f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 97f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org # TODO(machenbach): This metric counts all revisions. It could be 98f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org # improved by counting only the revisions on bleeding_edge. 99a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org if int(self["lkgr"]) - int(last_push_be) < 10: # pragma: no cover 100f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org # This makes sure the script doesn't push twice in a row when the cron 101f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org # job retries several times. 102a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org self.Die("Last push too recently: %s" % last_push_be) 103113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org 104113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org 105a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgclass PushToTrunk(Step): 106a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org MESSAGE = "Pushing to trunk if specified." 107af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 108af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org def RunStep(self): 109a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org print "Pushing lkgr %s to trunk." % self["lkgr"] 110af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 111a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org # TODO(machenbach): Update the script before calling it. 112a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org if self._options.push: 113a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org self._side_effect_handler.Call( 11406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org push_to_trunk.PushToTrunk().Run, 115a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org ["--author", self._options.author, 116a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org "--reviewer", self._options.reviewer, 117a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org "--revision", self["lkgr"], 118a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org "--force"]) 119af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 12026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 121a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgclass AutoPush(ScriptsBase): 122bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org def _PrepareOptions(self, parser): 123bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org parser.add_argument("-p", "--push", 124bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org help="Push to trunk. Dry run if unspecified.", 125bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org default=False, action="store_true") 126bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org 127bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org def _ProcessOptions(self, options): 128486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if not options.author or not options.reviewer: # pragma: no cover 129bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org print "You need to specify author and reviewer." 130bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org return False 131bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org options.requires_editor = False 132bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org return True 133bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org 13406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org def _Config(self): 13506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org return { 13606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org "PERSISTFILE_BASENAME": "/tmp/v8-auto-push-tempfile", 13706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org "SETTINGS_LOCATION": "~/.auto-roll", 13806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 13906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 140bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org def _Steps(self): 141bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org return [ 142bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org Preparation, 143a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org CheckAutoPushSettings, 144bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org CheckTreeStatus, 145bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org FetchLKGR, 146a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org CheckLastPush, 147bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org PushToTrunk, 148bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org ] 149bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org 150af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 151486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.orgif __name__ == "__main__": # pragma: no cover 15206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org sys.exit(AutoPush().Run()) 153