blob: e9757452f5423b7841a1648a929c95f2f55d5818 [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2012 The ChromiumOS Authors
Chris Sosadad0d322011-01-31 16:37:33 -08002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""This module uprevs Chrome for cbuildbot.
6
7After calling, it prints outs CHROME_VERSION_ATOM=(version atom string). A
8caller could then use this atom with emerge to build the newly uprevved version
9of Chrome e.g.
10
11./cros_mark_chrome_as_stable tot
12Returns chrome-base/chromeos-chrome-8.0.552.0_alpha_r1
13
14emerge-x86-generic =chrome-base/chromeos-chrome-8.0.552.0_alpha_r1
15"""
16
Stefan Zagerd49d9ff2014-08-15 21:33:37 -070017import base64
Mike Frysingera94f1252019-09-12 02:39:28 -040018import distutils.version # pylint: disable=import-error,no-name-in-module
Chris Sosa8be39132011-04-14 12:09:24 -070019import filecmp
Chris McDonaldb55b7032021-06-17 16:41:32 -060020import logging
Chris Sosadad0d322011-01-31 16:37:33 -080021import os
22import re
Mike Frysingere852b072021-05-21 12:39:03 -040023import urllib.parse
Chris Sosadad0d322011-01-31 16:37:33 -080024
Chris McDonaldb55b7032021-06-17 16:41:32 -060025from chromite.cbuildbot import cbuildbot_alerts
Mike Frysingera13c04f2016-09-01 00:35:17 -040026from chromite.lib import commandline
Chris McDonaldb55b7032021-06-17 16:41:32 -060027from chromite.lib import constants
David James1b363582012-12-17 11:53:11 -080028from chromite.lib import cros_build_lib
David James97d95872012-11-16 15:09:56 -080029from chromite.lib import git
Stefan Zagerd49d9ff2014-08-15 21:33:37 -070030from chromite.lib import gob_util
Alex Deymo075c2292014-09-04 18:31:50 -070031from chromite.lib import portage_util
Stefan Zagerd49d9ff2014-08-15 21:33:37 -070032from chromite.lib import timeout_util
Mike Frysinger6cb624a2012-05-24 18:17:38 -040033from chromite.scripts import cros_mark_as_stable
Chris Sosadad0d322011-01-31 16:37:33 -080034
Mike Frysinger807d8282022-04-28 22:45:17 -040035
Chris Sosadad0d322011-01-31 16:37:33 -080036# Helper regex's for finding ebuilds.
Alex Klein1699fab2022-09-08 08:46:06 -060037_CHROME_VERSION_REGEX = r"\d+\.\d+\.\d+\.\d+"
38_NON_STICKY_REGEX = r"%s[(_rc.*)|(_alpha.*)]+" % _CHROME_VERSION_REGEX
Chris Sosadad0d322011-01-31 16:37:33 -080039
40# Dir where all the action happens.
Alex Klein1699fab2022-09-08 08:46:06 -060041_OVERLAY_DIR = "%(srcroot)s/third_party/chromiumos-overlay/"
Chris Sosadad0d322011-01-31 16:37:33 -080042
Alex Klein1699fab2022-09-08 08:46:06 -060043_GIT_COMMIT_MESSAGE = (
44 "Marking %(chrome_rev)s for %(chrome_pn)s ebuild "
45 "with version %(chrome_version)s as stable."
46)
Chris Sosadad0d322011-01-31 16:37:33 -080047
Chris Masone592cab52011-08-02 14:05:48 -070048# URLs that print lists of chrome revisions between two versions of the browser.
Alex Klein1699fab2022-09-08 08:46:06 -060049_CHROME_VERSION_URL = (
50 "http://omahaproxy.appspot.com/changelog?"
51 "old_version=%(old)s&new_version=%(new)s"
52)
Chris Sosadd611df2012-02-03 15:26:23 -080053
54# Only print links when we rev these types.
Alex Klein1699fab2022-09-08 08:46:06 -060055_REV_TYPES_FOR_LINKS = [
56 constants.CHROME_REV_LATEST,
57 constants.CHROME_REV_STICKY,
58]
Chris Masone592cab52011-08-02 14:05:48 -070059
ChromeOS Developer03118eb2013-02-12 14:27:09 -080060
petermayo@chromium.org163b3372011-09-12 02:06:05 -040061def _GetVersionContents(chrome_version_info):
Alex Klein68b270c2023-04-14 14:42:50 -060062 """Get the current Chromium version, from the contents of a VERSION file.
Chris Sosadad0d322011-01-31 16:37:33 -080063
Alex Klein1699fab2022-09-08 08:46:06 -060064 Args:
Alex Klein68b270c2023-04-14 14:42:50 -060065 chrome_version_info: The contents of a chromium VERSION file.
Alex Klein1699fab2022-09-08 08:46:06 -060066 """
67 chrome_version_array = []
68 for line in chrome_version_info.splitlines():
69 chrome_version_array.append(line.rpartition("=")[2])
Chris Sosadad0d322011-01-31 16:37:33 -080070
Alex Klein1699fab2022-09-08 08:46:06 -060071 return ".".join(chrome_version_array)
Chris Sosadad0d322011-01-31 16:37:33 -080072
Mike Frysingercc838832014-05-24 13:10:30 -040073
Stefan Zagerd49d9ff2014-08-15 21:33:37 -070074def _GetSpecificVersionUrl(git_url, revision, time_to_wait=600):
Alex Klein1699fab2022-09-08 08:46:06 -060075 """Returns the Chromium version, from a repository URL and version.
Peter Mayo177500f2011-09-09 17:25:23 -040076
Alex Klein1699fab2022-09-08 08:46:06 -060077 Args:
Alex Klein68b270c2023-04-14 14:42:50 -060078 git_url: Repository URL for chromium.
79 revision: the git revision we want to use.
80 time_to_wait: the minimum period before abandoning our wait for the
81 desired revision to be present.
Alex Klein1699fab2022-09-08 08:46:06 -060082 """
83 parsed_url = urllib.parse.urlparse(git_url)
84 host = parsed_url[1]
85 path = parsed_url[2].rstrip("/") + (
86 "/+/%s/chrome/VERSION?format=text" % revision
87 )
petermayo@chromium.org163b3372011-09-12 02:06:05 -040088
Alex Klein1699fab2022-09-08 08:46:06 -060089 # Allow for git repository replication lag with sleep/retry loop.
90 def _fetch():
91 return gob_util.FetchUrl(host, path, ignore_404=True)
petermayo@chromium.org163b3372011-09-12 02:06:05 -040092
Alex Klein1699fab2022-09-08 08:46:06 -060093 def _wait_msg(_remaining):
94 logging.info(
95 "Repository does not yet have revision %s. Sleeping...", revision
96 )
petermayo@chromium.org163b3372011-09-12 02:06:05 -040097
Alex Klein1699fab2022-09-08 08:46:06 -060098 content = timeout_util.WaitForSuccess(
99 retry_check=lambda x: not bool(x),
100 func=_fetch,
101 timeout=time_to_wait,
102 period=30,
103 side_effect_func=_wait_msg,
104 )
105 return _GetVersionContents(base64.b64decode(content).decode("utf-8"))
petermayo@chromium.org163b3372011-09-12 02:06:05 -0400106
Peter Mayo177500f2011-09-09 17:25:23 -0400107
108def _GetTipOfTrunkVersionFile(root):
Alex Klein1699fab2022-09-08 08:46:06 -0600109 """Returns the current Chromium version, from a file in a checkout.
Peter Mayo177500f2011-09-09 17:25:23 -0400110
Alex Klein1699fab2022-09-08 08:46:06 -0600111 Args:
Alex Klein68b270c2023-04-14 14:42:50 -0600112 root: path to the root of the chromium checkout.
Alex Klein1699fab2022-09-08 08:46:06 -0600113 """
114 version_file = os.path.join(root, "src", "chrome", "VERSION")
115 try:
116 chrome_version_info = cros_build_lib.run(
117 ["cat", version_file], stdout=True
118 ).stdout
119 except cros_build_lib.RunCommandError as e:
120 e.msg += "\nCould not read version file at %s." % version_file
121 raise e
Peter Mayo177500f2011-09-09 17:25:23 -0400122
Alex Klein1699fab2022-09-08 08:46:06 -0600123 return _GetVersionContents(chrome_version_info)
Peter Mayo177500f2011-09-09 17:25:23 -0400124
ChromeOS Developer03118eb2013-02-12 14:27:09 -0800125
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700126def CheckIfChromeRightForOS(deps_content):
Alex Klein1699fab2022-09-08 08:46:06 -0600127 """Checks if DEPS is right for Chrome OS.
Dharani Govindan4beb94c2014-07-18 13:31:47 -0700128
Alex Klein1699fab2022-09-08 08:46:06 -0600129 This function checks for a variable called 'buildspec_platforms' to
130 find out if its 'chromeos' or 'all'. If any of those values,
131 then it chooses that DEPS.
Dharani Govindan4beb94c2014-07-18 13:31:47 -0700132
Alex Klein1699fab2022-09-08 08:46:06 -0600133 Args:
Alex Klein68b270c2023-04-14 14:42:50 -0600134 deps_content: Content of release buildspec DEPS file.
Dharani Govindan4beb94c2014-07-18 13:31:47 -0700135
Alex Klein1699fab2022-09-08 08:46:06 -0600136 Returns:
Alex Klein68b270c2023-04-14 14:42:50 -0600137 True if DEPS is the right Chrome for Chrome OS.
Alex Klein1699fab2022-09-08 08:46:06 -0600138 """
139 platforms_search = re.search(r"buildspec_platforms.*\s.*\s", deps_content)
Dharani Govindancbbf69c2014-07-29 15:37:39 -0700140
Alex Klein1699fab2022-09-08 08:46:06 -0600141 if platforms_search:
142 platforms = platforms_search.group()
143 if "chromeos" in platforms or "all" in platforms:
144 return True
Dharani Govindan4beb94c2014-07-18 13:31:47 -0700145
Alex Klein1699fab2022-09-08 08:46:06 -0600146 return False
Dharani Govindan4beb94c2014-07-18 13:31:47 -0700147
148
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700149def GetLatestRelease(git_url, branch=None):
Alex Klein1699fab2022-09-08 08:46:06 -0600150 """Gets the latest release version from the release tags in the repository.
Chris Sosadad0d322011-01-31 16:37:33 -0800151
Alex Klein1699fab2022-09-08 08:46:06 -0600152 Args:
Alex Klein68b270c2023-04-14 14:42:50 -0600153 git_url: URL of git repository.
154 branch: If set, gets the latest release for branch, otherwise latest
155 release.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500156
Alex Klein1699fab2022-09-08 08:46:06 -0600157 Returns:
Alex Klein68b270c2023-04-14 14:42:50 -0600158 Latest version string.
Alex Klein1699fab2022-09-08 08:46:06 -0600159 """
Alex Klein68b270c2023-04-14 14:42:50 -0600160 # TODO(szager): This only works for public release buildspecs in the
161 # chromium src repository. Internal buildspecs are tracked differently. At
162 # the time of writing, I can't find any callers that use this method to scan
163 # for internal buildspecs. But there may be something lurking...
Stefan Zagerd49d9ff2014-08-15 21:33:37 -0700164
Alex Klein1699fab2022-09-08 08:46:06 -0600165 parsed_url = urllib.parse.urlparse(git_url)
166 path = parsed_url[2].rstrip("/") + "/+refs/tags?format=JSON"
167 j = gob_util.FetchUrlJson(parsed_url[1], path, ignore_404=False)
168 if branch:
169 chrome_version_re = re.compile(r"^%s\.\d+.*" % branch)
170 else:
171 chrome_version_re = re.compile(r"^[0-9]+\..*")
172 matching_versions = [
173 key for key in j.keys() if chrome_version_re.match(key)
174 ]
175 matching_versions.sort(key=distutils.version.LooseVersion)
176 for chrome_version in reversed(matching_versions):
177 path = parsed_url[2].rstrip() + (
178 "/+/refs/tags/%s/DEPS?format=text" % chrome_version
179 )
180 content = gob_util.FetchUrl(parsed_url[1], path, ignore_404=False)
181 if content:
182 deps_content = base64.b64decode(content).decode("utf-8")
183 if CheckIfChromeRightForOS(deps_content):
184 return chrome_version
Peter Mayoad8173d2011-11-08 16:18:23 -0500185
Alex Klein1699fab2022-09-08 08:46:06 -0600186 return None
Chris Sosadad0d322011-01-31 16:37:33 -0800187
188
189def _GetStickyEBuild(stable_ebuilds):
Alex Klein1699fab2022-09-08 08:46:06 -0600190 """Returns the sticky ebuild."""
191 sticky_ebuilds = []
192 non_sticky_re = re.compile(_NON_STICKY_REGEX)
193 for ebuild in stable_ebuilds:
194 if not non_sticky_re.match(ebuild.version):
195 sticky_ebuilds.append(ebuild)
Chris Sosadad0d322011-01-31 16:37:33 -0800196
Alex Klein1699fab2022-09-08 08:46:06 -0600197 if not sticky_ebuilds:
198 raise Exception("No sticky ebuilds found")
199 elif len(sticky_ebuilds) > 1:
200 logging.warning("More than one sticky ebuild found:")
201 for ebuild in sticky_ebuilds:
202 logging.warning(" %s", ebuild.ebuild_path)
203 logging.warning("Make sure to *not* create xxx.0-r1.ebuilds")
Chris Sosadad0d322011-01-31 16:37:33 -0800204
Alex Klein1699fab2022-09-08 08:46:06 -0600205 return portage_util.BestEBuild(sticky_ebuilds)
Chris Sosadad0d322011-01-31 16:37:33 -0800206
207
Alex Deymo075c2292014-09-04 18:31:50 -0700208class ChromeEBuild(portage_util.EBuild):
Alex Klein1699fab2022-09-08 08:46:06 -0600209 """Thin sub-class of EBuild that adds a chrome_version field."""
Chris Sosadad0d322011-01-31 16:37:33 -0800210
Alex Klein1699fab2022-09-08 08:46:06 -0600211 chrome_version_re = re.compile(r".*-(%s|9999).*" % (_CHROME_VERSION_REGEX))
212 chrome_version = ""
Chris Sosadad0d322011-01-31 16:37:33 -0800213
Alex Klein1699fab2022-09-08 08:46:06 -0600214 def __init__(self, path):
215 portage_util.EBuild.__init__(self, path)
Jack Rosenthal451b0262023-09-13 12:52:16 -0600216 re_match = self.chrome_version_re.match(
217 str(self.ebuild_path_no_revision)
218 )
Alex Klein1699fab2022-09-08 08:46:06 -0600219 if re_match:
220 self.chrome_version = re_match.group(1)
221
222 def __str__(self):
Jack Rosenthal451b0262023-09-13 12:52:16 -0600223 return str(self.ebuild_path)
Chris Sosadad0d322011-01-31 16:37:33 -0800224
225
David Zeuthen665d3132014-08-25 15:27:02 -0400226def FindChromeCandidates(package_dir):
Alex Klein1699fab2022-09-08 08:46:06 -0600227 """Return a tuple of chrome's unstable ebuild and stable ebuilds.
Chris Sosadad0d322011-01-31 16:37:33 -0800228
Alex Klein1699fab2022-09-08 08:46:06 -0600229 Args:
Alex Klein68b270c2023-04-14 14:42:50 -0600230 package_dir: The path to where the package ebuild is stored.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500231
Alex Klein1699fab2022-09-08 08:46:06 -0600232 Returns:
Alex Klein68b270c2023-04-14 14:42:50 -0600233 Tuple [unstable_ebuild, stable_ebuilds].
Mike Frysinger1a736a82013-12-12 01:50:59 -0500234
Alex Klein1699fab2022-09-08 08:46:06 -0600235 Raises:
Alex Klein68b270c2023-04-14 14:42:50 -0600236 Exception: if no unstable ebuild exists for Chrome.
Alex Klein1699fab2022-09-08 08:46:06 -0600237 """
238 stable_ebuilds = []
239 unstable_ebuilds = []
240 for path in [
241 os.path.join(package_dir, entry) for entry in os.listdir(package_dir)
242 ]:
243 if path.endswith(".ebuild"):
244 ebuild = ChromeEBuild(path)
245 if not ebuild.chrome_version:
246 logging.warning("Poorly formatted ebuild found at %s", path)
247 else:
248 if "9999" in ebuild.version:
249 unstable_ebuilds.append(ebuild)
250 else:
251 stable_ebuilds.append(ebuild)
Chris Sosadad0d322011-01-31 16:37:33 -0800252
Alex Klein1699fab2022-09-08 08:46:06 -0600253 # Apply some confidence checks.
254 if not unstable_ebuilds:
255 raise Exception("Missing 9999 ebuild for %s" % package_dir)
256 if not stable_ebuilds:
257 logging.warning("Missing stable ebuild for %s", package_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800258
Alex Klein1699fab2022-09-08 08:46:06 -0600259 return portage_util.BestEBuild(unstable_ebuilds), stable_ebuilds
Chris Sosadad0d322011-01-31 16:37:33 -0800260
261
262def FindChromeUprevCandidate(stable_ebuilds, chrome_rev, sticky_branch):
Alex Klein1699fab2022-09-08 08:46:06 -0600263 """Finds the Chrome uprev candidate for the given chrome_rev.
Chris Sosadad0d322011-01-31 16:37:33 -0800264
Alex Klein1699fab2022-09-08 08:46:06 -0600265 Using the pre-flight logic, this means the stable ebuild you are uprevving
266 from. The difference here is that the version could be different and in
267 that case we want to find it to delete it.
Chris Sosadad0d322011-01-31 16:37:33 -0800268
Alex Klein1699fab2022-09-08 08:46:06 -0600269 Args:
Alex Klein68b270c2023-04-14 14:42:50 -0600270 stable_ebuilds: A list of stable ebuilds.
271 chrome_rev: The chrome_rev designating which candidate to find.
272 sticky_branch: The branch that is currently sticky with Major/Minor
273 components. For example: 9.0.553. Can be None but not if chrome_rev
274 is CHROME_REV_STICKY.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500275
Alex Klein1699fab2022-09-08 08:46:06 -0600276 Returns:
Alex Klein68b270c2023-04-14 14:42:50 -0600277 The EBuild, otherwise None if none found.
Alex Klein1699fab2022-09-08 08:46:06 -0600278 """
279 candidates = []
280 if chrome_rev in [
281 constants.CHROME_REV_LOCAL,
282 constants.CHROME_REV_TOT,
283 constants.CHROME_REV_SPEC,
284 ]:
285 # These are labelled alpha, for historic reasons,
286 # not just for the fun of confusion.
287 chrome_branch_re = re.compile(r"%s.*_alpha.*" % _CHROME_VERSION_REGEX)
288 for ebuild in stable_ebuilds:
289 if chrome_branch_re.search(ebuild.version):
290 candidates.append(ebuild)
Chris Sosadad0d322011-01-31 16:37:33 -0800291
Alex Klein1699fab2022-09-08 08:46:06 -0600292 elif chrome_rev == constants.CHROME_REV_STICKY:
293 assert sticky_branch is not None
294 chrome_branch_re = re.compile(r"%s\..*" % sticky_branch)
295 for ebuild in stable_ebuilds:
296 if chrome_branch_re.search(ebuild.version):
297 candidates.append(ebuild)
Chris Sosadad0d322011-01-31 16:37:33 -0800298
Alex Klein1699fab2022-09-08 08:46:06 -0600299 else:
300 chrome_branch_re = re.compile(r"%s.*_rc.*" % _CHROME_VERSION_REGEX)
301 for ebuild in stable_ebuilds:
302 if chrome_branch_re.search(ebuild.version):
303 candidates.append(ebuild)
Chris Sosadad0d322011-01-31 16:37:33 -0800304
Alex Klein1699fab2022-09-08 08:46:06 -0600305 if candidates:
306 return portage_util.BestEBuild(candidates)
307 else:
308 return None
Chris Sosadad0d322011-01-31 16:37:33 -0800309
Mike Frysingercc838832014-05-24 13:10:30 -0400310
Chris Masone592cab52011-08-02 14:05:48 -0700311def GetChromeRevisionLinkFromVersions(old_chrome_version, chrome_version):
Alex Klein1699fab2022-09-08 08:46:06 -0600312 """Return appropriately formatted link to revision info, given versions
Chris Masone592cab52011-08-02 14:05:48 -0700313
Alex Klein68b270c2023-04-14 14:42:50 -0600314 Given two Chrome version strings (e.g. 9.0.533.0), generate a link to a
Alex Klein1699fab2022-09-08 08:46:06 -0600315 page that prints the Chromium revisions between those two versions.
Chris Masone592cab52011-08-02 14:05:48 -0700316
Alex Klein1699fab2022-09-08 08:46:06 -0600317 Args:
Alex Klein68b270c2023-04-14 14:42:50 -0600318 old_chrome_version: version to diff from
319 chrome_version: version to which to diff
Mike Frysinger1a736a82013-12-12 01:50:59 -0500320
Alex Klein1699fab2022-09-08 08:46:06 -0600321 Returns:
Alex Klein68b270c2023-04-14 14:42:50 -0600322 The desired URL.
Alex Klein1699fab2022-09-08 08:46:06 -0600323 """
324 return _CHROME_VERSION_URL % {
325 "old": old_chrome_version,
326 "new": chrome_version,
327 }
Chris Masone592cab52011-08-02 14:05:48 -0700328
Mike Frysinger750c5f52014-09-16 16:16:57 -0400329
Chris Masone592cab52011-08-02 14:05:48 -0700330def GetChromeRevisionListLink(old_chrome, new_chrome, chrome_rev):
Alex Klein1699fab2022-09-08 08:46:06 -0600331 """Returns a link to the list of revisions between two Chromium versions
Chris Masone592cab52011-08-02 14:05:48 -0700332
Alex Klein1699fab2022-09-08 08:46:06 -0600333 Given two ChromeEBuilds and the kind of rev we're doing, generate a
334 link to a page that prints the Chromium changes between those two
335 revisions, inclusive.
Chris Masone592cab52011-08-02 14:05:48 -0700336
Alex Klein1699fab2022-09-08 08:46:06 -0600337 Args:
Alex Klein68b270c2023-04-14 14:42:50 -0600338 old_chrome: ebuild for the version to diff from
339 new_chrome: ebuild for the version to which to diff
340 chrome_rev: one of constants.VALID_CHROME_REVISIONS
Mike Frysinger1a736a82013-12-12 01:50:59 -0500341
Alex Klein1699fab2022-09-08 08:46:06 -0600342 Returns:
Alex Klein68b270c2023-04-14 14:42:50 -0600343 The desired URL.
Chris Sosa8be39132011-04-14 12:09:24 -0700344 """
Alex Klein1699fab2022-09-08 08:46:06 -0600345 assert chrome_rev in _REV_TYPES_FOR_LINKS
346 return GetChromeRevisionLinkFromVersions(
347 old_chrome.chrome_version, new_chrome.chrome_version
348 )
Chris Sosa8be39132011-04-14 12:09:24 -0700349
Chris Sosa8be39132011-04-14 12:09:24 -0700350
Alex Klein1699fab2022-09-08 08:46:06 -0600351def MarkChromeEBuildAsStable(
352 stable_candidate,
353 unstable_ebuild,
354 chrome_pn,
355 chrome_rev,
356 chrome_version,
357 package_dir,
358):
359 r"""Uprevs the chrome ebuild specified by chrome_rev.
David James629febb2012-11-25 13:07:34 -0800360
Alex Klein1699fab2022-09-08 08:46:06 -0600361 This is the main function that uprevs the chrome_rev from a stable candidate
362 to its new version.
Chris Sosadad0d322011-01-31 16:37:33 -0800363
Alex Klein1699fab2022-09-08 08:46:06 -0600364 Args:
Alex Klein68b270c2023-04-14 14:42:50 -0600365 stable_candidate: ebuild that corresponds to the stable ebuild we are
366 revving from. If None, builds a new ebuild given the version
367 and logic for chrome_rev type with revision set to 1.
368 unstable_ebuild: ebuild corresponding to the unstable ebuild for chrome.
369 chrome_pn: package name.
370 chrome_rev: one of constants.VALID_CHROME_REVISIONS or LOCAL
371 constants.CHROME_REV_SPEC - Requires commit value. Revs the ebuild
372 for the specified version and uses the portage suffix of _alpha.
373 constants.CHROME_REV_TOT - Requires commit value. Revs the ebuild
374 for the TOT version and uses the portage suffix of _alpha.
375 constants.CHROME_REV_LOCAL - Requires a chrome_root. Revs the ebuild
376 for the local version and uses the portage suffix of _alpha.
377 constants.CHROME_REV_LATEST - This uses the portage suffix of _rc as
378 they are release candidates for the next sticky version.
379 constants.CHROME_REV_STICKY - Revs the sticky version.
380 chrome_version: The \d.\d.\d.\d version of Chrome.
381 package_dir: Path to the chromeos-chrome package dir.
Chris Sosa8be39132011-04-14 12:09:24 -0700382
Alex Klein1699fab2022-09-08 08:46:06 -0600383 Returns:
Alex Klein68b270c2023-04-14 14:42:50 -0600384 Full portage version atom (including rc's, etc) that was revved.
Alex Klein1699fab2022-09-08 08:46:06 -0600385 """
Chris Sosadad0d322011-01-31 16:37:33 -0800386
Alex Klein1699fab2022-09-08 08:46:06 -0600387 def IsTheNewEBuildRedundant(new_ebuild, stable_ebuild):
388 """Returns True if the new ebuild is redundant.
Chris Masone592cab52011-08-02 14:05:48 -0700389
Alex Klein68b270c2023-04-14 14:42:50 -0600390 This is True if the current stable ebuild is an exact copy of the new
391 one.
Alex Klein1699fab2022-09-08 08:46:06 -0600392 """
393 if not stable_ebuild:
394 return False
Chris Sosadad0d322011-01-31 16:37:33 -0800395
Alex Klein1699fab2022-09-08 08:46:06 -0600396 if stable_candidate.chrome_version == new_ebuild.chrome_version:
397 return filecmp.cmp(
398 new_ebuild.ebuild_path, stable_ebuild.ebuild_path, shallow=False
399 )
Chris Sosadad0d322011-01-31 16:37:33 -0800400
Alex Klein1699fab2022-09-08 08:46:06 -0600401 # Mark latest release and sticky branches as stable.
402 mark_stable = chrome_rev not in [
403 constants.CHROME_REV_TOT,
404 constants.CHROME_REV_SPEC,
405 constants.CHROME_REV_LOCAL,
406 ]
407
408 # Case where we have the last stable candidate with same version just rev.
409 if stable_candidate and stable_candidate.chrome_version == chrome_version:
410 new_ebuild_path = "%s-r%d.ebuild" % (
411 stable_candidate.ebuild_path_no_revision,
412 stable_candidate.current_revision + 1,
413 )
414 else:
415 suffix = "rc" if mark_stable else "alpha"
416 pf = "%s-%s_%s-r1" % (chrome_pn, chrome_version, suffix)
417 new_ebuild_path = os.path.join(package_dir, "%s.ebuild" % pf)
418
419 portage_util.EBuild.MarkAsStable(
420 unstable_ebuild.ebuild_path,
421 new_ebuild_path,
422 {},
423 make_stable=mark_stable,
424 )
425 new_ebuild = ChromeEBuild(new_ebuild_path)
426
427 # Determine whether this is ebuild is redundant.
428 if IsTheNewEBuildRedundant(new_ebuild, stable_candidate):
429 msg = "Previous ebuild with same version found and ebuild is redundant."
430 logging.info(msg)
431 os.unlink(new_ebuild_path)
432 return None
433
434 if stable_candidate and chrome_rev in _REV_TYPES_FOR_LINKS:
435 cbuildbot_alerts.PrintBuildbotLink(
436 "Chromium revisions",
437 GetChromeRevisionListLink(stable_candidate, new_ebuild, chrome_rev),
438 )
439
440 git.RunGit(package_dir, ["add", new_ebuild_path])
441 if stable_candidate and not stable_candidate.IsSticky():
Jack Rosenthal451b0262023-09-13 12:52:16 -0600442 git.RunGit(package_dir, ["rm", str(stable_candidate.ebuild_path)])
Alex Klein1699fab2022-09-08 08:46:06 -0600443
444 portage_util.EBuild.CommitChange(
445 _GIT_COMMIT_MESSAGE
446 % {
447 "chrome_pn": chrome_pn,
448 "chrome_rev": chrome_rev,
449 "chrome_version": chrome_version,
450 },
451 package_dir,
452 )
453
454 return "%s-%s" % (new_ebuild.package, new_ebuild.version)
Chris Sosadad0d322011-01-31 16:37:33 -0800455
456
Mike Frysingera13c04f2016-09-01 00:35:17 -0400457def GetParser():
Alex Klein1699fab2022-09-08 08:46:06 -0600458 """Return a command line parser."""
459 parser = commandline.ArgumentParser(description=__doc__)
460 parser.add_argument("-b", "--boards")
461 parser.add_argument(
462 "-c", "--chrome_url", default=constants.CHROMIUM_GOB_URL
463 )
464 parser.add_argument(
465 "-f",
466 "--force_version",
467 help="Chrome version or git revision hash to use",
468 )
469 parser.add_argument(
470 "-s",
471 "--srcroot",
472 default=os.path.join(os.environ["HOME"], "trunk", "src"),
473 help="Path to the src directory",
474 )
475 parser.add_argument(
476 "-t",
477 "--tracking_branch",
478 default="cros/master",
479 help="Branch we are tracking changes against",
480 )
481 parser.add_argument("revision", choices=constants.VALID_CHROME_REVISIONS)
482 return parser
Chris Sosadad0d322011-01-31 16:37:33 -0800483
Chris Sosadad0d322011-01-31 16:37:33 -0800484
Mike Frysingera13c04f2016-09-01 00:35:17 -0400485def main(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600486 parser = GetParser()
487 options = parser.parse_args(argv)
488 options.Freeze()
489 chrome_rev = options.revision
Mike Frysingera13c04f2016-09-01 00:35:17 -0400490
Alex Klein1699fab2022-09-08 08:46:06 -0600491 if options.force_version and chrome_rev not in (
492 constants.CHROME_REV_SPEC,
493 constants.CHROME_REV_LATEST,
494 ):
495 parser.error(
496 "--force_version is not compatible with the %r "
497 "option." % (chrome_rev,)
498 )
David Jamesfb160012014-07-01 10:00:57 -0700499
Alex Klein1699fab2022-09-08 08:46:06 -0600500 overlay_dir = os.path.abspath(_OVERLAY_DIR % {"srcroot": options.srcroot})
501 chrome_package_dir = os.path.join(overlay_dir, constants.CHROME_CP)
502 version_to_uprev = None
503 sticky_branch = None
Chris Sosadad0d322011-01-31 16:37:33 -0800504
Alex Klein1699fab2022-09-08 08:46:06 -0600505 (unstable_ebuild, stable_ebuilds) = FindChromeCandidates(chrome_package_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800506
Alex Klein1699fab2022-09-08 08:46:06 -0600507 if chrome_rev == constants.CHROME_REV_LOCAL:
508 if "CHROME_ROOT" in os.environ:
509 chrome_root = os.environ["CHROME_ROOT"]
510 else:
511 chrome_root = os.path.join(os.environ["HOME"], "chrome_root")
512
513 version_to_uprev = _GetTipOfTrunkVersionFile(chrome_root)
514 logging.info("Using local source, versioning is untrustworthy.")
515 elif chrome_rev == constants.CHROME_REV_SPEC:
516 if "." in options.force_version:
517 version_to_uprev = options.force_version
518 else:
519 commit_to_use = options.force_version
520 if "@" in commit_to_use:
521 commit_to_use = commit_to_use.rpartition("@")[2]
522 version_to_uprev = _GetSpecificVersionUrl(
523 options.chrome_url, commit_to_use
524 )
525 elif chrome_rev == constants.CHROME_REV_TOT:
526 commit_to_use = gob_util.GetTipOfTrunkRevision(options.chrome_url)
527 version_to_uprev = _GetSpecificVersionUrl(
528 options.chrome_url, commit_to_use
529 )
530 elif chrome_rev == constants.CHROME_REV_LATEST:
531 if options.force_version:
532 if "." not in options.force_version:
533 parser.error(
534 "%s only accepts released Chrome versions, not SVN or "
535 "Git revisions." % (chrome_rev,)
536 )
537 version_to_uprev = options.force_version
538 else:
539 version_to_uprev = GetLatestRelease(options.chrome_url)
Peter Mayo177500f2011-09-09 17:25:23 -0400540 else:
Alex Klein1699fab2022-09-08 08:46:06 -0600541 sticky_ebuild = _GetStickyEBuild(stable_ebuilds)
542 sticky_version = sticky_ebuild.chrome_version
543 sticky_branch = sticky_version.rpartition(".")[0]
544 version_to_uprev = GetLatestRelease(options.chrome_url, sticky_branch)
Peter Mayo177500f2011-09-09 17:25:23 -0400545
Alex Klein1699fab2022-09-08 08:46:06 -0600546 stable_candidate = FindChromeUprevCandidate(
547 stable_ebuilds, chrome_rev, sticky_branch
548 )
549
550 if stable_candidate:
551 logging.info("Stable candidate found %s", stable_candidate)
David Jamesfb160012014-07-01 10:00:57 -0700552 else:
Alex Klein1699fab2022-09-08 08:46:06 -0600553 logging.info("No stable candidate found.")
Chris Sosadad0d322011-01-31 16:37:33 -0800554
Alex Klein1699fab2022-09-08 08:46:06 -0600555 tracking_branch = "remotes/m/%s" % os.path.basename(options.tracking_branch)
556 existing_branch = git.GetCurrentBranch(chrome_package_dir)
557 work_branch = cros_mark_as_stable.GitBranch(
558 constants.STABLE_EBUILD_BRANCH, tracking_branch, chrome_package_dir
559 )
560 work_branch.CreateBranch()
Chris Sosadad0d322011-01-31 16:37:33 -0800561
Alex Klein1699fab2022-09-08 08:46:06 -0600562 # In the case of uprevving overlays that have patches applied to them,
563 # include the patched changes in the stabilizing branch.
564 if existing_branch:
565 git.RunGit(chrome_package_dir, ["rebase", existing_branch])
Chris Sosadad0d322011-01-31 16:37:33 -0800566
Alex Klein1699fab2022-09-08 08:46:06 -0600567 chrome_version_atom = MarkChromeEBuildAsStable(
568 stable_candidate,
569 unstable_ebuild,
570 "chromeos-chrome",
571 chrome_rev,
572 version_to_uprev,
573 chrome_package_dir,
574 )
575 if chrome_version_atom:
576 if options.boards:
577 cros_mark_as_stable.CleanStalePackages(
578 options.srcroot,
579 options.boards.split(":"),
580 [chrome_version_atom],
581 )
David Jamesd6708c02012-03-22 10:49:15 -0700582
Alex Klein1699fab2022-09-08 08:46:06 -0600583 # If we did rev Chrome, now is a good time to uprev other packages.
584 for other_ebuild in constants.OTHER_CHROME_PACKAGES:
585 other_ebuild_name = os.path.basename(other_ebuild)
586 other_package_dir = os.path.join(overlay_dir, other_ebuild)
587 (
588 other_unstable_ebuild,
589 other_stable_ebuilds,
590 ) = FindChromeCandidates(other_package_dir)
591 other_stable_candidate = FindChromeUprevCandidate(
592 other_stable_ebuilds, chrome_rev, sticky_branch
593 )
594 revved_atom = MarkChromeEBuildAsStable(
595 other_stable_candidate,
596 other_unstable_ebuild,
597 other_ebuild_name,
598 chrome_rev,
599 version_to_uprev,
600 other_package_dir,
601 )
602 if revved_atom and options.boards:
603 cros_mark_as_stable.CleanStalePackages(
604 options.srcroot, options.boards.split(":"), [revved_atom]
605 )
David Jamesd6708c02012-03-22 10:49:15 -0700606
Alex Klein1699fab2022-09-08 08:46:06 -0600607 # Explicit print to communicate to caller.
608 if chrome_version_atom:
609 print("CHROME_VERSION_ATOM=%s" % chrome_version_atom)