blob: 507e82808336162d6310a93773ae9c7c8d6be358 [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2016 The ChromiumOS Authors
David Rileyc0da9d92016-02-01 12:11:01 -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 Android for cbuildbot.
6
Shao-Chuan Lee84bf9a22021-11-19 17:42:11 +09007After calling, it prints out a JSON representing the result, with the new
8Android version atom string included. A caller could then use this atom with
9emerge to build the newly uprevved version of Android e.g.
David Rileyc0da9d92016-02-01 12:11:01 -080010
Shuhei Takahashi6d02c192017-04-05 14:01:24 +090011./cros_mark_android_as_stable \
Shao-Chuan Lee7e507e62022-11-15 02:17:34 +000012 --android_build_branch=git_pi-arc \
Shao-Chuan Lee9c39e0c2020-04-24 11:40:34 +090013 --android_package=android-container-pi
Shuhei Takahashi6d02c192017-04-05 14:01:24 +090014
Shao-Chuan Lee84bf9a22021-11-19 17:42:11 +090015Returns {"android_atom": "chromeos-base/android-container-pi-6417892-r1"}
David Rileyc0da9d92016-02-01 12:11:01 -080016
Shao-Chuan Lee9c39e0c2020-04-24 11:40:34 +090017emerge-eve =chromeos-base/android-container-pi-6417892-r1
David Rileyc0da9d92016-02-01 12:11:01 -080018"""
19
David Rileyc0da9d92016-02-01 12:11:01 -080020import filecmp
21import glob
Junichi Uekawad21f94d2020-07-27 15:50:05 +090022import json
Chris McDonaldb55b7032021-06-17 16:41:32 -060023import logging
David Rileyc0da9d92016-02-01 12:11:01 -080024import os
25
Chris McDonaldb55b7032021-06-17 16:41:32 -060026from chromite.cbuildbot import cbuildbot_alerts
David Rileyc0da9d92016-02-01 12:11:01 -080027from chromite.lib import commandline
Chris McDonaldb55b7032021-06-17 16:41:32 -060028from chromite.lib import constants
David Rileyc0da9d92016-02-01 12:11:01 -080029from chromite.lib import cros_build_lib
David Rileyc0da9d92016-02-01 12:11:01 -080030from chromite.lib import git
31from chromite.lib import gs
Shao-Chuan Lee301a4192021-02-08 11:53:49 +090032from chromite.lib import osutils
David Rileyc0da9d92016-02-01 12:11:01 -080033from chromite.lib import portage_util
Shao-Chuan Lee007dbe82021-02-09 14:05:39 +090034from chromite.lib import repo_util
David Rileyc0da9d92016-02-01 12:11:01 -080035from chromite.scripts import cros_mark_as_stable
Shao-Chuan Lee7fd0ca12021-03-19 15:57:40 +090036from chromite.service import android
Yury Khmelc0a18442022-11-01 16:56:22 -070037from chromite.service import packages
David Rileyc0da9d92016-02-01 12:11:01 -080038
39
40# Dir where all the action happens.
Alex Klein1699fab2022-09-08 08:46:06 -060041_OVERLAY_DIR = "%(srcroot)s/private-overlays/project-cheets-private/"
David Rileyc0da9d92016-02-01 12:11:01 -080042
Junichi Uekawa6d61ab02020-04-15 14:52:28 +090043_GIT_COMMIT_MESSAGE = """Marking latest for %(android_package)s ebuild with \
44version %(android_version)s as stable.
45
46BUG=None
47TEST=CQ
48"""
David Rileyc0da9d92016-02-01 12:11:01 -080049
Shao-Chuan Lee3aa76522021-12-03 17:18:58 +090050_GIT_COMMIT_MESSAGE_LKGB = """%(android_package)s: Mark version \
51%(android_version)s as LKGB.
52
53Generated by Android PFQ. This change will trigger PUpr to actually submit an
54Android uprev.
55
56For details, see "Migration plan" section of go/android-uprev-recipes.
57
58BUG=None
59TEST=CQ
60"""
61
Alex Klein1699fab2022-09-08 08:46:06 -060062_RUNTIME_ARTIFACTS_BUCKET_URL = "gs://chromeos-arc-images/runtime_artifacts"
David Rileyc0da9d92016-02-01 12:11:01 -080063
David Rileyc0da9d92016-02-01 12:11:01 -080064
65def FindAndroidCandidates(package_dir):
Alex Klein1699fab2022-09-08 08:46:06 -060066 """Return a tuple of Android's unstable ebuild and stable ebuilds.
David Rileyc0da9d92016-02-01 12:11:01 -080067
Alex Klein1699fab2022-09-08 08:46:06 -060068 Args:
69 package_dir: The path to where the package ebuild is stored.
David Rileyc0da9d92016-02-01 12:11:01 -080070
Alex Klein1699fab2022-09-08 08:46:06 -060071 Returns:
72 Tuple [unstable_ebuild, stable_ebuilds].
David Rileyc0da9d92016-02-01 12:11:01 -080073
Alex Klein1699fab2022-09-08 08:46:06 -060074 Raises:
75 Exception: if no unstable ebuild exists for Android.
76 """
77 stable_ebuilds = []
78 unstable_ebuilds = []
79 for path in glob.glob(os.path.join(package_dir, "*.ebuild")):
80 ebuild = portage_util.EBuild(path)
81 if ebuild.version == "9999":
82 unstable_ebuilds.append(ebuild)
83 else:
84 stable_ebuilds.append(ebuild)
David Rileyc0da9d92016-02-01 12:11:01 -080085
Alex Klein1699fab2022-09-08 08:46:06 -060086 # Apply some confidence checks.
87 if not unstable_ebuilds:
88 raise Exception("Missing 9999 ebuild for %s" % package_dir)
89 if not stable_ebuilds:
90 logging.warning("Missing stable ebuild for %s", package_dir)
David Rileyc0da9d92016-02-01 12:11:01 -080091
Alex Klein1699fab2022-09-08 08:46:06 -060092 return portage_util.BestEBuild(unstable_ebuilds), stable_ebuilds
David Rileyc0da9d92016-02-01 12:11:01 -080093
94
Shao-Chuan Lee085e3d72020-05-11 16:00:42 +090095def PrintUprevMetadata(build_branch, stable_candidate, new_ebuild):
Alex Klein1699fab2022-09-08 08:46:06 -060096 """Shows metadata on buildbot page at UprevAndroid step.
David Rileyc0da9d92016-02-01 12:11:01 -080097
Alex Klein1699fab2022-09-08 08:46:06 -060098 Args:
99 build_branch: The branch of Android builds.
100 stable_candidate: The existing stable ebuild.
101 new_ebuild: The newly written ebuild.
David Rileyc0da9d92016-02-01 12:11:01 -0800102 """
Alex Klein1699fab2022-09-08 08:46:06 -0600103 # Examples:
104 # "android-container-pi revved 6461825-r1 -> 6468247-r1"
105 # "android-container-pi revved 6461825-r1 -> 6461825-r2 (ebuild update only)"
106 msg = "%s revved %s -> %s" % (
107 stable_candidate.pkgname,
108 stable_candidate.version,
109 new_ebuild.version,
110 )
David Rileyc0da9d92016-02-01 12:11:01 -0800111
Alex Klein1699fab2022-09-08 08:46:06 -0600112 old_android = stable_candidate.version_no_rev
113 new_android = new_ebuild.version_no_rev
David Rileyc0da9d92016-02-01 12:11:01 -0800114
Alex Klein1699fab2022-09-08 08:46:06 -0600115 if old_android == new_android:
116 msg += " (ebuild update only)"
117 else:
118 ab_link = (
119 "https://android-build.googleplex.com"
120 "/builds/%s/branches/%s/cls?end=%s"
121 % (new_android, build_branch, old_android)
122 )
123 cbuildbot_alerts.PrintBuildbotLink("Android changelog", ab_link)
David Rileyc0da9d92016-02-01 12:11:01 -0800124
Alex Klein1699fab2022-09-08 08:46:06 -0600125 cbuildbot_alerts.PrintBuildbotStepText(msg)
126 cbuildbot_alerts.PrintKitchenSetBuildProperty(
127 "android_uprev",
128 json.dumps(
129 {
130 "branch": build_branch,
131 "new": new_ebuild.version,
132 "old": stable_candidate.version,
133 "pkgname": stable_candidate.pkgname,
134 }
135 ),
136 )
David Rileyc0da9d92016-02-01 12:11:01 -0800137
khmel@chromium.orgd3ec3d72020-04-29 15:57:35 -0700138
Alex Klein1699fab2022-09-08 08:46:06 -0600139def FindDataCollectorArtifacts(
Yury Khmelc0a18442022-11-01 16:56:22 -0700140 gs_context,
141 android_version,
142 package_name,
143 runtime_artifacts_bucket_url,
144 version_reference,
Alex Klein1699fab2022-09-08 08:46:06 -0600145):
146 r"""Finds and includes into variables artifacts from arc.DataCollector.
David Rileyc0da9d92016-02-01 12:11:01 -0800147
Alex Klein1699fab2022-09-08 08:46:06 -0600148 This is used from UpdateDataCollectorArtifacts in order to check the
149 particular version.
David Rileyc0da9d92016-02-01 12:11:01 -0800150
Alex Klein1699fab2022-09-08 08:46:06 -0600151 Args:
152 gs_context: context to execute gsutil
153 android_version: The \d+ build id of Android.
Yury Khmelc0a18442022-11-01 16:56:22 -0700154 package_name: android package name. Used as folder to locate the cache.
Alex Klein1699fab2022-09-08 08:46:06 -0600155 runtime_artifacts_bucket_url: root of runtime artifacts
Alex Klein1699fab2022-09-08 08:46:06 -0600156 version_reference: which version to use as a reference. Could be '${PV}' in
157 case version of data collector artifacts matches the
158 Android version or direct version in case of override.
David Rileyc0da9d92016-02-01 12:11:01 -0800159
Alex Klein1699fab2022-09-08 08:46:06 -0600160 Returns:
161 dictionary with filled ebuild variables. This dictionary is empty in case
162 no artificats are found.
163 """
164 variables = {}
David Rileyc0da9d92016-02-01 12:11:01 -0800165
Yury Khmel697863b2022-10-25 09:02:57 -0700166 buckets = ["ureadahead_pack_host", "gms_core_cache", "tts_cache"]
Alex Klein1699fab2022-09-08 08:46:06 -0600167 archs = ["arm", "arm64", "x86", "x86_64"]
168 build_types = ["user", "userdebug"]
David Rileyc0da9d92016-02-01 12:11:01 -0800169
Alex Klein1699fab2022-09-08 08:46:06 -0600170 for bucket in buckets:
171 for arch in archs:
172 for build_type in build_types:
Yury Khmelc0a18442022-11-01 16:56:22 -0700173 # TODO(b/255854925): remove path without |package_name|.
174 # |package_name| is required to separate artefacts for bertha
175 # and cheets.
176 root_paths = [
177 f"{runtime_artifacts_bucket_url}/{package_name}/{bucket}_{arch}_{build_type}",
178 f"{runtime_artifacts_bucket_url}/{bucket}_{arch}_{build_type}",
179 ]
180
181 for _, root_path in enumerate(root_paths):
182 path = f"{root_path}_{android_version}.tar"
183 if gs_context.Exists(path):
184 variables[
185 (f"{arch}_{build_type}_{bucket}").upper()
186 ] = f"{root_path}_{version_reference}.tar"
187 break
Alex Klein1699fab2022-09-08 08:46:06 -0600188
189 return variables
190
191
192def UpdateDataCollectorArtifacts(
Yury Khmelc0a18442022-11-01 16:56:22 -0700193 android_version, runtime_artifacts_bucket_url, package_name
Alex Klein1699fab2022-09-08 08:46:06 -0600194):
195 r"""Finds and includes into variables artifacts from arc.DataCollector.
196
197 This verifies default android version. In case artificts are not found for
198 default Android version it tries to find artifacts for pinned version. If
199 pinned version is provided, it is required artifacts exist for the pinned
200 version.
201
202 Args:
203 android_version: The \d+ build id of Android.
204 runtime_artifacts_bucket_url: root of runtime artifacts
Yury Khmelc0a18442022-11-01 16:56:22 -0700205 package_name: android package name. Used to determine the pinned version if exists.
Alex Klein1699fab2022-09-08 08:46:06 -0600206
207 Returns:
208 dictionary with filled ebuild variables.
209 """
210
211 gs_context = gs.GSContext()
212 # Check the existing version. If we find any artifacts, use them.
213 variables = FindDataCollectorArtifacts(
Yury Khmelc0a18442022-11-01 16:56:22 -0700214 gs_context,
215 android_version,
216 package_name,
217 runtime_artifacts_bucket_url,
218 "${PV}",
Alex Klein1699fab2022-09-08 08:46:06 -0600219 )
220 if variables:
221 # Data artificts were found.
222 return variables
223
224 # Check pinned version for the current branch.
Yury Khmelc0a18442022-11-01 16:56:22 -0700225 milestone = packages.determine_milestone_version()
226 pin_path = f"{runtime_artifacts_bucket_url}/{package_name}/M{milestone}_pin_version"
Alex Klein1699fab2022-09-08 08:46:06 -0600227 if not gs_context.Exists(pin_path):
228 # No pinned version.
229 logging.warning(
230 "No data collector artifacts were found for %s", android_version
231 )
232 return variables
233
234 pin_version = gs_context.Cat(pin_path, encoding="utf-8").rstrip()
235 logging.info("Pinned version %s overrides %s", pin_version, android_version)
236 variables = FindDataCollectorArtifacts(
Yury Khmelc0a18442022-11-01 16:56:22 -0700237 gs_context,
238 pin_version,
239 package_name,
240 runtime_artifacts_bucket_url,
241 pin_version,
Alex Klein1699fab2022-09-08 08:46:06 -0600242 )
243 if not variables:
244 # If pin version set it must contain data.
245 raise Exception(
Yury Khmelc0a18442022-11-01 16:56:22 -0700246 "Pinned version %s does not contain artificats" % pin_path
Alex Klein1699fab2022-09-08 08:46:06 -0600247 )
Alex Klein1699fab2022-09-08 08:46:06 -0600248 return variables
249
250
251def MarkAndroidEBuildAsStable(
252 stable_candidate,
253 unstable_ebuild,
254 android_package,
255 android_version,
256 package_dir,
Shao-Chuan Lee7e507e62022-11-15 02:17:34 +0000257 build_branch,
Alex Klein1699fab2022-09-08 08:46:06 -0600258 arc_bucket_url,
259 runtime_artifacts_bucket_url,
260):
261 r"""Uprevs the Android ebuild.
262
263 This is the main function that uprevs from a stable candidate
264 to its new version.
265
266 Args:
267 stable_candidate: ebuild that corresponds to the stable ebuild we are
268 revving from. If None, builds the a new ebuild given the version
269 with revision set to 1.
270 unstable_ebuild: ebuild corresponding to the unstable ebuild for Android.
271 android_package: android package name.
272 android_version: The \d+ build id of Android.
273 package_dir: Path to the android-container package dir.
Shao-Chuan Lee7e507e62022-11-15 02:17:34 +0000274 build_branch: branch of Android builds.
Alex Klein1699fab2022-09-08 08:46:06 -0600275 arc_bucket_url: URL of the target ARC build gs bucket.
276 runtime_artifacts_bucket_url: root of runtime artifacts
277
278 Returns:
279 Tuple[str, List[str], List[str]] if revved, or None
280 1. Full portage version atom (including rc's, etc) that was revved.
281 2. List of files to be `git add`ed.
282 3. List of files to be `git rm`ed.
283 """
284
285 def IsTheNewEBuildRedundant(new_ebuild, stable_ebuild):
286 """Returns True if the new ebuild is redundant.
287
288 This is True if there if the current stable ebuild is the exact same copy
289 of the new one.
290 """
291 if not stable_ebuild:
292 return False
293
294 if stable_candidate.version_no_rev == new_ebuild.version_no_rev:
295 return filecmp.cmp(
296 new_ebuild.ebuild_path, stable_ebuild.ebuild_path, shallow=False
297 )
298 return False
299
300 # Case where we have the last stable candidate with same version just rev.
301 if stable_candidate and stable_candidate.version_no_rev == android_version:
302 new_ebuild_path = "%s-r%d.ebuild" % (
303 stable_candidate.ebuild_path_no_revision,
304 stable_candidate.current_revision + 1,
305 )
306 else:
307 pf = "%s-%s-r1" % (android_package, android_version)
308 new_ebuild_path = os.path.join(package_dir, "%s.ebuild" % pf)
309
Shao-Chuan Leeca2cbcc2022-11-02 08:28:31 +0900310 build_targets = android.GetAndroidEbuildTargetsForPackage(android_package)
Alex Klein1699fab2022-09-08 08:46:06 -0600311 variables = {"BASE_URL": arc_bucket_url}
312 for var, target in build_targets.items():
Shao-Chuan Lee20c51d82022-10-26 21:56:56 +0900313 # TODO(b/255705023): Have MirrorArtifacts generate the mapping for us.
Alex Klein1699fab2022-09-08 08:46:06 -0600314 variables[var] = f"{build_branch}-linux-{target}"
315
316 variables.update(
317 UpdateDataCollectorArtifacts(
Yury Khmelc0a18442022-11-01 16:56:22 -0700318 android_version,
319 runtime_artifacts_bucket_url,
320 android_package,
Alex Klein1699fab2022-09-08 08:46:06 -0600321 )
322 )
323
324 portage_util.EBuild.MarkAsStable(
325 unstable_ebuild.ebuild_path,
326 new_ebuild_path,
327 variables,
328 make_stable=True,
329 )
330 new_ebuild = portage_util.EBuild(new_ebuild_path)
331
332 # Determine whether this is ebuild is redundant.
333 if IsTheNewEBuildRedundant(new_ebuild, stable_candidate):
334 msg = "Previous ebuild with same version found and ebuild is redundant."
335 logging.info(msg)
336 cbuildbot_alerts.PrintBuildbotStepText(
337 "%s %s not revved"
338 % (stable_candidate.pkgname, stable_candidate.version)
339 )
340 osutils.SafeUnlink(new_ebuild_path)
341 return None
342
343 # PFQ runs should always be able to find a stable candidate.
344 if stable_candidate:
345 PrintUprevMetadata(build_branch, stable_candidate, new_ebuild)
346
347 files_to_add = [new_ebuild_path]
348 files_to_remove = []
349 if stable_candidate and not stable_candidate.IsSticky():
350 osutils.SafeUnlink(stable_candidate.ebuild_path)
351 files_to_remove.append(stable_candidate.ebuild_path)
352
353 # Update ebuild manifest and git add it.
354 gen_manifest_cmd = ["ebuild", new_ebuild_path, "manifest", "--force"]
355 cros_build_lib.run(gen_manifest_cmd, extra_env=None, print_cmd=True)
356 files_to_add.append(os.path.join(package_dir, "Manifest"))
357
358 return (
359 f"{new_ebuild.package}-{new_ebuild.version}",
360 files_to_add,
361 files_to_remove,
362 )
David Rileyc0da9d92016-02-01 12:11:01 -0800363
Shao-Chuan Lee301a4192021-02-08 11:53:49 +0900364
Shao-Chuan Lee007dbe82021-02-09 14:05:39 +0900365def _PrepareGitBranch(overlay_dir):
Alex Klein1699fab2022-09-08 08:46:06 -0600366 """Prepares a git branch for the uprev commit.
Shao-Chuan Lee301a4192021-02-08 11:53:49 +0900367
Alex Klein1699fab2022-09-08 08:46:06 -0600368 If the overlay project is currently on a branch (e.g. patches are being
369 applied), rebase the new branch on top of it.
Shao-Chuan Lee007dbe82021-02-09 14:05:39 +0900370
Alex Klein1699fab2022-09-08 08:46:06 -0600371 Args:
372 overlay_dir: The overlay directory.
373 """
374 existing_branch = git.GetCurrentBranch(overlay_dir)
375 repo_util.Repository.MustFind(overlay_dir).StartBranch(
376 constants.STABLE_EBUILD_BRANCH, projects=["."], cwd=overlay_dir
377 )
378 if existing_branch:
379 git.RunGit(overlay_dir, ["rebase", existing_branch])
Shao-Chuan Lee301a4192021-02-08 11:53:49 +0900380
381
382def _CommitChange(message, android_package_dir, files_to_add, files_to_remove):
Alex Klein1699fab2022-09-08 08:46:06 -0600383 """Commit changes to git with list of files to add/remove."""
384 git.RunGit(android_package_dir, ["add", "--"] + files_to_add)
385 if files_to_remove:
386 git.RunGit(android_package_dir, ["rm", "--"] + files_to_remove)
Shao-Chuan Lee301a4192021-02-08 11:53:49 +0900387
Alex Klein1699fab2022-09-08 08:46:06 -0600388 portage_util.EBuild.CommitChange(message, android_package_dir)
David Rileyc0da9d92016-02-01 12:11:01 -0800389
390
391def GetParser():
Alex Klein1699fab2022-09-08 08:46:06 -0600392 """Creates the argument parser."""
393 parser = commandline.ArgumentParser()
394 parser.add_argument("-b", "--boards")
395 parser.add_argument(
396 "--android_bucket_url",
397 default=android.ANDROID_BUCKET_URL,
398 type="gs_path",
399 )
400 parser.add_argument(
401 "--android_build_branch",
Shao-Chuan Lee7e507e62022-11-15 02:17:34 +0000402 help="Android branch to import from, overriding default",
Alex Klein1699fab2022-09-08 08:46:06 -0600403 )
404 parser.add_argument(
405 "--android_package",
406 required=True,
Shao-Chuan Leeca2cbcc2022-11-02 08:28:31 +0900407 choices=android.GetAllAndroidPackages(),
Alex Klein1699fab2022-09-08 08:46:06 -0600408 help="Android package to uprev",
409 )
410 parser.add_argument(
411 "--arc_bucket_url", default=constants.ARC_BUCKET_URL, type="gs_path"
412 )
413 parser.add_argument("-f", "--force_version", help="Android build id to use")
414 parser.add_argument(
415 "-s",
416 "--srcroot",
417 default=os.path.join(constants.SOURCE_ROOT, "src"),
418 help="Path to the src directory",
419 )
420 parser.add_argument(
421 "--runtime_artifacts_bucket_url",
422 default=_RUNTIME_ARTIFACTS_BUCKET_URL,
423 type="gs_path",
424 )
425 parser.add_argument(
426 "--skip_commit",
427 action="store_true",
428 help="Skip commiting uprev changes to git",
429 )
430 parser.add_argument(
431 "--update_lkgb",
432 action="store_true",
433 help=(
434 "Update the LKGB file instead of uprevving ebuilds "
435 "and populating artifacts. "
436 "Requires --force_version be set."
437 ),
438 )
439 return parser
David Rileyc0da9d92016-02-01 12:11:01 -0800440
441
442def main(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600443 cbuildbot_alerts.EnableBuildbotMarkers()
444 parser = GetParser()
445 options = parser.parse_args(argv)
446 options.Freeze()
David Rileyc0da9d92016-02-01 12:11:01 -0800447
Alex Klein1699fab2022-09-08 08:46:06 -0600448 overlay_dir = os.path.abspath(_OVERLAY_DIR % {"srcroot": options.srcroot})
449 android_package_dir = android.GetAndroidPackageDir(
450 options.android_package, overlay_dir=overlay_dir
451 )
Shao-Chuan Lee3aa76522021-12-03 17:18:58 +0900452
453 if not options.skip_commit:
Alex Klein1699fab2022-09-08 08:46:06 -0600454 _PrepareGitBranch(overlay_dir)
Shao-Chuan Lee3aa76522021-12-03 17:18:58 +0900455
Alex Klein1699fab2022-09-08 08:46:06 -0600456 if options.update_lkgb:
457 if not options.force_version:
458 raise Exception("--force_version is required with --update_lkgb")
Shao-Chuan Leea4b4f302021-05-12 14:40:20 +0900459
Alex Klein1699fab2022-09-08 08:46:06 -0600460 # Attempt to read current LKGB, if available.
461 current_lkgb = None
462 try:
463 current_lkgb = android.ReadLKGB(android_package_dir)
464 except android.MissingLKGBError:
465 logging.info("LKGB file is missing, creating a new one.")
466 except android.InvalidLKGBError:
467 logging.warning("Current LKGB file is invalid, overwriting.")
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900468
Alex Klein1699fab2022-09-08 08:46:06 -0600469 # Do nothing if LKGB is already set to the requested version.
470 if current_lkgb == options.force_version:
471 logging.warning(
472 "LKGB of %s is already %s, doing nothing.",
473 options.android_package,
474 options.force_version,
475 )
476 cbuildbot_alerts.PrintBuildbotStepText(
477 "LKGB of %s unchanged @ %s"
478 % (options.android_package, options.force_version)
479 )
480 return
David Rileyc0da9d92016-02-01 12:11:01 -0800481
Alex Klein1699fab2022-09-08 08:46:06 -0600482 # Actually update the LKGB.
483 path = android.WriteLKGB(android_package_dir, options.force_version)
484 cbuildbot_alerts.PrintBuildbotStepText(
485 "LKGB of %s updated %s -> %s"
486 % (options.android_package, current_lkgb, options.force_version)
487 )
David Rileyc0da9d92016-02-01 12:11:01 -0800488
Alex Klein1699fab2022-09-08 08:46:06 -0600489 if not options.skip_commit:
490 _CommitChange(
491 _GIT_COMMIT_MESSAGE_LKGB
492 % {
493 "android_package": options.android_package,
494 "android_version": options.force_version,
495 },
496 android_package_dir,
497 [path],
498 [],
499 )
500 return
Shao-Chuan Lee301a4192021-02-08 11:53:49 +0900501
Shao-Chuan Lee7e507e62022-11-15 02:17:34 +0000502 # Use default Android branch if not overridden.
503 android_build_branch = (
Shao-Chuan Lee20c51d82022-10-26 21:56:56 +0900504 options.android_build_branch
Shao-Chuan Lee7e507e62022-11-15 02:17:34 +0000505 or android.GetAndroidBranchForPackage(options.android_package)
506 )
Shao-Chuan Leedea458f2021-11-25 23:46:53 +0900507
Alex Klein1699fab2022-09-08 08:46:06 -0600508 (unstable_ebuild, stable_ebuilds) = FindAndroidCandidates(
509 android_package_dir
510 )
511 # Mirror artifacts, i.e., images and some sdk tools (e.g., adb, aapt).
512 version_to_uprev = android.MirrorArtifacts(
Shao-Chuan Lee20c51d82022-10-26 21:56:56 +0900513 options.android_package,
Alex Klein1699fab2022-09-08 08:46:06 -0600514 options.android_bucket_url,
Shao-Chuan Lee7e507e62022-11-15 02:17:34 +0000515 android_build_branch,
Alex Klein1699fab2022-09-08 08:46:06 -0600516 options.arc_bucket_url,
517 android_package_dir,
518 options.force_version,
519 )
David Rileyc0da9d92016-02-01 12:11:01 -0800520
Alex Klein1699fab2022-09-08 08:46:06 -0600521 stable_candidate = portage_util.BestEBuild(stable_ebuilds)
Shao-Chuan Leedea458f2021-11-25 23:46:53 +0900522
Alex Klein1699fab2022-09-08 08:46:06 -0600523 if stable_candidate:
524 logging.info("Stable candidate found %s", stable_candidate.version)
525 else:
526 logging.info("No stable candidate found.")
527
528 revved = MarkAndroidEBuildAsStable(
529 stable_candidate,
530 unstable_ebuild,
531 options.android_package,
532 version_to_uprev,
533 android_package_dir,
Shao-Chuan Lee7e507e62022-11-15 02:17:34 +0000534 android_build_branch,
Alex Klein1699fab2022-09-08 08:46:06 -0600535 options.arc_bucket_url,
536 options.runtime_artifacts_bucket_url,
537 )
538
539 output = dict(revved=bool(revved))
540
541 if revved:
542 android_atom, files_to_add, files_to_remove = revved
543 if not options.skip_commit:
544 _CommitChange(
545 _GIT_COMMIT_MESSAGE
546 % {
547 "android_package": options.android_package,
548 "android_version": version_to_uprev,
549 },
550 android_package_dir,
551 files_to_add,
552 files_to_remove,
553 )
554 if options.boards:
555 cros_mark_as_stable.CleanStalePackages(
556 options.srcroot, options.boards.split(":"), [android_atom]
557 )
558
559 output["android_atom"] = android_atom
560 # This field is read by the PUpr uprev handler for creating CLs. We cannot
561 # return absolute paths because this script runs inside chroot but the uprev
562 # handler runs outside.
563 # Here we return paths relative to |overlay_dir|.
564 output["modified_files"] = [
565 os.path.relpath(f, overlay_dir)
566 for f in files_to_add + files_to_remove
567 ]
568
569 # The output is being parsed by service.packages.uprev_android and has to be
570 # in its own single line. When invoked from chromite API endpoints, entering
571 # chroot can generate junk messages on stdout, so we prefix our output with a
572 # line break to further ensure that.
573 print("\n" + json.dumps(output, sort_keys=True))