Revision: 22477
Author: [email protected]
Date: Fri Jul 18 12:16:14 2014 UTC
Log: Add automatic tag script.
The script can be run in a cron job to automatically tag
lkgrs.
BUG=391261
LOG=n
TEST=tools/push-to-trunk/script_test.py
TEST=tools/push-to-trunk/auto_tag.py --dry_run
[email protected]
Review URL: https://codereview.chromium.org/400693002
http://code.google.com/p/v8/source/detail?r=22477
Added:
/branches/bleeding_edge/tools/push-to-trunk/auto_tag.py
Modified:
/branches/bleeding_edge/tools/push-to-trunk/common_includes.py
/branches/bleeding_edge/tools/push-to-trunk/git_recipes.py
/branches/bleeding_edge/tools/push-to-trunk/test_scripts.py
=======================================
--- /dev/null
+++ /branches/bleeding_edge/tools/push-to-trunk/auto_tag.py Fri Jul 18
12:16:14 2014 UTC
@@ -0,0 +1,200 @@
+#!/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.
+
+import argparse
+import sys
+
+from common_includes import *
+
+CONFIG = {
+ BRANCHNAME: "auto-tag-v8",
+ PERSISTFILE_BASENAME: "/tmp/v8-auto-tag-tempfile",
+ DOT_GIT_LOCATION: ".git",
+ VERSION_FILE: "src/version.cc",
+}
+
+
+class Preparation(Step):
+ MESSAGE = "Preparation."
+
+ def RunStep(self):
+ self.CommonPrepare()
+ self.PrepareBranch()
+ self.GitCheckout("master")
+ self.GitSVNRebase()
+
+
+class GetTags(Step):
+ MESSAGE = "Get all V8 tags."
+
+ def RunStep(self):
+ self.GitCreateBranch(self._config[BRANCHNAME])
+
+ # Get remote tags.
+ tags = filter(lambda s: re.match(r"^svn/tags/[\d+\.]+$", s),
+ self.GitRemotes())
+
+ # Remove 'svn/tags/' prefix.
+ self["tags"] = map(lambda s: s[9:], tags)
+
+
+class GetOldestUntaggedVersion(Step):
+ MESSAGE = "Check if there's a version on bleeding edge without a tag."
+
+ def RunStep(self):
+ tags = set(self["tags"])
+ self["candidate"] = None
+ self["candidate_version"] = None
+ self["next"] = None
+ self["next_version"] = None
+
+ # Iterate backwards through all automatic version updates.
+ for git_hash in self.GitLog(
+ format="%H", grep="\\[Auto\\-roll\\] Bump up version
to").splitlines():
+
+ # Get the version.
+ if not self.GitCheckoutFileSafe(self._config[VERSION_FILE],
git_hash):
+ continue
+
+ self.ReadAndPersistVersion()
+ version = self.ArrayToVersion("")
+
+ # Strip off trailing patch level (tags don't include tag level 0).
+ if version.endswith(".0"):
+ version = version[:-2]
+
+ # Clean up checked-out version file.
+ self.GitCheckoutFileSafe(self._config[VERSION_FILE], "HEAD")
+
+ if version in tags:
+ if self["candidate"]:
+ # Revision "git_hash" is tagged already and "candidate" was the
next
+ # newer revision without a tag.
+ break
+ else:
+ print("Stop as %s is the latest version and it has been
tagged." %
+ version)
+ self.CommonCleanup()
+ return True
+ else:
+ # This is the second oldest version without a tag.
+ self["next"] = self["candidate"]
+ self["next_version"] = self["candidate_version"]
+
+ # This is the oldest version without a tag.
+ self["candidate"] = git_hash
+ self["candidate_version"] = version
+
+ if not self["candidate"] or not self["candidate_version"]:
+ print "Nothing found to tag."
+ self.CommonCleanup()
+ return True
+
+ print("Candidate for tagging is %s with version %s" %
+ (self["candidate"], self["candidate_version"]))
+
+
+class GetLKGRs(Step):
+ MESSAGE = "Get the last lkgrs."
+
+ def RunStep(self):
+ revision_url = "https://v8-status.appspot.com/revisions?format=json"
+ status_json = self.ReadURL(revision_url, wait_plan=[5, 20])
+ self["lkgrs"] = [entry["revision"]
+ for entry in json.loads(status_json) if
entry["status"]]
+
+
+class CalculateTagRevision(Step):
+ MESSAGE = "Calculate the revision to tag."
+
+ def LastLKGR(self, min_rev, max_rev):
+ """Finds the newest lkgr between min_rev (inclusive) and max_rev
+ (exclusive).
+ """
+ for lkgr in self["lkgrs"]:
+ # LKGRs are reverse sorted.
+ if int(min_rev) <= int(lkgr) and int(lkgr) < int(max_rev):
+ return lkgr
+ return None
+
+ def RunStep(self):
+ # Get the lkgr after the tag candidate and before the next tag
candidate.
+ candidate_svn = self.GitSVNFindSVNRev(self["candidate"])
+ if self["next"]:
+ next_svn = self.GitSVNFindSVNRev(self["next"])
+ else:
+ # Don't include the version change commit itself if there is no upper
+ # limit yet.
+ candidate_svn = str(int(candidate_svn) + 1)
+ next_svn = sys.maxint
+ lkgr_svn = self.LastLKGR(candidate_svn, next_svn)
+
+ if not lkgr_svn:
+ print "There is no lkgr since the candidate version yet."
+ self.CommonCleanup()
+ return True
+
+ # Let's check if the lkgr is at least three hours old.
+ self["lkgr"] = self.GitSVNFindGitHash(lkgr_svn)
+ if not self["lkgr"]:
+ print "Couldn't find git hash for lkgr %s" % lkgr_svn
+ self.CommonCleanup()
+ return True
+
+ lkgr_utc_time = int(self.GitLog(n=1, format="%at",
git_hash=self["lkgr"]))
+ current_utc_time = self._side_effect_handler.GetUTCStamp()
+
+ if current_utc_time < lkgr_utc_time + 10800:
+ print "Candidate lkgr %s is too recent for tagging." % lkgr_svn
+ self.CommonCleanup()
+ return True
+
+ print "Tagging revision %s with %s" % (lkgr_svn,
self["candidate_version"])
+
+
+class MakeTag(Step):
+ MESSAGE = "Tag the version."
+
+ def RunStep(self):
+ if not self._options.dry_run:
+ self.GitReset(self["lkgr"])
+ self.GitSVNTag(self["candidate_version"])
+
+
+class CleanUp(Step):
+ MESSAGE = "Clean up."
+
+ def RunStep(self):
+ self.CommonCleanup()
+
+
+class AutoTag(ScriptsBase):
+ def _PrepareOptions(self, parser):
+ parser.add_argument("--dry_run", help="Don't tag 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,
+ GetTags,
+ GetOldestUntaggedVersion,
+ GetLKGRs,
+ CalculateTagRevision,
+ MakeTag,
+ CleanUp,
+ ]
+
+
+if __name__ == "__main__": # pragma: no cover
+ sys.exit(AutoTag(CONFIG).Run())
=======================================
--- /branches/bleeding_edge/tools/push-to-trunk/common_includes.py Wed Jul
16 07:57:13 2014 UTC
+++ /branches/bleeding_edge/tools/push-to-trunk/common_includes.py Fri Jul
18 12:16:14 2014 UTC
@@ -244,6 +244,9 @@
def GetDate(self):
return datetime.date.today().strftime("%Y-%m-%d")
+ def GetUTCStamp(self):
+ time.mktime(datetime.datetime.utcnow().timetuple())
+
DEFAULT_SIDE_EFFECT_HANDLER = SideEffectHandler()
=======================================
--- /branches/bleeding_edge/tools/push-to-trunk/git_recipes.py Wed Jul 16
07:57:13 2014 UTC
+++ /branches/bleeding_edge/tools/push-to-trunk/git_recipes.py Fri Jul 18
12:16:14 2014 UTC
@@ -185,6 +185,9 @@
def GitSVNFetch(self):
self.Git("svn fetch")
+ def GitSVNRebase(self):
+ self.Git("svn rebase")
+
# TODO(machenbach): Unused? Remove.
@Strip
def GitSVNLog(self):
=======================================
--- /branches/bleeding_edge/tools/push-to-trunk/test_scripts.py Wed Jul 16
07:57:13 2014 UTC
+++ /branches/bleeding_edge/tools/push-to-trunk/test_scripts.py Fri Jul 18
12:16:14 2014 UTC
@@ -52,6 +52,7 @@
from bump_up_version import BumpUpVersion
from bump_up_version import LastChangeBailout
from bump_up_version import LKGRVersionUpToDateBailout
+from auto_tag import AutoTag
TEST_CONFIG = {
@@ -401,6 +402,9 @@
def GetDate(self):
return "1999-07-31"
+ def GetUTCStamp(self):
+ return "100000"
+
def ExpectGit(self, *args):
"""Convenience wrapper."""
self._git_mock.Expect(*args)
@@ -1323,6 +1327,57 @@
BumpUpVersion(TEST_CONFIG, self).Run(["-a", "[email protected]"])
+ def testAutoTag(self):
+ TEST_CONFIG[VERSION_FILE] = self.MakeEmptyTempFile()
+ self.WriteFakeVersionFile()
+
+ def ResetVersion(minor, build, patch=0):
+ return lambda: self.WriteFakeVersionFile(minor=minor,
+ build=build,
+ patch=patch)
+
+ self.ExpectGit([
+ Git("status -s -uno", ""),
+ Git("status -s -b -uno", "## some_branch\n"),
+ Git("svn fetch", ""),
+ Git("branch", " branch1\n* branch2\n"),
+ Git("checkout -f master", ""),
+ Git("svn rebase", ""),
+ Git("checkout -b %s" % TEST_CONFIG[BRANCHNAME], "",
+ cb=ResetVersion(4, 5)),
+ Git("branch
-r", "svn/tags/3.4.2\nsvn/tags/3.2.1.0\nsvn/branches/3.4"),
+ Git("log --format=%H --grep=\"\\[Auto\\-roll\\] Bump up version
to\"",
+ "hash125\nhash118\nhash111\nhash101"),
+ Git("checkout -f hash125 -- %s" % TEST_CONFIG[VERSION_FILE], "",
+ cb=ResetVersion(4, 4)),
+ Git("checkout -f HEAD -- %s" % TEST_CONFIG[VERSION_FILE], "",
+ cb=ResetVersion(4, 5)),
+ Git("checkout -f hash118 -- %s" % TEST_CONFIG[VERSION_FILE], "",
+ cb=ResetVersion(4, 3)),
+ Git("checkout -f HEAD -- %s" % TEST_CONFIG[VERSION_FILE], "",
+ cb=ResetVersion(4, 5)),
+ Git("checkout -f hash111 -- %s" % TEST_CONFIG[VERSION_FILE], "",
+ cb=ResetVersion(4, 2)),
+ Git("checkout -f HEAD -- %s" % TEST_CONFIG[VERSION_FILE], "",
+ cb=ResetVersion(4, 5)),
+ Git("svn find-rev hash118", "118"),
+ Git("svn find-rev hash125", "125"),
+ Git("svn find-rev r123", "hash123"),
+ Git("log -1 --format=%at hash123", "1"),
+ Git("reset --hard hash123", ""),
+ Git("svn tag 3.4.3 -m \"Tagging version 3.4.3\"", ""),
+ Git("checkout -f some_branch", ""),
+ Git("branch -D %s" % TEST_CONFIG[BRANCHNAME], ""),
+ ])
+
+ self.ExpectReadURL([
+ URL("https://v8-status.appspot.com/revisions?format=json",
+ "[{\"revision\": \"123\", \"status\": true},"
+ "{\"revision\": \"112\", \"status\": true}]"),
+ ])
+
+ AutoTag(TEST_CONFIG, self).Run(["-a", "[email protected]"])
+
# Test that we bail out if the last change was a version change.
def testBumpUpVersionBailout1(self):
TEST_CONFIG[VERSION_FILE] = self.MakeEmptyTempFile()
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.