| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2014 the V8 project authors. All rights reserved. | 2 # Copyright 2014 the V8 project authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 import argparse | 6 import argparse |
| 7 import json | 7 import json |
| 8 import os | 8 import os |
| 9 import sys | 9 import sys |
| 10 import urllib | 10 import urllib |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 result = self.ReadURL(search_url, params, wait_plan=[5, 20]) | 35 result = self.ReadURL(search_url, params, wait_plan=[5, 20]) |
| 36 if self.ContainsChromiumRoll(json.loads(result)["results"]): | 36 if self.ContainsChromiumRoll(json.loads(result)["results"]): |
| 37 print "Stop due to existing Chromium roll." | 37 print "Stop due to existing Chromium roll." |
| 38 return True | 38 return True |
| 39 | 39 |
| 40 | 40 |
| 41 class DetectLastRoll(Step): | 41 class DetectLastRoll(Step): |
| 42 MESSAGE = "Detect commit ID of the last Chromium roll." | 42 MESSAGE = "Detect commit ID of the last Chromium roll." |
| 43 | 43 |
| 44 def RunStep(self): | 44 def RunStep(self): |
| 45 # The revision that should be rolled. | 45 # The revision that should be rolled. Check for the latest of the most |
| 46 latest_release = self.GetLatestRelease() | 46 # recent releases based on commit timestamp. |
| 47 revisions = self.GetRecentReleases( |
| 48 max_age=self._options.max_age * DAY_IN_SECONDS) |
| 49 assert revisions, "Didn't find any recent release." |
| 47 | 50 |
| 48 # Interpret the DEPS file to retrieve the v8 revision. | 51 # Interpret the DEPS file to retrieve the v8 revision. |
| 49 # TODO(machenbach): This should be part or the roll-deps api of | 52 # TODO(machenbach): This should be part or the roll-deps api of |
| 50 # depot_tools. | 53 # depot_tools. |
| 51 Var = lambda var: '%s' | 54 Var = lambda var: '%s' |
| 52 exec(FileToText(os.path.join(self._options.chromium, "DEPS"))) | 55 exec(FileToText(os.path.join(self._options.chromium, "DEPS"))) |
| 53 | 56 |
| 54 # The revision rolled last. | 57 # The revision rolled last. |
| 55 self["last_roll"] = vars['v8_revision'] | 58 self["last_roll"] = vars['v8_revision'] |
| 56 | 59 |
| 57 # TODO(machenbach): It is possible that the auto-push script made a new | 60 # There must be some progress between the last roll and the new candidate |
| 58 # fast-forward release (e.g. 4.2.3) while somebody patches the last | 61 # revision (i.e. we don't go backwards). The revisions are ordered newest |
| 59 # candidate (e.g. 4.2.2.1). In this case, the auto-roller would pick | 62 # to oldest. It is possible that the newest timestamp has no progress |
| 60 # the fast-forward release. Should there be a way to prioritize the | 63 # compared to the last roll, i.e. if the newest release is a cherry-pick |
| 61 # patched version? | 64 # on a release branch. Then we look further. |
| 62 | 65 for revision in revisions: |
| 63 if latest_release == self["last_roll"]: | 66 commits = self.GitLog( |
| 64 # We always try to roll if the latest revision is not the revision in | 67 format="%H", git_hash="%s..%s" % (self["last_roll"], revision)) |
| 65 # chromium. | 68 if commits: |
| 69 self["roll"] = revision |
| 70 break |
| 71 else: |
| 66 print("There is no newer v8 revision than the one in Chromium (%s)." | 72 print("There is no newer v8 revision than the one in Chromium (%s)." |
| 67 % self["last_roll"]) | 73 % self["last_roll"]) |
| 68 return True | 74 return True |
| 69 | 75 |
| 70 | 76 |
| 71 class CheckClusterFuzz(Step): | |
| 72 MESSAGE = "Check ClusterFuzz api for new problems." | |
| 73 | |
| 74 def RunStep(self): | |
| 75 if not os.path.exists(self.Config("CLUSTERFUZZ_API_KEY_FILE")): | |
| 76 print "Skipping ClusterFuzz check. No api key file found." | |
| 77 return False | |
| 78 api_key = FileToText(self.Config("CLUSTERFUZZ_API_KEY_FILE")) | |
| 79 # Check for open, reproducible issues that have no associated bug. | |
| 80 result = self._side_effect_handler.ReadClusterFuzzAPI( | |
| 81 api_key, job_type="linux_asan_d8_dbg", reproducible="True", | |
| 82 open="True", bug_information="", | |
| 83 revision_greater_or_equal=str(self["last_push"])) | |
| 84 if result: | |
| 85 print "Stop due to pending ClusterFuzz issues." | |
| 86 return True | |
| 87 | |
| 88 | |
| 89 class RollChromium(Step): | 77 class RollChromium(Step): |
| 90 MESSAGE = "Roll V8 into Chromium." | 78 MESSAGE = "Roll V8 into Chromium." |
| 91 | 79 |
| 92 def RunStep(self): | 80 def RunStep(self): |
| 93 if self._options.roll: | 81 if self._options.roll: |
| 94 args = [ | 82 args = [ |
| 95 "--author", self._options.author, | 83 "--author", self._options.author, |
| 96 "--reviewer", self._options.reviewer, | 84 "--reviewer", self._options.reviewer, |
| 97 "--chromium", self._options.chromium, | 85 "--chromium", self._options.chromium, |
| 98 "--last-roll", self["last_roll"], | 86 "--last-roll", self["last_roll"], |
| 99 "--use-commit-queue", | 87 "--use-commit-queue", |
| 88 self["roll"], |
| 100 ] | 89 ] |
| 101 if self._options.sheriff: | 90 if self._options.sheriff: |
| 102 args.append("--sheriff") | 91 args.append("--sheriff") |
| 103 if self._options.dry_run: | 92 if self._options.dry_run: |
| 104 args.append("--dry-run") | 93 args.append("--dry-run") |
| 105 if self._options.work_dir: | 94 if self._options.work_dir: |
| 106 args.extend(["--work-dir", self._options.work_dir]) | 95 args.extend(["--work-dir", self._options.work_dir]) |
| 107 self._side_effect_handler.Call(chromium_roll.ChromiumRoll().Run, args) | 96 self._side_effect_handler.Call(chromium_roll.ChromiumRoll().Run, args) |
| 108 | 97 |
| 109 | 98 |
| 110 class AutoRoll(ScriptsBase): | 99 class AutoRoll(ScriptsBase): |
| 111 def _PrepareOptions(self, parser): | 100 def _PrepareOptions(self, parser): |
| 112 parser.add_argument("-c", "--chromium", required=True, | 101 parser.add_argument("-c", "--chromium", required=True, |
| 113 help=("The path to your Chromium src/ " | 102 help=("The path to your Chromium src/ " |
| 114 "directory to automate the V8 roll.")) | 103 "directory to automate the V8 roll.")) |
| 104 parser.add_argument("--max-age", default=3, type=int, |
| 105 help="Maximum age in days of the latest release.") |
| 115 parser.add_argument("--roll", help="Call Chromium roll script.", | 106 parser.add_argument("--roll", help="Call Chromium roll script.", |
| 116 default=False, action="store_true") | 107 default=False, action="store_true") |
| 117 | 108 |
| 118 def _ProcessOptions(self, options): # pragma: no cover | 109 def _ProcessOptions(self, options): # pragma: no cover |
| 119 if not options.reviewer: | 110 if not options.reviewer: |
| 120 print "A reviewer (-r) is required." | 111 print "A reviewer (-r) is required." |
| 121 return False | 112 return False |
| 122 if not options.author: | 113 if not options.author: |
| 123 print "An author (-a) is required." | 114 print "An author (-a) is required." |
| 124 return False | 115 return False |
| 125 return True | 116 return True |
| 126 | 117 |
| 127 def _Config(self): | 118 def _Config(self): |
| 128 return { | 119 return { |
| 129 "PERSISTFILE_BASENAME": "/tmp/v8-auto-roll-tempfile", | 120 "PERSISTFILE_BASENAME": "/tmp/v8-auto-roll-tempfile", |
| 130 "CLUSTERFUZZ_API_KEY_FILE": ".cf_api_key", | |
| 131 } | 121 } |
| 132 | 122 |
| 133 def _Steps(self): | 123 def _Steps(self): |
| 134 return [ | 124 return [ |
| 135 CheckActiveRoll, | 125 CheckActiveRoll, |
| 136 DetectLastRoll, | 126 DetectLastRoll, |
| 137 CheckClusterFuzz, | |
| 138 RollChromium, | 127 RollChromium, |
| 139 ] | 128 ] |
| 140 | 129 |
| 141 | 130 |
| 142 if __name__ == "__main__": # pragma: no cover | 131 if __name__ == "__main__": # pragma: no cover |
| 143 sys.exit(AutoRoll().Run()) | 132 sys.exit(AutoRoll().Run()) |
| OLD | NEW |