Index: tools/push-to-trunk/bump_up_version.py |
diff --git a/tools/push-to-trunk/bump_up_version.py b/tools/push-to-trunk/bump_up_version.py |
new file mode 100755 |
index 0000000000000000000000000000000000000000..31d834fe4a27c6e3b2304d61b2faf1322ff1deaf |
--- /dev/null |
+++ b/tools/push-to-trunk/bump_up_version.py |
@@ -0,0 +1,240 @@ |
+#!/usr/bin/env python |
+# Copyright 2014 the V8 project authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+""" |
+Script for auto-increasing the version on bleeding_edge. |
+ |
+The script can be run regularly by a cron job. It will increase the build |
+level of the version on bleeding_edge if: |
+- the lkgr version is smaller than the version of the latest revision, |
+- the lkgr version is not a version change itself, |
+- the tree is not closed for maintenance. |
+ |
+The new version will be the maximum of the bleeding_edge and trunk versions +1. |
+E.g. latest bleeding_edge version: 3.22.11.0 and latest trunk 3.23.0.0 gives |
+the new version 3.23.1.0. |
+ |
+This script requires a depot tools git checkout. I.e. 'fetch v8'. |
+""" |
+ |
+import argparse |
+import os |
+import sys |
+ |
+from common_includes import * |
+ |
+CONFIG = { |
+ PERSISTFILE_BASENAME: "/tmp/v8-bump-up-version-tempfile", |
+ VERSION_FILE: "src/version.cc", |
+} |
+ |
+VERSION_BRANCH = "auto-bump-up-version" |
+ |
+ |
+class Preparation(Step): |
+ MESSAGE = "Preparation." |
+ |
+ def RunStep(self): |
+ # Check for a clean workdir. |
+ if not self.GitIsWorkdirClean(): # pragma: no cover |
+ # This is in case a developer runs this script on a dirty tree. |
+ self.GitStash() |
+ |
+ # TODO(machenbach): This should be called master after the git switch. |
+ self.GitCheckout("bleeding_edge") |
+ |
+ self.GitPull() |
+ |
+ # Ensure a clean version branch. |
+ self.DeleteBranch(VERSION_BRANCH) |
+ |
+ |
+class GetCurrentBleedingEdgeVersion(Step): |
+ MESSAGE = "Get latest bleeding edge version." |
+ |
+ def RunStep(self): |
+ # TODO(machenbach): This should be called master after the git switch. |
+ self.GitCheckout("bleeding_edge") |
+ |
+ # Store latest version and revision. |
+ self.ReadAndPersistVersion() |
+ self["latest_version"] = self.ArrayToVersion("") |
+ self["latest"] = self.GitLog(n=1, format="%H") |
+ print "Bleeding edge version: %s" % self["latest_version"] |
+ |
+ |
+# This step is pure paranoia. It forbids the script to continue if the last |
+# commit changed version.cc. Just in case the other bailout has a bug, this |
+# prevents the script from continuously commiting version changes. |
+class LastChangeBailout(Step): |
+ MESSAGE = "Stop script if the last change modified the version." |
+ |
+ def RunStep(self): |
+ if self._config[VERSION_FILE] in self.GitChangedFiles(self["latest"]): |
+ print "Stop due to recent version change." |
+ return True |
+ |
+ |
+# TODO(machenbach): Implement this for git. |
+class FetchLKGR(Step): |
+ MESSAGE = "Fetching V8 LKGR." |
+ |
+ def RunStep(self): |
+ lkgr_url = "https://v8-status.appspot.com/lkgr" |
+ self["lkgr_svn"] = self.ReadURL(lkgr_url, wait_plan=[5]) |
+ |
+ |
+# TODO(machenbach): Implement this for git. With a git lkgr we could simply |
+# checkout that revision. With svn, we have to search backwards until that |
+# revision is found. |
+class GetLKGRVersion(Step): |
+ MESSAGE = "Get bleeding edge lkgr version." |
+ |
+ def RunStep(self): |
+ self.GitCheckout("bleeding_edge") |
+ # If the commit was made from svn, there is a mapping entry in the commit |
+ # message. |
+ self["lkgr"] = self.GitLog( |
+ grep="^git-svn-id: [^@]*@%s [A-Za-z0-9-]*$" % self["lkgr_svn"], |
+ format="%H") |
+ |
+ # FIXME(machenbach): http://crbug.com/391712 can lead to svn lkgrs on the |
+ # trunk branch (rarely). |
+ if not self["lkgr"]: # pragma: no cover |
+ self.Die("No git hash found for svn lkgr.") |
+ |
+ self.GitCreateBranch(VERSION_BRANCH, self["lkgr"]) |
+ self.ReadAndPersistVersion("lkgr_") |
+ self["lkgr_version"] = self.ArrayToVersion("lkgr_") |
+ print "LKGR version: %s" % self["lkgr_version"] |
+ |
+ # Ensure a clean version branch. |
+ self.GitCheckout("bleeding_edge") |
+ self.DeleteBranch(VERSION_BRANCH) |
+ |
+ |
+class LKGRVersionUpToDateBailout(Step): |
+ MESSAGE = "Stop script if the lkgr has a renewed version." |
+ |
+ def RunStep(self): |
+ # If a version-change commit becomes the lkgr, don't bump up the version |
+ # again. |
+ if self._config[VERSION_FILE] in self.GitChangedFiles(self["lkgr"]): |
+ print "Stop because the lkgr is a version change itself." |
+ return True |
+ |
+ # Don't bump up the version if it got updated already after the lkgr. |
+ if SortingKey(self["lkgr_version"]) < SortingKey(self["latest_version"]): |
+ print("Stop because the latest version already changed since the lkgr " |
+ "version.") |
+ return True |
+ |
+ |
+class GetTrunkVersion(Step): |
+ MESSAGE = "Get latest trunk version." |
+ |
+ def RunStep(self): |
+ # TODO(machenbach): This should be called trunk after the git switch. |
+ self.GitCheckout("master") |
+ self.GitPull() |
+ self.ReadAndPersistVersion("trunk_") |
+ self["trunk_version"] = self.ArrayToVersion("trunk_") |
+ print "Trunk version: %s" % self["trunk_version"] |
+ |
+ |
+class CalculateVersion(Step): |
+ MESSAGE = "Calculate the new version." |
+ |
+ def RunStep(self): |
+ if self["lkgr_build"] == "9999": # pragma: no cover |
+ # If version control on bleeding edge was switched off, just use the last |
+ # trunk version. |
+ self["lkgr_version"] = self["trunk_version"] |
+ |
+ # The new version needs to be greater than the max on bleeding edge and |
+ # trunk. |
+ max_version = max(self["trunk_version"], |
+ self["lkgr_version"], |
+ key=SortingKey) |
+ |
+ # Strip off possible leading zeros. |
+ self["new_major"], self["new_minor"], self["new_build"], _ = ( |
+ map(str, map(int, max_version.split(".")))) |
+ |
+ self["new_build"] = str(int(self["new_build"]) + 1) |
+ self["new_patch"] = "0" |
+ |
+ self["new_version"] = ("%s.%s.%s.0" % |
+ (self["new_major"], self["new_minor"], self["new_build"])) |
+ print "New version is %s" % self["new_version"] |
+ |
+ if self._options.dry_run: # pragma: no cover |
+ print "Dry run, skipping version change." |
+ return True |
+ |
+ |
+class CheckTreeStatus(Step): |
+ MESSAGE = "Checking v8 tree status message." |
+ |
+ def RunStep(self): |
+ status_url = "https://v8-status.appspot.com/current?format=json" |
+ status_json = self.ReadURL(status_url, wait_plan=[5, 20, 300, 300]) |
+ message = json.loads(status_json)["message"] |
+ if re.search(r"maintenance|no commits", message, flags=re.I): |
+ print "Skip version change by tree status: \"%s\"" % message |
+ return True |
+ |
+ |
+class ChangeVersion(Step): |
+ MESSAGE = "Bump up the version." |
+ |
+ def RunStep(self): |
+ self.GitCreateBranch(VERSION_BRANCH, "bleeding_edge") |
+ |
+ self.SetVersion(self.Config(VERSION_FILE), "new_") |
+ |
+ try: |
+ self.GitCommit("[Auto-roll] Bump up version to %s\n\nTBR=%s" % |
+ (self["new_version"], self._options.author)) |
+ self.GitUpload(author=self._options.author, |
+ force=self._options.force_upload) |
+ self.GitDCommit() |
+ print "Successfully changed the version." |
+ finally: |
+ # Clean up. |
+ self.GitCheckout("bleeding_edge") |
+ self.DeleteBranch(VERSION_BRANCH) |
+ |
+ |
+class BumpUpVersion(ScriptsBase): |
+ def _PrepareOptions(self, parser): |
+ parser.add_argument("--dry_run", help="Don't commit the new version.", |
+ default=False, action="store_true") |
+ |
+ def _ProcessOptions(self, options): # pragma: no cover |
+ if not options.dry_run and not options.author: |
+ print "Specify your chromium.org email with -a" |
+ return False |
+ options.wait_for_lgtm = False |
+ options.force_readline_defaults = True |
+ options.force_upload = True |
+ return True |
+ |
+ def _Steps(self): |
+ return [ |
+ Preparation, |
+ GetCurrentBleedingEdgeVersion, |
+ LastChangeBailout, |
+ FetchLKGR, |
+ GetLKGRVersion, |
+ LKGRVersionUpToDateBailout, |
+ GetTrunkVersion, |
+ CalculateVersion, |
+ CheckTreeStatus, |
+ ChangeVersion, |
+ ] |
+ |
+if __name__ == "__main__": # pragma: no cover |
+ sys.exit(BumpUpVersion(CONFIG).Run()) |