| OLD | NEW |
| (Empty) |
| 1 #!/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 """ | |
| 7 Script for auto-increasing the version on bleeding_edge. | |
| 8 | |
| 9 The script can be run regularly by a cron job. It will increase the build | |
| 10 level 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 | |
| 15 The new version will be the maximum of the bleeding_edge and trunk versions +1. | |
| 16 E.g. latest bleeding_edge version: 3.22.11.0 and latest trunk 3.23.0.0 gives | |
| 17 the new version 3.23.1.0. | |
| 18 | |
| 19 This script requires a depot tools git checkout. I.e. 'fetch v8'. | |
| 20 """ | |
| 21 | |
| 22 import argparse | |
| 23 import os | |
| 24 import sys | |
| 25 | |
| 26 from common_includes import * | |
| 27 | |
| 28 VERSION_BRANCH = "auto-bump-up-version" | |
| 29 | |
| 30 | |
| 31 # TODO(machenbach): Add vc interface that works on git mirror. | |
| 32 class Preparation(Step): | |
| 33 MESSAGE = "Preparation." | |
| 34 | |
| 35 def RunStep(self): | |
| 36 # 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 | |
| 42 # 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 | |
| 47 self.GitCheckout("master") | |
| 48 | |
| 49 self.GitPull() | |
| 50 | |
| 51 # Ensure a clean version branch. | |
| 52 self.DeleteBranch(VERSION_BRANCH) | |
| 53 | |
| 54 | |
| 55 class GetCurrentBleedingEdgeVersion(Step): | |
| 56 MESSAGE = "Get latest bleeding edge version." | |
| 57 | |
| 58 def RunStep(self): | |
| 59 self.GitCheckout("master") | |
| 60 | |
| 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. | |
| 71 class 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. | |
| 81 class 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. | |
| 92 class GetLKGRVersion(Step): | |
| 93 MESSAGE = "Get bleeding edge lkgr version." | |
| 94 | |
| 95 def RunStep(self): | |
| 96 self.GitCheckout("master") | |
| 97 # 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. | |
| 114 self.GitCheckout("master") | |
| 115 self.DeleteBranch(VERSION_BRANCH) | |
| 116 | |
| 117 | |
| 118 class 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 | |
| 135 class GetTrunkVersion(Step): | |
| 136 MESSAGE = "Get latest trunk version." | |
| 137 | |
| 138 def RunStep(self): | |
| 139 self.GitCheckout("candidates") | |
| 140 self.GitPull() | |
| 141 self.ReadAndPersistVersion("trunk_") | |
| 142 self["trunk_version"] = self.ArrayToVersion("trunk_") | |
| 143 print "Trunk version: %s" % self["trunk_version"] | |
| 144 | |
| 145 | |
| 146 class 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 | |
| 177 class 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 | |
| 189 class ChangeVersion(Step): | |
| 190 MESSAGE = "Bump up the version." | |
| 191 | |
| 192 def RunStep(self): | |
| 193 self.GitCreateBranch(VERSION_BRANCH, "master") | |
| 194 | |
| 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) | |
| 201 self.GitUpload(author=self._options.author, | |
| 202 force=self._options.force_upload, | |
| 203 bypass_hooks=True) | |
| 204 self.GitCLLand() | |
| 205 print "Successfully changed the version." | |
| 206 finally: | |
| 207 # Clean up. | |
| 208 self.GitCheckout("master") | |
| 209 self.DeleteBranch(VERSION_BRANCH) | |
| 210 | |
| 211 | |
| 212 class 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", | |
| 229 "PATCH_FILE": "/tmp/v8-bump-up-version-tempfile-patch-file", | |
| 230 } | |
| 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 | |
| 246 if __name__ == "__main__": # pragma: no cover | |
| 247 sys.exit(BumpUpVersion().Run()) | |
| OLD | NEW |