blob: a52a02869756f26131ee6ec45ae8ee73dc630f97 [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
6import argparse
7import sys
8
9from common_includes import *
10
11
12class Preparation(Step):
13 MESSAGE = "Preparation."
14
15 def RunStep(self):
Emily Bernierd0a1eb72015-03-24 16:35:39 -040016 # TODO(machenbach): Remove after the git switch.
17 if self.Config("PERSISTFILE_BASENAME") == "/tmp/v8-auto-tag-tempfile":
18 print "This script is disabled until after the v8 git migration."
19 return True
20
Ben Murdochb8a8cc12014-11-26 15:28:44 +000021 self.CommonPrepare()
22 self.PrepareBranch()
23 self.GitCheckout("master")
Emily Bernierd0a1eb72015-03-24 16:35:39 -040024 self.vc.Pull()
Ben Murdochb8a8cc12014-11-26 15:28:44 +000025
26
27class GetTags(Step):
28 MESSAGE = "Get all V8 tags."
29
30 def RunStep(self):
31 self.GitCreateBranch(self._config["BRANCHNAME"])
Emily Bernierd0a1eb72015-03-24 16:35:39 -040032 self["tags"] = self.vc.GetTags()
Ben Murdochb8a8cc12014-11-26 15:28:44 +000033
34
35class GetOldestUntaggedVersion(Step):
36 MESSAGE = "Check if there's a version on bleeding edge without a tag."
37
38 def RunStep(self):
39 tags = set(self["tags"])
40 self["candidate"] = None
41 self["candidate_version"] = None
42 self["next"] = None
43 self["next_version"] = None
44
45 # Iterate backwards through all automatic version updates.
46 for git_hash in self.GitLog(
47 format="%H", grep="\\[Auto\\-roll\\] Bump up version to").splitlines():
48
49 # Get the version.
50 if not self.GitCheckoutFileSafe(VERSION_FILE, git_hash):
51 continue
52
53 self.ReadAndPersistVersion()
54 version = self.ArrayToVersion("")
55
56 # Strip off trailing patch level (tags don't include tag level 0).
57 if version.endswith(".0"):
58 version = version[:-2]
59
60 # Clean up checked-out version file.
61 self.GitCheckoutFileSafe(VERSION_FILE, "HEAD")
62
63 if version in tags:
64 if self["candidate"]:
65 # Revision "git_hash" is tagged already and "candidate" was the next
66 # newer revision without a tag.
67 break
68 else:
69 print("Stop as %s is the latest version and it has been tagged." %
70 version)
71 self.CommonCleanup()
72 return True
73 else:
74 # This is the second oldest version without a tag.
75 self["next"] = self["candidate"]
76 self["next_version"] = self["candidate_version"]
77
78 # This is the oldest version without a tag.
79 self["candidate"] = git_hash
80 self["candidate_version"] = version
81
82 if not self["candidate"] or not self["candidate_version"]:
83 print "Nothing found to tag."
84 self.CommonCleanup()
85 return True
86
87 print("Candidate for tagging is %s with version %s" %
88 (self["candidate"], self["candidate_version"]))
89
90
91class GetLKGRs(Step):
92 MESSAGE = "Get the last lkgrs."
93
94 def RunStep(self):
95 revision_url = "https://v8-status.appspot.com/revisions?format=json"
96 status_json = self.ReadURL(revision_url, wait_plan=[5, 20])
97 self["lkgrs"] = [entry["revision"]
98 for entry in json.loads(status_json) if entry["status"]]
99
100
101class CalculateTagRevision(Step):
102 MESSAGE = "Calculate the revision to tag."
103
104 def LastLKGR(self, min_rev, max_rev):
105 """Finds the newest lkgr between min_rev (inclusive) and max_rev
106 (exclusive).
107 """
108 for lkgr in self["lkgrs"]:
109 # LKGRs are reverse sorted.
110 if int(min_rev) <= int(lkgr) and int(lkgr) < int(max_rev):
111 return lkgr
112 return None
113
114 def RunStep(self):
115 # Get the lkgr after the tag candidate and before the next tag candidate.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400116 candidate_svn = self.vc.GitSvn(self["candidate"])
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000117 if self["next"]:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400118 next_svn = self.vc.GitSvn(self["next"])
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000119 else:
120 # Don't include the version change commit itself if there is no upper
121 # limit yet.
122 candidate_svn = str(int(candidate_svn) + 1)
123 next_svn = sys.maxint
124 lkgr_svn = self.LastLKGR(candidate_svn, next_svn)
125
126 if not lkgr_svn:
127 print "There is no lkgr since the candidate version yet."
128 self.CommonCleanup()
129 return True
130
131 # Let's check if the lkgr is at least three hours old.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400132 self["lkgr"] = self.vc.SvnGit(lkgr_svn)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000133 if not self["lkgr"]:
134 print "Couldn't find git hash for lkgr %s" % lkgr_svn
135 self.CommonCleanup()
136 return True
137
138 lkgr_utc_time = int(self.GitLog(n=1, format="%at", git_hash=self["lkgr"]))
139 current_utc_time = self._side_effect_handler.GetUTCStamp()
140
141 if current_utc_time < lkgr_utc_time + 10800:
142 print "Candidate lkgr %s is too recent for tagging." % lkgr_svn
143 self.CommonCleanup()
144 return True
145
146 print "Tagging revision %s with %s" % (lkgr_svn, self["candidate_version"])
147
148
149class MakeTag(Step):
150 MESSAGE = "Tag the version."
151
152 def RunStep(self):
153 if not self._options.dry_run:
154 self.GitReset(self["lkgr"])
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400155 # FIXME(machenbach): Make this work with the git repo.
156 self.vc.Tag(self["candidate_version"],
157 "svn/bleeding_edge",
158 "This won't work!")
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000159
160
161class CleanUp(Step):
162 MESSAGE = "Clean up."
163
164 def RunStep(self):
165 self.CommonCleanup()
166
167
168class AutoTag(ScriptsBase):
169 def _PrepareOptions(self, parser):
170 parser.add_argument("--dry_run", help="Don't tag the new version.",
171 default=False, action="store_true")
172
173 def _ProcessOptions(self, options): # pragma: no cover
174 if not options.dry_run and not options.author:
175 print "Specify your chromium.org email with -a"
176 return False
177 options.wait_for_lgtm = False
178 options.force_readline_defaults = True
179 options.force_upload = True
180 return True
181
182 def _Config(self):
183 return {
184 "BRANCHNAME": "auto-tag-v8",
185 "PERSISTFILE_BASENAME": "/tmp/v8-auto-tag-tempfile",
186 }
187
188 def _Steps(self):
189 return [
190 Preparation,
191 GetTags,
192 GetOldestUntaggedVersion,
193 GetLKGRs,
194 CalculateTagRevision,
195 MakeTag,
196 CleanUp,
197 ]
198
199
200if __name__ == "__main__": # pragma: no cover
201 sys.exit(AutoTag().Run())