blob: 5eb8c879bfb4a87991b17cdd495fdce03bcf69dc [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)
216 re_match = self.chrome_version_re.match(self.ebuild_path_no_revision)
217 if re_match:
218 self.chrome_version = re_match.group(1)
219
220 def __str__(self):
221 return self.ebuild_path
Chris Sosadad0d322011-01-31 16:37:33 -0800222
223
David Zeuthen665d3132014-08-25 15:27:02 -0400224def FindChromeCandidates(package_dir):
Alex Klein1699fab2022-09-08 08:46:06 -0600225 """Return a tuple of chrome's unstable ebuild and stable ebuilds.
Chris Sosadad0d322011-01-31 16:37:33 -0800226
Alex Klein1699fab2022-09-08 08:46:06 -0600227 Args:
Alex Klein68b270c2023-04-14 14:42:50 -0600228 package_dir: The path to where the package ebuild is stored.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500229
Alex Klein1699fab2022-09-08 08:46:06 -0600230 Returns:
Alex Klein68b270c2023-04-14 14:42:50 -0600231 Tuple [unstable_ebuild, stable_ebuilds].
Mike Frysinger1a736a82013-12-12 01:50:59 -0500232
Alex Klein1699fab2022-09-08 08:46:06 -0600233 Raises:
Alex Klein68b270c2023-04-14 14:42:50 -0600234 Exception: if no unstable ebuild exists for Chrome.
Alex Klein1699fab2022-09-08 08:46:06 -0600235 """
236 stable_ebuilds = []
237 unstable_ebuilds = []
238 for path in [
239 os.path.join(package_dir, entry) for entry in os.listdir(package_dir)
240 ]:
241 if path.endswith(".ebuild"):
242 ebuild = ChromeEBuild(path)
243 if not ebuild.chrome_version:
244 logging.warning("Poorly formatted ebuild found at %s", path)
245 else:
246 if "9999" in ebuild.version:
247 unstable_ebuilds.append(ebuild)
248 else:
249 stable_ebuilds.append(ebuild)
Chris Sosadad0d322011-01-31 16:37:33 -0800250
Alex Klein1699fab2022-09-08 08:46:06 -0600251 # Apply some confidence checks.
252 if not unstable_ebuilds:
253 raise Exception("Missing 9999 ebuild for %s" % package_dir)
254 if not stable_ebuilds:
255 logging.warning("Missing stable ebuild for %s", package_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800256
Alex Klein1699fab2022-09-08 08:46:06 -0600257 return portage_util.BestEBuild(unstable_ebuilds), stable_ebuilds
Chris Sosadad0d322011-01-31 16:37:33 -0800258
259
260def FindChromeUprevCandidate(stable_ebuilds, chrome_rev, sticky_branch):
Alex Klein1699fab2022-09-08 08:46:06 -0600261 """Finds the Chrome uprev candidate for the given chrome_rev.
Chris Sosadad0d322011-01-31 16:37:33 -0800262
Alex Klein1699fab2022-09-08 08:46:06 -0600263 Using the pre-flight logic, this means the stable ebuild you are uprevving
264 from. The difference here is that the version could be different and in
265 that case we want to find it to delete it.
Chris Sosadad0d322011-01-31 16:37:33 -0800266
Alex Klein1699fab2022-09-08 08:46:06 -0600267 Args:
Alex Klein68b270c2023-04-14 14:42:50 -0600268 stable_ebuilds: A list of stable ebuilds.
269 chrome_rev: The chrome_rev designating which candidate to find.
270 sticky_branch: The branch that is currently sticky with Major/Minor
271 components. For example: 9.0.553. Can be None but not if chrome_rev
272 is CHROME_REV_STICKY.
Mike Frysinger1a736a82013-12-12 01:50:59 -0500273
Alex Klein1699fab2022-09-08 08:46:06 -0600274 Returns:
Alex Klein68b270c2023-04-14 14:42:50 -0600275 The EBuild, otherwise None if none found.
Alex Klein1699fab2022-09-08 08:46:06 -0600276 """
277 candidates = []
278 if chrome_rev in [
279 constants.CHROME_REV_LOCAL,
280 constants.CHROME_REV_TOT,
281 constants.CHROME_REV_SPEC,
282 ]:
283 # These are labelled alpha, for historic reasons,
284 # not just for the fun of confusion.
285 chrome_branch_re = re.compile(r"%s.*_alpha.*" % _CHROME_VERSION_REGEX)
286 for ebuild in stable_ebuilds:
287 if chrome_branch_re.search(ebuild.version):
288 candidates.append(ebuild)
Chris Sosadad0d322011-01-31 16:37:33 -0800289
Alex Klein1699fab2022-09-08 08:46:06 -0600290 elif chrome_rev == constants.CHROME_REV_STICKY:
291 assert sticky_branch is not None
292 chrome_branch_re = re.compile(r"%s\..*" % sticky_branch)
293 for ebuild in stable_ebuilds:
294 if chrome_branch_re.search(ebuild.version):
295 candidates.append(ebuild)
Chris Sosadad0d322011-01-31 16:37:33 -0800296
Alex Klein1699fab2022-09-08 08:46:06 -0600297 else:
298 chrome_branch_re = re.compile(r"%s.*_rc.*" % _CHROME_VERSION_REGEX)
299 for ebuild in stable_ebuilds:
300 if chrome_branch_re.search(ebuild.version):
301 candidates.append(ebuild)
Chris Sosadad0d322011-01-31 16:37:33 -0800302
Alex Klein1699fab2022-09-08 08:46:06 -0600303 if candidates:
304 return portage_util.BestEBuild(candidates)
305 else:
306 return None
Chris Sosadad0d322011-01-31 16:37:33 -0800307
Mike Frysingercc838832014-05-24 13:10:30 -0400308
Chris Masone592cab52011-08-02 14:05:48 -0700309def GetChromeRevisionLinkFromVersions(old_chrome_version, chrome_version):
Alex Klein1699fab2022-09-08 08:46:06 -0600310 """Return appropriately formatted link to revision info, given versions
Chris Masone592cab52011-08-02 14:05:48 -0700311
Alex Klein68b270c2023-04-14 14:42:50 -0600312 Given two Chrome version strings (e.g. 9.0.533.0), generate a link to a
Alex Klein1699fab2022-09-08 08:46:06 -0600313 page that prints the Chromium revisions between those two versions.
Chris Masone592cab52011-08-02 14:05:48 -0700314
Alex Klein1699fab2022-09-08 08:46:06 -0600315 Args:
Alex Klein68b270c2023-04-14 14:42:50 -0600316 old_chrome_version: version to diff from
317 chrome_version: version to which to diff
Mike Frysinger1a736a82013-12-12 01:50:59 -0500318
Alex Klein1699fab2022-09-08 08:46:06 -0600319 Returns:
Alex Klein68b270c2023-04-14 14:42:50 -0600320 The desired URL.
Alex Klein1699fab2022-09-08 08:46:06 -0600321 """
322 return _CHROME_VERSION_URL % {
323 "old": old_chrome_version,
324 "new": chrome_version,
325 }
Chris Masone592cab52011-08-02 14:05:48 -0700326
Mike Frysinger750c5f52014-09-16 16:16:57 -0400327
Chris Masone592cab52011-08-02 14:05:48 -0700328def GetChromeRevisionListLink(old_chrome, new_chrome, chrome_rev):
Alex Klein1699fab2022-09-08 08:46:06 -0600329 """Returns a link to the list of revisions between two Chromium versions
Chris Masone592cab52011-08-02 14:05:48 -0700330
Alex Klein1699fab2022-09-08 08:46:06 -0600331 Given two ChromeEBuilds and the kind of rev we're doing, generate a
332 link to a page that prints the Chromium changes between those two
333 revisions, inclusive.
Chris Masone592cab52011-08-02 14:05:48 -0700334
Alex Klein1699fab2022-09-08 08:46:06 -0600335 Args:
Alex Klein68b270c2023-04-14 14:42:50 -0600336 old_chrome: ebuild for the version to diff from
337 new_chrome: ebuild for the version to which to diff
338 chrome_rev: one of constants.VALID_CHROME_REVISIONS
Mike Frysinger1a736a82013-12-12 01:50:59 -0500339
Alex Klein1699fab2022-09-08 08:46:06 -0600340 Returns:
Alex Klein68b270c2023-04-14 14:42:50 -0600341 The desired URL.
Chris Sosa8be39132011-04-14 12:09:24 -0700342 """
Alex Klein1699fab2022-09-08 08:46:06 -0600343 assert chrome_rev in _REV_TYPES_FOR_LINKS
344 return GetChromeRevisionLinkFromVersions(
345 old_chrome.chrome_version, new_chrome.chrome_version
346 )
Chris Sosa8be39132011-04-14 12:09:24 -0700347
Chris Sosa8be39132011-04-14 12:09:24 -0700348
Alex Klein1699fab2022-09-08 08:46:06 -0600349def MarkChromeEBuildAsStable(
350 stable_candidate,
351 unstable_ebuild,
352 chrome_pn,
353 chrome_rev,
354 chrome_version,
355 package_dir,
356):
357 r"""Uprevs the chrome ebuild specified by chrome_rev.
David James629febb2012-11-25 13:07:34 -0800358
Alex Klein1699fab2022-09-08 08:46:06 -0600359 This is the main function that uprevs the chrome_rev from a stable candidate
360 to its new version.
Chris Sosadad0d322011-01-31 16:37:33 -0800361
Alex Klein1699fab2022-09-08 08:46:06 -0600362 Args:
Alex Klein68b270c2023-04-14 14:42:50 -0600363 stable_candidate: ebuild that corresponds to the stable ebuild we are
364 revving from. If None, builds a new ebuild given the version
365 and logic for chrome_rev type with revision set to 1.
366 unstable_ebuild: ebuild corresponding to the unstable ebuild for chrome.
367 chrome_pn: package name.
368 chrome_rev: one of constants.VALID_CHROME_REVISIONS or LOCAL
369 constants.CHROME_REV_SPEC - Requires commit value. Revs the ebuild
370 for the specified version and uses the portage suffix of _alpha.
371 constants.CHROME_REV_TOT - Requires commit value. Revs the ebuild
372 for the TOT version and uses the portage suffix of _alpha.
373 constants.CHROME_REV_LOCAL - Requires a chrome_root. Revs the ebuild
374 for the local version and uses the portage suffix of _alpha.
375 constants.CHROME_REV_LATEST - This uses the portage suffix of _rc as
376 they are release candidates for the next sticky version.
377 constants.CHROME_REV_STICKY - Revs the sticky version.
378 chrome_version: The \d.\d.\d.\d version of Chrome.
379 package_dir: Path to the chromeos-chrome package dir.
Chris Sosa8be39132011-04-14 12:09:24 -0700380
Alex Klein1699fab2022-09-08 08:46:06 -0600381 Returns:
Alex Klein68b270c2023-04-14 14:42:50 -0600382 Full portage version atom (including rc's, etc) that was revved.
Alex Klein1699fab2022-09-08 08:46:06 -0600383 """
Chris Sosadad0d322011-01-31 16:37:33 -0800384
Alex Klein1699fab2022-09-08 08:46:06 -0600385 def IsTheNewEBuildRedundant(new_ebuild, stable_ebuild):
386 """Returns True if the new ebuild is redundant.
Chris Masone592cab52011-08-02 14:05:48 -0700387
Alex Klein68b270c2023-04-14 14:42:50 -0600388 This is True if the current stable ebuild is an exact copy of the new
389 one.
Alex Klein1699fab2022-09-08 08:46:06 -0600390 """
391 if not stable_ebuild:
392 return False
Chris Sosadad0d322011-01-31 16:37:33 -0800393
Alex Klein1699fab2022-09-08 08:46:06 -0600394 if stable_candidate.chrome_version == new_ebuild.chrome_version:
395 return filecmp.cmp(
396 new_ebuild.ebuild_path, stable_ebuild.ebuild_path, shallow=False
397 )
Chris Sosadad0d322011-01-31 16:37:33 -0800398
Alex Klein1699fab2022-09-08 08:46:06 -0600399 # Mark latest release and sticky branches as stable.
400 mark_stable = chrome_rev not in [
401 constants.CHROME_REV_TOT,
402 constants.CHROME_REV_SPEC,
403 constants.CHROME_REV_LOCAL,
404 ]
405
406 # Case where we have the last stable candidate with same version just rev.
407 if stable_candidate and stable_candidate.chrome_version == chrome_version:
408 new_ebuild_path = "%s-r%d.ebuild" % (
409 stable_candidate.ebuild_path_no_revision,
410 stable_candidate.current_revision + 1,
411 )
412 else:
413 suffix = "rc" if mark_stable else "alpha"
414 pf = "%s-%s_%s-r1" % (chrome_pn, chrome_version, suffix)
415 new_ebuild_path = os.path.join(package_dir, "%s.ebuild" % pf)
416
417 portage_util.EBuild.MarkAsStable(
418 unstable_ebuild.ebuild_path,
419 new_ebuild_path,
420 {},
421 make_stable=mark_stable,
422 )
423 new_ebuild = ChromeEBuild(new_ebuild_path)
424
425 # Determine whether this is ebuild is redundant.
426 if IsTheNewEBuildRedundant(new_ebuild, stable_candidate):
427 msg = "Previous ebuild with same version found and ebuild is redundant."
428 logging.info(msg)
429 os.unlink(new_ebuild_path)
430 return None
431
432 if stable_candidate and chrome_rev in _REV_TYPES_FOR_LINKS:
433 cbuildbot_alerts.PrintBuildbotLink(
434 "Chromium revisions",
435 GetChromeRevisionListLink(stable_candidate, new_ebuild, chrome_rev),
436 )
437
438 git.RunGit(package_dir, ["add", new_ebuild_path])
439 if stable_candidate and not stable_candidate.IsSticky():
440 git.RunGit(package_dir, ["rm", stable_candidate.ebuild_path])
441
442 portage_util.EBuild.CommitChange(
443 _GIT_COMMIT_MESSAGE
444 % {
445 "chrome_pn": chrome_pn,
446 "chrome_rev": chrome_rev,
447 "chrome_version": chrome_version,
448 },
449 package_dir,
450 )
451
452 return "%s-%s" % (new_ebuild.package, new_ebuild.version)
Chris Sosadad0d322011-01-31 16:37:33 -0800453
454
Mike Frysingera13c04f2016-09-01 00:35:17 -0400455def GetParser():
Alex Klein1699fab2022-09-08 08:46:06 -0600456 """Return a command line parser."""
457 parser = commandline.ArgumentParser(description=__doc__)
458 parser.add_argument("-b", "--boards")
459 parser.add_argument(
460 "-c", "--chrome_url", default=constants.CHROMIUM_GOB_URL
461 )
462 parser.add_argument(
463 "-f",
464 "--force_version",
465 help="Chrome version or git revision hash to use",
466 )
467 parser.add_argument(
468 "-s",
469 "--srcroot",
470 default=os.path.join(os.environ["HOME"], "trunk", "src"),
471 help="Path to the src directory",
472 )
473 parser.add_argument(
474 "-t",
475 "--tracking_branch",
476 default="cros/master",
477 help="Branch we are tracking changes against",
478 )
479 parser.add_argument("revision", choices=constants.VALID_CHROME_REVISIONS)
480 return parser
Chris Sosadad0d322011-01-31 16:37:33 -0800481
Chris Sosadad0d322011-01-31 16:37:33 -0800482
Mike Frysingera13c04f2016-09-01 00:35:17 -0400483def main(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600484 parser = GetParser()
485 options = parser.parse_args(argv)
486 options.Freeze()
487 chrome_rev = options.revision
Mike Frysingera13c04f2016-09-01 00:35:17 -0400488
Alex Klein1699fab2022-09-08 08:46:06 -0600489 if options.force_version and chrome_rev not in (
490 constants.CHROME_REV_SPEC,
491 constants.CHROME_REV_LATEST,
492 ):
493 parser.error(
494 "--force_version is not compatible with the %r "
495 "option." % (chrome_rev,)
496 )
David Jamesfb160012014-07-01 10:00:57 -0700497
Alex Klein1699fab2022-09-08 08:46:06 -0600498 overlay_dir = os.path.abspath(_OVERLAY_DIR % {"srcroot": options.srcroot})
499 chrome_package_dir = os.path.join(overlay_dir, constants.CHROME_CP)
500 version_to_uprev = None
501 sticky_branch = None
Chris Sosadad0d322011-01-31 16:37:33 -0800502
Alex Klein1699fab2022-09-08 08:46:06 -0600503 (unstable_ebuild, stable_ebuilds) = FindChromeCandidates(chrome_package_dir)
Chris Sosadad0d322011-01-31 16:37:33 -0800504
Alex Klein1699fab2022-09-08 08:46:06 -0600505 if chrome_rev == constants.CHROME_REV_LOCAL:
506 if "CHROME_ROOT" in os.environ:
507 chrome_root = os.environ["CHROME_ROOT"]
508 else:
509 chrome_root = os.path.join(os.environ["HOME"], "chrome_root")
510
511 version_to_uprev = _GetTipOfTrunkVersionFile(chrome_root)
512 logging.info("Using local source, versioning is untrustworthy.")
513 elif chrome_rev == constants.CHROME_REV_SPEC:
514 if "." in options.force_version:
515 version_to_uprev = options.force_version
516 else:
517 commit_to_use = options.force_version
518 if "@" in commit_to_use:
519 commit_to_use = commit_to_use.rpartition("@")[2]
520 version_to_uprev = _GetSpecificVersionUrl(
521 options.chrome_url, commit_to_use
522 )
523 elif chrome_rev == constants.CHROME_REV_TOT:
524 commit_to_use = gob_util.GetTipOfTrunkRevision(options.chrome_url)
525 version_to_uprev = _GetSpecificVersionUrl(
526 options.chrome_url, commit_to_use
527 )
528 elif chrome_rev == constants.CHROME_REV_LATEST:
529 if options.force_version:
530 if "." not in options.force_version:
531 parser.error(
532 "%s only accepts released Chrome versions, not SVN or "
533 "Git revisions." % (chrome_rev,)
534 )
535 version_to_uprev = options.force_version
536 else:
537 version_to_uprev = GetLatestRelease(options.chrome_url)
Peter Mayo177500f2011-09-09 17:25:23 -0400538 else:
Alex Klein1699fab2022-09-08 08:46:06 -0600539 sticky_ebuild = _GetStickyEBuild(stable_ebuilds)
540 sticky_version = sticky_ebuild.chrome_version
541 sticky_branch = sticky_version.rpartition(".")[0]
542 version_to_uprev = GetLatestRelease(options.chrome_url, sticky_branch)
Peter Mayo177500f2011-09-09 17:25:23 -0400543
Alex Klein1699fab2022-09-08 08:46:06 -0600544 stable_candidate = FindChromeUprevCandidate(
545 stable_ebuilds, chrome_rev, sticky_branch
546 )
547
548 if stable_candidate:
549 logging.info("Stable candidate found %s", stable_candidate)
David Jamesfb160012014-07-01 10:00:57 -0700550 else:
Alex Klein1699fab2022-09-08 08:46:06 -0600551 logging.info("No stable candidate found.")
Chris Sosadad0d322011-01-31 16:37:33 -0800552
Alex Klein1699fab2022-09-08 08:46:06 -0600553 tracking_branch = "remotes/m/%s" % os.path.basename(options.tracking_branch)
554 existing_branch = git.GetCurrentBranch(chrome_package_dir)
555 work_branch = cros_mark_as_stable.GitBranch(
556 constants.STABLE_EBUILD_BRANCH, tracking_branch, chrome_package_dir
557 )
558 work_branch.CreateBranch()
Chris Sosadad0d322011-01-31 16:37:33 -0800559
Alex Klein1699fab2022-09-08 08:46:06 -0600560 # In the case of uprevving overlays that have patches applied to them,
561 # include the patched changes in the stabilizing branch.
562 if existing_branch:
563 git.RunGit(chrome_package_dir, ["rebase", existing_branch])
Chris Sosadad0d322011-01-31 16:37:33 -0800564
Alex Klein1699fab2022-09-08 08:46:06 -0600565 chrome_version_atom = MarkChromeEBuildAsStable(
566 stable_candidate,
567 unstable_ebuild,
568 "chromeos-chrome",
569 chrome_rev,
570 version_to_uprev,
571 chrome_package_dir,
572 )
573 if chrome_version_atom:
574 if options.boards:
575 cros_mark_as_stable.CleanStalePackages(
576 options.srcroot,
577 options.boards.split(":"),
578 [chrome_version_atom],
579 )
David Jamesd6708c02012-03-22 10:49:15 -0700580
Alex Klein1699fab2022-09-08 08:46:06 -0600581 # If we did rev Chrome, now is a good time to uprev other packages.
582 for other_ebuild in constants.OTHER_CHROME_PACKAGES:
583 other_ebuild_name = os.path.basename(other_ebuild)
584 other_package_dir = os.path.join(overlay_dir, other_ebuild)
585 (
586 other_unstable_ebuild,
587 other_stable_ebuilds,
588 ) = FindChromeCandidates(other_package_dir)
589 other_stable_candidate = FindChromeUprevCandidate(
590 other_stable_ebuilds, chrome_rev, sticky_branch
591 )
592 revved_atom = MarkChromeEBuildAsStable(
593 other_stable_candidate,
594 other_unstable_ebuild,
595 other_ebuild_name,
596 chrome_rev,
597 version_to_uprev,
598 other_package_dir,
599 )
600 if revved_atom and options.boards:
601 cros_mark_as_stable.CleanStalePackages(
602 options.srcroot, options.boards.split(":"), [revved_atom]
603 )
David Jamesd6708c02012-03-22 10:49:15 -0700604
Alex Klein1699fab2022-09-08 08:46:06 -0600605 # Explicit print to communicate to caller.
606 if chrome_version_atom:
607 print("CHROME_VERSION_ATOM=%s" % chrome_version_atom)