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 | |
8 import os | 7 import os |
9 import sys | 8 import sys |
10 import urllib | |
11 | 9 |
12 from common_includes import * | 10 from common_includes import * |
Michael Achenbach
2015/11/23 10:37:30
Rietveld is not so helpful here. Better is a diff
| |
13 import chromium_roll | 11 |
12 ROLL_SUMMARY = ("Summary of changes available at:\n" | |
13 "https://chromium.googlesource.com/v8/v8/+log/%s..%s") | |
14 | |
15 ISSUE_MSG = ( | |
16 """Please follow these instructions for assigning/CC'ing issues: | |
17 https://code.google.com/p/v8-wiki/wiki/TriagingIssues | |
18 | |
19 Please close rolling in case of a roll revert: | |
20 https://v8-roll.appspot.com/ | |
21 This only works with a Google account.""") | |
22 | |
23 class Preparation(Step): | |
24 MESSAGE = "Preparation." | |
25 | |
26 def RunStep(self): | |
27 # Update v8 remote tracking branches. | |
28 self.GitFetchOrigin() | |
29 self.Git("fetch origin +refs/tags/*:refs/tags/*") | |
14 | 30 |
15 | 31 |
16 class DetectLastRoll(Step): | 32 class DetectLastRoll(Step): |
17 MESSAGE = "Detect commit ID of the last Chromium roll." | 33 MESSAGE = "Detect commit ID of the last Chromium roll." |
18 | 34 |
19 def RunStep(self): | 35 def RunStep(self): |
36 self["last_roll"] = self._options.last_roll | |
37 if not self["last_roll"]: | |
38 # Interpret the DEPS file to retrieve the v8 revision. | |
39 # TODO(machenbach): This should be part or the roll-deps api of | |
40 # depot_tools. | |
41 Var = lambda var: '%s' | |
42 exec(FileToText(os.path.join(self._options.chromium, "DEPS"))) | |
43 | |
44 # The revision rolled last. | |
45 self["last_roll"] = vars['v8_revision'] | |
46 self["last_version"] = self.GetVersionTag(self["last_roll"]) | |
47 assert self["last_version"], "The last rolled v8 revision is not tagged." | |
48 | |
49 | |
50 class DetectRevisionToRoll(Step): | |
51 MESSAGE = "Detect commit ID of the V8 revision to roll." | |
52 | |
53 def RunStep(self): | |
54 self["roll"] = self._options.revision | |
55 if self["roll"]: | |
56 # If the revision was passed on the cmd line, continue script execution | |
57 # in the next step. | |
58 return False | |
59 | |
20 # The revision that should be rolled. Check for the latest of the most | 60 # The revision that should be rolled. Check for the latest of the most |
21 # recent releases based on commit timestamp. | 61 # recent releases based on commit timestamp. |
22 revisions = self.GetRecentReleases( | 62 revisions = self.GetRecentReleases( |
23 max_age=self._options.max_age * DAY_IN_SECONDS) | 63 max_age=self._options.max_age * DAY_IN_SECONDS) |
24 assert revisions, "Didn't find any recent release." | 64 assert revisions, "Didn't find any recent release." |
25 | 65 |
26 # Interpret the DEPS file to retrieve the v8 revision. | |
27 # TODO(machenbach): This should be part or the roll-deps api of | |
28 # depot_tools. | |
29 Var = lambda var: '%s' | |
30 exec(FileToText(os.path.join(self._options.chromium, "DEPS"))) | |
31 | |
32 # The revision rolled last. | |
33 self["last_roll"] = vars['v8_revision'] | |
34 last_version = self.GetVersionTag(self["last_roll"]) | |
35 assert last_version, "The last rolled v8 revision is not tagged." | |
36 | |
37 # There must be some progress between the last roll and the new candidate | 66 # There must be some progress between the last roll and the new candidate |
38 # revision (i.e. we don't go backwards). The revisions are ordered newest | 67 # revision (i.e. we don't go backwards). The revisions are ordered newest |
39 # to oldest. It is possible that the newest timestamp has no progress | 68 # to oldest. It is possible that the newest timestamp has no progress |
40 # compared to the last roll, i.e. if the newest release is a cherry-pick | 69 # compared to the last roll, i.e. if the newest release is a cherry-pick |
41 # on a release branch. Then we look further. | 70 # on a release branch. Then we look further. |
42 for revision in revisions: | 71 for revision in revisions: |
43 version = self.GetVersionTag(revision) | 72 version = self.GetVersionTag(revision) |
44 assert version, "Internal error. All recent releases should have a tag" | 73 assert version, "Internal error. All recent releases should have a tag" |
45 | 74 |
46 if SortingKey(last_version) < SortingKey(version): | 75 if SortingKey(self["last_version"]) < SortingKey(version): |
47 self["roll"] = revision | 76 self["roll"] = revision |
48 break | 77 break |
49 else: | 78 else: |
50 print("There is no newer v8 revision than the one in Chromium (%s)." | 79 print("There is no newer v8 revision than the one in Chromium (%s)." |
51 % self["last_roll"]) | 80 % self["last_roll"]) |
52 return True | 81 return True |
53 | 82 |
54 | 83 |
55 class RollChromium(Step): | 84 class PrepareRollCandidate(Step): |
56 MESSAGE = "Roll V8 into Chromium." | 85 MESSAGE = "Robustness checks of the roll candidate." |
57 | 86 |
58 def RunStep(self): | 87 def RunStep(self): |
59 if self._options.roll: | 88 self["roll_title"] = self.GitLog(n=1, format="%s", |
60 args = [ | 89 git_hash=self["roll"]) |
61 "--author", self._options.author, | 90 |
62 "--reviewer", self._options.reviewer, | 91 # Make sure the last roll and the roll candidate are releases. |
63 "--chromium", self._options.chromium, | 92 version = self.GetVersionTag(self["roll"]) |
64 "--last-roll", self["last_roll"], | 93 assert version, "The revision to roll is not tagged." |
65 "--use-commit-queue", | 94 version = self.GetVersionTag(self["last_roll"]) |
66 self["roll"], | 95 assert version, "The revision used as last roll is not tagged." |
67 ] | 96 |
68 if self._options.dry_run: | 97 |
69 args.append("--dry-run") | 98 class SwitchChromium(Step): |
70 if self._options.work_dir: | 99 MESSAGE = "Switch to Chromium checkout." |
71 args.extend(["--work-dir", self._options.work_dir]) | 100 |
72 if self._options.chromium_roll_json_output: | 101 def RunStep(self): |
73 args.extend(["--json-output", self._options.chromium_roll_json_output]) | 102 cwd = self._options.chromium |
74 self._side_effect_handler.Call(chromium_roll.ChromiumRoll().Run, args) | 103 self.InitialEnvironmentChecks(cwd) |
104 # Check for a clean workdir. | |
105 if not self.GitIsWorkdirClean(cwd=cwd): # pragma: no cover | |
106 self.Die("Workspace is not clean. Please commit or undo your changes.") | |
107 # Assert that the DEPS file is there. | |
108 if not os.path.exists(os.path.join(cwd, "DEPS")): # pragma: no cover | |
109 self.Die("DEPS file not present.") | |
110 | |
111 | |
112 class UpdateChromiumCheckout(Step): | |
113 MESSAGE = "Update the checkout and create a new branch." | |
114 | |
115 def RunStep(self): | |
116 cwd = self._options.chromium | |
117 self.GitCheckout("master", cwd=cwd) | |
118 self.DeleteBranch("work-branch", cwd=cwd) | |
119 self.Command("gclient", "sync --nohooks", cwd=cwd) | |
120 self.GitPull(cwd=cwd) | |
121 | |
122 # Update v8 remotes. | |
123 self.GitFetchOrigin() | |
124 | |
125 self.GitCreateBranch("work-branch", cwd=cwd) | |
126 | |
127 | |
128 class UploadCL(Step): | |
129 MESSAGE = "Create and upload CL." | |
130 | |
131 def RunStep(self): | |
132 cwd = self._options.chromium | |
133 # Patch DEPS file. | |
134 if self.Command("roll-dep-svn", "v8 %s" % | |
135 self["roll"], cwd=cwd) is None: | |
136 self.Die("Failed to create deps for %s" % self["roll"]) | |
137 | |
138 message = [] | |
139 message.append("Update V8 to %s." % self["roll_title"].lower()) | |
140 | |
141 message.append( | |
142 ROLL_SUMMARY % (self["last_roll"][:8], self["roll"][:8])) | |
143 | |
144 message.append(ISSUE_MSG) | |
145 | |
146 message.append("TBR=%s" % self._options.reviewer) | |
147 self.GitCommit("\n\n".join(message), author=self._options.author, cwd=cwd) | |
148 if not self._options.dry_run: | |
149 self.GitUpload(author=self._options.author, | |
150 force=True, | |
151 cq=self._options.use_commit_queue, | |
152 cwd=cwd) | |
153 print "CL uploaded." | |
154 else: | |
155 print "Dry run - don't upload." | |
156 | |
157 self.GitCheckout("master", cwd=cwd) | |
158 self.GitDeleteBranch("work-branch", cwd=cwd) | |
159 | |
160 class CleanUp(Step): | |
161 MESSAGE = "Done!" | |
162 | |
163 def RunStep(self): | |
164 print("Congratulations, you have successfully rolled %s into " | |
165 "Chromium." | |
166 % self["roll"]) | |
167 | |
168 # Clean up all temporary files. | |
169 Command("rm", "-f %s*" % self._config["PERSISTFILE_BASENAME"]) | |
75 | 170 |
76 | 171 |
77 class AutoRoll(ScriptsBase): | 172 class AutoRoll(ScriptsBase): |
78 def _PrepareOptions(self, parser): | 173 def _PrepareOptions(self, parser): |
79 parser.add_argument("-c", "--chromium", required=True, | 174 parser.add_argument("-c", "--chromium", required=True, |
80 help=("The path to your Chromium src/ " | 175 help=("The path to your Chromium src/ " |
81 "directory to automate the V8 roll.")) | 176 "directory to automate the V8 roll.")) |
82 parser.add_argument("--chromium-roll-json-output", | 177 parser.add_argument("--last-roll", |
83 help="File to write wrapped results summary to.") | 178 help="The git commit ID of the last rolled version. " |
179 "Auto-detected by default.") | |
Michael Hablich
2015/11/24 08:22:20
If there is a default shouldn't default be specifi
Michael Achenbach
2015/11/24 08:35:50
This is a changing value, it can be _any_ hash. Ei
| |
84 parser.add_argument("--max-age", default=3, type=int, | 180 parser.add_argument("--max-age", default=3, type=int, |
85 help="Maximum age in days of the latest release.") | 181 help="Maximum age in days of the latest release.") |
86 parser.add_argument("--roll", help="Call Chromium roll script.", | 182 parser.add_argument("--revision", |
87 default=False, action="store_true") | 183 help="Revision to roll. Auto-detected by default."), |
184 parser.add_argument("--roll", help="Deprecated.", | |
185 default=True, action="store_true") | |
186 parser.add_argument("--use-commit-queue", | |
187 help="Check the CQ bit on upload.", | |
188 default=True, action="store_true") | |
88 | 189 |
89 def _ProcessOptions(self, options): # pragma: no cover | 190 def _ProcessOptions(self, options): # pragma: no cover |
90 if not options.reviewer: | 191 if not options.author or not options.reviewer: |
91 print "A reviewer (-r) is required." | 192 print "A reviewer (-r) and an author (-a) are required." |
92 return False | 193 return False |
93 if not options.author: | 194 |
94 print "An author (-a) is required." | 195 options.requires_editor = False |
95 return False | 196 options.force = True |
197 options.manual = False | |
96 return True | 198 return True |
97 | 199 |
98 def _Config(self): | 200 def _Config(self): |
99 return { | 201 return { |
100 "PERSISTFILE_BASENAME": "/tmp/v8-auto-roll-tempfile", | 202 "PERSISTFILE_BASENAME": "/tmp/v8-chromium-roll-tempfile", |
101 } | 203 } |
102 | 204 |
103 def _Steps(self): | 205 def _Steps(self): |
104 return [ | 206 return [ |
207 Preparation, | |
105 DetectLastRoll, | 208 DetectLastRoll, |
106 RollChromium, | 209 DetectRevisionToRoll, |
210 PrepareRollCandidate, | |
211 SwitchChromium, | |
212 UpdateChromiumCheckout, | |
213 UploadCL, | |
214 CleanUp, | |
107 ] | 215 ] |
108 | 216 |
109 | 217 |
110 if __name__ == "__main__": # pragma: no cover | 218 if __name__ == "__main__": # pragma: no cover |
111 sys.exit(AutoRoll().Run()) | 219 sys.exit(AutoRoll().Run()) |
OLD | NEW |