blob: 647708c0c76324158019273c561f0c461f8eb76b [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001#!/usr/bin/env python
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
4# found in the LICENSE file.
5
6"""
7Script for auto-increasing the version on bleeding_edge.
8
9The script can be run regularly by a cron job. It will increase the build
10level of the version on bleeding_edge if:
11- the lkgr version is smaller than the version of the latest revision,
12- the lkgr version is not a version change itself,
13- the tree is not closed for maintenance.
14
15The new version will be the maximum of the bleeding_edge and trunk versions +1.
16E.g. latest bleeding_edge version: 3.22.11.0 and latest trunk 3.23.0.0 gives
17the new version 3.23.1.0.
18
19This script requires a depot tools git checkout. I.e. 'fetch v8'.
20"""
21
22import argparse
23import os
24import sys
25
26from common_includes import *
27
28VERSION_BRANCH = "auto-bump-up-version"
29
30
Emily Bernierd0a1eb72015-03-24 16:35:39 -040031# TODO(machenbach): Add vc interface that works on git mirror.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000032class Preparation(Step):
33 MESSAGE = "Preparation."
34
35 def RunStep(self):
Emily Bernierd0a1eb72015-03-24 16:35:39 -040036 # TODO(machenbach): Remove after the git switch.
37 if(self.Config("PERSISTFILE_BASENAME") ==
38 "/tmp/v8-bump-up-version-tempfile"):
39 print "This script is disabled until after the v8 git migration."
40 return True
41
Ben Murdochb8a8cc12014-11-26 15:28:44 +000042 # Check for a clean workdir.
43 if not self.GitIsWorkdirClean(): # pragma: no cover
44 # This is in case a developer runs this script on a dirty tree.
45 self.GitStash()
46
Emily Bernierd0a1eb72015-03-24 16:35:39 -040047 self.GitCheckout("master")
Ben Murdochb8a8cc12014-11-26 15:28:44 +000048
49 self.GitPull()
50
51 # Ensure a clean version branch.
52 self.DeleteBranch(VERSION_BRANCH)
53
54
55class GetCurrentBleedingEdgeVersion(Step):
56 MESSAGE = "Get latest bleeding edge version."
57
58 def RunStep(self):
Emily Bernierd0a1eb72015-03-24 16:35:39 -040059 self.GitCheckout("master")
Ben Murdochb8a8cc12014-11-26 15:28:44 +000060
61 # Store latest version and revision.
62 self.ReadAndPersistVersion()
63 self["latest_version"] = self.ArrayToVersion("")
64 self["latest"] = self.GitLog(n=1, format="%H")
65 print "Bleeding edge version: %s" % self["latest_version"]
66
67
68# This step is pure paranoia. It forbids the script to continue if the last
69# commit changed version.cc. Just in case the other bailout has a bug, this
70# prevents the script from continuously commiting version changes.
71class LastChangeBailout(Step):
72 MESSAGE = "Stop script if the last change modified the version."
73
74 def RunStep(self):
75 if VERSION_FILE in self.GitChangedFiles(self["latest"]):
76 print "Stop due to recent version change."
77 return True
78
79
80# TODO(machenbach): Implement this for git.
81class FetchLKGR(Step):
82 MESSAGE = "Fetching V8 LKGR."
83
84 def RunStep(self):
85 lkgr_url = "https://v8-status.appspot.com/lkgr"
86 self["lkgr_svn"] = self.ReadURL(lkgr_url, wait_plan=[5])
87
88
89# TODO(machenbach): Implement this for git. With a git lkgr we could simply
90# checkout that revision. With svn, we have to search backwards until that
91# revision is found.
92class GetLKGRVersion(Step):
93 MESSAGE = "Get bleeding edge lkgr version."
94
95 def RunStep(self):
Emily Bernierd0a1eb72015-03-24 16:35:39 -040096 self.GitCheckout("master")
Ben Murdochb8a8cc12014-11-26 15:28:44 +000097 # If the commit was made from svn, there is a mapping entry in the commit
98 # message.
99 self["lkgr"] = self.GitLog(
100 grep="^git-svn-id: [^@]*@%s [A-Za-z0-9-]*$" % self["lkgr_svn"],
101 format="%H")
102
103 # FIXME(machenbach): http://crbug.com/391712 can lead to svn lkgrs on the
104 # trunk branch (rarely).
105 if not self["lkgr"]: # pragma: no cover
106 self.Die("No git hash found for svn lkgr.")
107
108 self.GitCreateBranch(VERSION_BRANCH, self["lkgr"])
109 self.ReadAndPersistVersion("lkgr_")
110 self["lkgr_version"] = self.ArrayToVersion("lkgr_")
111 print "LKGR version: %s" % self["lkgr_version"]
112
113 # Ensure a clean version branch.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400114 self.GitCheckout("master")
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000115 self.DeleteBranch(VERSION_BRANCH)
116
117
118class LKGRVersionUpToDateBailout(Step):
119 MESSAGE = "Stop script if the lkgr has a renewed version."
120
121 def RunStep(self):
122 # If a version-change commit becomes the lkgr, don't bump up the version
123 # again.
124 if VERSION_FILE in self.GitChangedFiles(self["lkgr"]):
125 print "Stop because the lkgr is a version change itself."
126 return True
127
128 # Don't bump up the version if it got updated already after the lkgr.
129 if SortingKey(self["lkgr_version"]) < SortingKey(self["latest_version"]):
130 print("Stop because the latest version already changed since the lkgr "
131 "version.")
132 return True
133
134
135class GetTrunkVersion(Step):
136 MESSAGE = "Get latest trunk version."
137
138 def RunStep(self):
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400139 self.GitCheckout("candidates")
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000140 self.GitPull()
141 self.ReadAndPersistVersion("trunk_")
142 self["trunk_version"] = self.ArrayToVersion("trunk_")
143 print "Trunk version: %s" % self["trunk_version"]
144
145
146class CalculateVersion(Step):
147 MESSAGE = "Calculate the new version."
148
149 def RunStep(self):
150 if self["lkgr_build"] == "9999": # pragma: no cover
151 # If version control on bleeding edge was switched off, just use the last
152 # trunk version.
153 self["lkgr_version"] = self["trunk_version"]
154
155 # The new version needs to be greater than the max on bleeding edge and
156 # trunk.
157 max_version = max(self["trunk_version"],
158 self["lkgr_version"],
159 key=SortingKey)
160
161 # Strip off possible leading zeros.
162 self["new_major"], self["new_minor"], self["new_build"], _ = (
163 map(str, map(int, max_version.split("."))))
164
165 self["new_build"] = str(int(self["new_build"]) + 1)
166 self["new_patch"] = "0"
167
168 self["new_version"] = ("%s.%s.%s.0" %
169 (self["new_major"], self["new_minor"], self["new_build"]))
170 print "New version is %s" % self["new_version"]
171
172 if self._options.dry_run: # pragma: no cover
173 print "Dry run, skipping version change."
174 return True
175
176
177class CheckTreeStatus(Step):
178 MESSAGE = "Checking v8 tree status message."
179
180 def RunStep(self):
181 status_url = "https://v8-status.appspot.com/current?format=json"
182 status_json = self.ReadURL(status_url, wait_plan=[5, 20, 300, 300])
183 message = json.loads(status_json)["message"]
184 if re.search(r"maintenance|no commits", message, flags=re.I):
185 print "Skip version change by tree status: \"%s\"" % message
186 return True
187
188
189class ChangeVersion(Step):
190 MESSAGE = "Bump up the version."
191
192 def RunStep(self):
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400193 self.GitCreateBranch(VERSION_BRANCH, "master")
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000194
195 self.SetVersion(os.path.join(self.default_cwd, VERSION_FILE), "new_")
196
197 try:
198 msg = "[Auto-roll] Bump up version to %s" % self["new_version"]
199 self.GitCommit("%s\n\nTBR=%s" % (msg, self._options.author),
200 author=self._options.author)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400201 self.GitUpload(author=self._options.author,
202 force=self._options.force_upload,
203 bypass_hooks=True)
204 self.GitCLLand()
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000205 print "Successfully changed the version."
206 finally:
207 # Clean up.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400208 self.GitCheckout("master")
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000209 self.DeleteBranch(VERSION_BRANCH)
210
211
212class BumpUpVersion(ScriptsBase):
213 def _PrepareOptions(self, parser):
214 parser.add_argument("--dry_run", help="Don't commit the new version.",
215 default=False, action="store_true")
216
217 def _ProcessOptions(self, options): # pragma: no cover
218 if not options.dry_run and not options.author:
219 print "Specify your chromium.org email with -a"
220 return False
221 options.wait_for_lgtm = False
222 options.force_readline_defaults = True
223 options.force_upload = True
224 return True
225
226 def _Config(self):
227 return {
228 "PERSISTFILE_BASENAME": "/tmp/v8-bump-up-version-tempfile",
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400229 "PATCH_FILE": "/tmp/v8-bump-up-version-tempfile-patch-file",
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000230 }
231
232 def _Steps(self):
233 return [
234 Preparation,
235 GetCurrentBleedingEdgeVersion,
236 LastChangeBailout,
237 FetchLKGR,
238 GetLKGRVersion,
239 LKGRVersionUpToDateBailout,
240 GetTrunkVersion,
241 CalculateVersion,
242 CheckTreeStatus,
243 ChangeVersion,
244 ]
245
246if __name__ == "__main__": # pragma: no cover
247 sys.exit(BumpUpVersion().Run())