Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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 | |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 31 | # TODO(machenbach): Add vc interface that works on git mirror. |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 32 | class Preparation(Step): |
| 33 | MESSAGE = "Preparation." |
| 34 | |
| 35 | def RunStep(self): |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 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 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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 | |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 47 | self.GitCheckout("master") |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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): |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 59 | self.GitCheckout("master") |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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): |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 96 | self.GitCheckout("master") |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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. |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 114 | self.GitCheckout("master") |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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): |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 139 | self.GitCheckout("candidates") |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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): |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 193 | self.GitCreateBranch(VERSION_BRANCH, "master") |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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) |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 201 | self.GitUpload(author=self._options.author, |
| 202 | force=self._options.force_upload, |
| 203 | bypass_hooks=True) |
| 204 | self.GitCLLand() |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 205 | print "Successfully changed the version." |
| 206 | finally: |
| 207 | # Clean up. |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 208 | self.GitCheckout("master") |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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", |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 229 | "PATCH_FILE": "/tmp/v8-bump-up-version-tempfile-patch-file", |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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()) |