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 399cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.orgSETTINGS_LOCATION = "SETTINGS_LOCATION" 409cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 41af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgCONFIG = { 424edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org PERSISTFILE_BASENAME: "/tmp/v8-auto-push-tempfile", 43af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org DOT_GIT_LOCATION: ".git", 449cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org SETTINGS_LOCATION: "~/.auto-roll", 45af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org} 46af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 47a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgPUSH_MESSAGE_RE = re.compile(r".* \(based on bleeding_edge revision r(\d+)\)$") 48a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org 49af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 50af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgclass Preparation(Step): 5190dca01eac542464c29011d239bf18f26e0b8f00machenbach@chromium.org MESSAGE = "Preparation." 52af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 53af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org def RunStep(self): 54af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org self.InitialEnvironmentChecks() 55af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org self.CommonPrepare() 56af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 57af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 58a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgclass CheckAutoPushSettings(Step): 599cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org MESSAGE = "Checking settings file." 609cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 619cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org def RunStep(self): 629cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org settings_file = os.path.realpath(self.Config(SETTINGS_LOCATION)) 639cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org if os.path.exists(settings_file): 649cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org settings_dict = json.loads(FileToText(settings_file)) 659cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org if settings_dict.get("enable_auto_roll") is False: 669cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org self.Die("Push to trunk disabled by auto-roll settings file: %s" 679cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org % settings_file) 689cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 699cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 709cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.orgclass CheckTreeStatus(Step): 719cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org MESSAGE = "Checking v8 tree status message." 729cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 739cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org def RunStep(self): 749cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org status_url = "https://v8-status.appspot.com/current?format=json" 759cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org status_json = self.ReadURL(status_url, wait_plan=[5, 20, 300, 300]) 76f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org self["tree_message"] = json.loads(status_json)["message"] 77f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if re.search(r"nopush|no push", self["tree_message"], flags=re.I): 78f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org self.Die("Push to trunk disabled by tree state: %s" 79f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org % self["tree_message"]) 809cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 819cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 82a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgclass FetchLKGR(Step): 83a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org MESSAGE = "Fetching V8 LKGR." 84af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 85af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org def RunStep(self): 86a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org lkgr_url = "https://v8-status.appspot.com/lkgr" 87a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org # Retry several times since app engine might have issues. 88a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org self["lkgr"] = self.ReadURL(lkgr_url, wait_plan=[5, 20, 300, 300]) 89af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 90af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 91113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.orgclass CheckLastPush(Step): 92113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org MESSAGE = "Checking last V8 push to trunk." 93113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org 94113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org def RunStep(self): 95a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org last_push = self.FindLastTrunkPush() 96a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org 97a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org # Retrieve the bleeding edge revision of the last push from the text in 98a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org # the push commit message. 99a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org last_push_title = self.GitLog(n=1, format="%s", git_hash=last_push) 100a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org last_push_be = PUSH_MESSAGE_RE.match(last_push_title).group(1) 101a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org 102a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org if not last_push_be: # pragma: no cover 103a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org self.Die("Could not retrieve bleeding edge revision for trunk push %s" 104a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org % last_push) 105f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 106f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org # TODO(machenbach): This metric counts all revisions. It could be 107f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org # improved by counting only the revisions on bleeding_edge. 108a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org if int(self["lkgr"]) - int(last_push_be) < 10: # pragma: no cover 109f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org # This makes sure the script doesn't push twice in a row when the cron 110f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org # job retries several times. 111a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org self.Die("Last push too recently: %s" % last_push_be) 112113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org 113113035e2f19feb7032fbe57b2e3e376f1dfc4110jkummerow@chromium.org 114a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgclass PushToTrunk(Step): 115a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org MESSAGE = "Pushing to trunk if specified." 116af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 117af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org def RunStep(self): 118a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org print "Pushing lkgr %s to trunk." % self["lkgr"] 119af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 120a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org # TODO(machenbach): Update the script before calling it. 121a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org if self._options.push: 122a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org P = push_to_trunk.PushToTrunk 123a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org self._side_effect_handler.Call( 124a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org P(push_to_trunk.CONFIG, self._side_effect_handler).Run, 125a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org ["--author", self._options.author, 126a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org "--reviewer", self._options.reviewer, 127a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org "--revision", self["lkgr"], 128a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org "--force"]) 129af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 13026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org 131a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.orgclass AutoPush(ScriptsBase): 132bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org def _PrepareOptions(self, parser): 133bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org parser.add_argument("-p", "--push", 134bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org help="Push to trunk. Dry run if unspecified.", 135bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org default=False, action="store_true") 136bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org 137bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org def _ProcessOptions(self, options): 138486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org if not options.author or not options.reviewer: # pragma: no cover 139bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org print "You need to specify author and reviewer." 140bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org return False 141bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org options.requires_editor = False 142bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org return True 143bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org 144bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org def _Steps(self): 145bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org return [ 146bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org Preparation, 147a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org CheckAutoPushSettings, 148bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org CheckTreeStatus, 149bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org FetchLKGR, 150a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org CheckLastPush, 151bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org PushToTrunk, 152bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org ] 153bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org 154af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 155486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.orgif __name__ == "__main__": # pragma: no cover 156a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org sys.exit(AutoPush(CONFIG).Run()) 157