blob: c58d6bcc030c2a1491181161de371fae91020312 [file] [log] [blame]
Mike Frysingere58c0e22017-10-04 15:43:30 -04001# -*- coding: utf-8 -*-
David Rileyc0da9d92016-02-01 12:11:01 -08002# Copyright 2016 The Chromium OS 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
6"""This module uprevs Android for cbuildbot.
7
8After calling, it prints outs ANDROID_VERSION_ATOM=(version atom string). A
9caller could then use this atom with emerge to build the newly uprevved version
10of Android e.g.
11
Shuhei Takahashi6d02c192017-04-05 14:01:24 +090012./cros_mark_android_as_stable \
Shao-Chuan Lee9c39e0c2020-04-24 11:40:34 +090013 --android_build_branch=git_pi-arc \
14 --android_package=android-container-pi
Shuhei Takahashi6d02c192017-04-05 14:01:24 +090015
Shao-Chuan Lee9c39e0c2020-04-24 11:40:34 +090016Returns chromeos-base/android-container-pi-6417892-r1
David Rileyc0da9d92016-02-01 12:11:01 -080017
Shao-Chuan Lee9c39e0c2020-04-24 11:40:34 +090018emerge-eve =chromeos-base/android-container-pi-6417892-r1
David Rileyc0da9d92016-02-01 12:11:01 -080019"""
20
21from __future__ import print_function
22
23import filecmp
24import glob
25import os
Hidehiko Abe12727dd2016-05-27 23:23:45 +090026import re
khmel@google.com96c193e2018-05-10 14:00:38 -070027import time
Mike Frysinger00a02292020-04-19 06:28:03 -040028import sys
David Rileyc0da9d92016-02-01 12:11:01 -080029
Aviv Keshetb7519e12016-10-04 00:50:00 -070030from chromite.lib import constants
David Rileyc0da9d92016-02-01 12:11:01 -080031from chromite.lib import commandline
32from chromite.lib import cros_build_lib
33from chromite.lib import cros_logging as logging
34from chromite.lib import git
35from chromite.lib import gs
36from chromite.lib import portage_util
37from chromite.scripts import cros_mark_as_stable
38
39
Mike Frysinger00a02292020-04-19 06:28:03 -040040assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'
41
42
David Rileyc0da9d92016-02-01 12:11:01 -080043# Dir where all the action happens.
44_OVERLAY_DIR = '%(srcroot)s/private-overlays/project-cheets-private/'
45
Junichi Uekawa6d61ab02020-04-15 14:52:28 +090046_GIT_COMMIT_MESSAGE = """Marking latest for %(android_package)s ebuild with \
47version %(android_version)s as stable.
48
49BUG=None
50TEST=CQ
51"""
David Rileyc0da9d92016-02-01 12:11:01 -080052
David Rileyc0da9d92016-02-01 12:11:01 -080053
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +090054def IsBuildIdValid(bucket_url, build_branch, build_id, targets):
David Rileyc0da9d92016-02-01 12:11:01 -080055 """Checks that a specific build_id is valid.
56
57 Looks for that build_id for all builds. Confirms that the subpath can
58 be found and that the zip file is present in that subdirectory.
59
60 Args:
61 bucket_url: URL of Android build gs bucket
62 build_branch: branch of Android builds
63 build_id: A string. The Android build id number to check.
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +090064 targets: Dict from build key to (targe build suffix, artifact file pattern)
65 pair.
David Rileyc0da9d92016-02-01 12:11:01 -080066
67 Returns:
68 Returns subpaths dictionary if build_id is valid.
69 None if the build_id is not valid.
70 """
71 gs_context = gs.GSContext()
72 subpaths_dict = {}
Mike Frysinger0bdbc102019-06-13 15:27:29 -040073 for build, (target, _) in targets.items():
David Rileyc0da9d92016-02-01 12:11:01 -080074 build_dir = '%s-%s' % (build_branch, target)
75 build_id_path = os.path.join(bucket_url, build_dir, build_id)
76
77 # Find name of subpath.
78 try:
79 subpaths = gs_context.List(build_id_path)
80 except gs.GSNoSuchKey:
Mike Frysinger968c1142020-05-09 00:37:56 -040081 logging.warning(
David Rileyc0da9d92016-02-01 12:11:01 -080082 'Directory [%s] does not contain any subpath, ignoring it.',
83 build_id_path)
84 return None
85 if len(subpaths) > 1:
Mike Frysinger968c1142020-05-09 00:37:56 -040086 logging.warning(
David Rileyc0da9d92016-02-01 12:11:01 -080087 'Directory [%s] contains more than one subpath, ignoring it.',
88 build_id_path)
89 return None
90
91 subpath_dir = subpaths[0].url.rstrip('/')
92 subpath_name = os.path.basename(subpath_dir)
93
94 # Look for a zipfile ending in the build_id number.
95 try:
Hidehiko Abe12727dd2016-05-27 23:23:45 +090096 gs_context.List(subpath_dir)
David Rileyc0da9d92016-02-01 12:11:01 -080097 except gs.GSNoSuchKey:
Mike Frysinger968c1142020-05-09 00:37:56 -040098 logging.warning(
Hidehiko Abe12727dd2016-05-27 23:23:45 +090099 'Did not find a file for build id [%s] in directory [%s].',
David Rileyc0da9d92016-02-01 12:11:01 -0800100 build_id, subpath_dir)
101 return None
102
103 # Record subpath for the build.
104 subpaths_dict[build] = subpath_name
105
106 # If we got here, it means we found an appropriate build for all platforms.
107 return subpaths_dict
108
109
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900110def GetLatestBuild(bucket_url, build_branch, targets):
David Rileyc0da9d92016-02-01 12:11:01 -0800111 """Searches the gs bucket for the latest green build.
112
113 Args:
114 bucket_url: URL of Android build gs bucket
115 build_branch: branch of Android builds
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900116 targets: Dict from build key to (targe build suffix, artifact file pattern)
117 pair.
David Rileyc0da9d92016-02-01 12:11:01 -0800118
119 Returns:
120 Tuple of (latest version string, subpaths dictionary)
121 If no latest build can be found, returns None, None
122 """
123 gs_context = gs.GSContext()
124 common_build_ids = None
125 # Find builds for each target.
Mike Frysinger0bdbc102019-06-13 15:27:29 -0400126 for target, _ in targets.values():
David Rileyc0da9d92016-02-01 12:11:01 -0800127 build_dir = '-'.join((build_branch, target))
128 base_path = os.path.join(bucket_url, build_dir)
129 build_ids = []
130 for gs_result in gs_context.List(base_path):
131 # Remove trailing slashes and get the base name, which is the build_id.
132 build_id = os.path.basename(gs_result.url.rstrip('/'))
133 if not build_id.isdigit():
Mike Frysinger968c1142020-05-09 00:37:56 -0400134 logging.warning('Directory [%s] does not look like a valid build_id.',
135 gs_result.url)
David Rileyc0da9d92016-02-01 12:11:01 -0800136 continue
137 build_ids.append(build_id)
138
139 # Update current list of builds.
140 if common_build_ids is None:
141 # First run, populate it with the first platform.
142 common_build_ids = set(build_ids)
143 else:
144 # Already populated, find the ones that are common.
145 common_build_ids.intersection_update(build_ids)
146
147 if common_build_ids is None:
Mike Frysinger968c1142020-05-09 00:37:56 -0400148 logging.warning('Did not find a build_id common to all platforms.')
David Rileyc0da9d92016-02-01 12:11:01 -0800149 return None, None
150
151 # Otherwise, find the most recent one that is valid.
152 for build_id in sorted(common_build_ids, key=int, reverse=True):
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900153 subpaths = IsBuildIdValid(bucket_url, build_branch, build_id, targets)
David Rileyc0da9d92016-02-01 12:11:01 -0800154 if subpaths:
155 return build_id, subpaths
156
157 # If not found, no build_id is valid.
Mike Frysinger968c1142020-05-09 00:37:56 -0400158 logging.warning('Did not find a build_id valid on all platforms.')
David Rileyc0da9d92016-02-01 12:11:01 -0800159 return None, None
160
161
162def FindAndroidCandidates(package_dir):
163 """Return a tuple of Android's unstable ebuild and stable ebuilds.
164
165 Args:
166 package_dir: The path to where the package ebuild is stored.
167
168 Returns:
169 Tuple [unstable_ebuild, stable_ebuilds].
170
171 Raises:
172 Exception: if no unstable ebuild exists for Android.
173 """
174 stable_ebuilds = []
175 unstable_ebuilds = []
176 for path in glob.glob(os.path.join(package_dir, '*.ebuild')):
177 ebuild = portage_util.EBuild(path)
178 if ebuild.version == '9999':
179 unstable_ebuilds.append(ebuild)
180 else:
181 stable_ebuilds.append(ebuild)
182
183 # Apply some sanity checks.
184 if not unstable_ebuilds:
185 raise Exception('Missing 9999 ebuild for %s' % package_dir)
186 if not stable_ebuilds:
Lann Martinffb95162018-08-28 12:02:54 -0600187 logging.warning('Missing stable ebuild for %s', package_dir)
David Rileyc0da9d92016-02-01 12:11:01 -0800188
189 return portage_util.BestEBuild(unstable_ebuilds), stable_ebuilds
190
191
Nicolas Norvezb08f54d2016-12-05 17:58:54 -0800192def _GetArcBasename(build, basename):
193 """Tweaks filenames between Android bucket and ARC++ bucket.
194
195 Android builders create build artifacts with the same name for -user and
196 -userdebug builds, which breaks the android-container ebuild (b/33072485).
197 When copying the artifacts from the Android bucket to the ARC++ bucket some
198 artifacts will be renamed from the usual pattern
199 *cheets_${ARCH}-target_files-S{VERSION}.zip to
200 cheets_${BUILD_NAME}-target_files-S{VERSION}.zip which will typically look
201 like cheets_(${LABEL})*${ARCH}_userdebug-target_files-S{VERSION}.zip.
202
203 Args:
204 build: the build being mirrored, e.g. 'X86', 'ARM', 'X86_USERDEBUG'.
205 basename: the basename of the artifact to copy.
206
207 Returns:
208 The basename of the destination.
209 """
210 if build not in constants.ARC_BUILDS_NEED_ARTIFACTS_RENAMED:
211 return basename
Yūki Ishiief1ada92018-03-27 15:46:15 +0900212 if basename in constants.ARC_ARTIFACTS_RENAME_NOT_NEEDED:
213 return basename
Nicolas Norvezb08f54d2016-12-05 17:58:54 -0800214 to_discard, sep, to_keep = basename.partition('-')
215 if not sep:
216 logging.error(('Build %s: Could not find separator "-" in artifact'
217 ' basename %s'), build, basename)
218 return basename
Bernie Thompson63ed5612017-08-16 12:27:34 -0700219 if 'cheets_' in to_discard:
220 return 'cheets_%s-%s' % (build.lower(), to_keep)
221 elif 'bertha_' in to_discard:
222 return 'bertha_%s-%s' % (build.lower(), to_keep)
223 logging.error('Build %s: Unexpected artifact basename %s',
224 build, basename)
225 return basename
Nicolas Norvezb08f54d2016-12-05 17:58:54 -0800226
227
David Riley73f00d92016-02-16 18:54:20 -0800228def CopyToArcBucket(android_bucket_url, build_branch, build_id, subpaths,
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900229 targets, arc_bucket_url, acls):
David Riley73f00d92016-02-16 18:54:20 -0800230 """Copies from source Android bucket to ARC++ specific bucket.
231
232 Copies each build to the ARC bucket eliminating the subpath.
233 Applies build specific ACLs for each file.
234
235 Args:
236 android_bucket_url: URL of Android build gs bucket
237 build_branch: branch of Android builds
238 build_id: A string. The Android build id number to check.
239 subpaths: Subpath dictionary for each build to copy.
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900240 targets: Dict from build key to (targe build suffix, artifact file pattern)
241 pair.
David Riley73f00d92016-02-16 18:54:20 -0800242 arc_bucket_url: URL of the target ARC build gs bucket
243 acls: ACLs dictionary for each build to copy.
244 """
245 gs_context = gs.GSContext()
Mike Frysinger0bdbc102019-06-13 15:27:29 -0400246 for build, subpath in subpaths.items():
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900247 target, pattern = targets[build]
David Riley73f00d92016-02-16 18:54:20 -0800248 build_dir = '%s-%s' % (build_branch, target)
249 android_dir = os.path.join(android_bucket_url, build_dir, build_id, subpath)
250 arc_dir = os.path.join(arc_bucket_url, build_dir, build_id)
251
Hidehiko Abe12727dd2016-05-27 23:23:45 +0900252 # Copy all target files from android_dir to arc_dir, setting ACLs.
253 for targetfile in gs_context.List(android_dir):
254 if re.search(pattern, targetfile.url):
255 basename = os.path.basename(targetfile.url)
Nicolas Norvezb08f54d2016-12-05 17:58:54 -0800256 arc_path = os.path.join(arc_dir, _GetArcBasename(build, basename))
David Riley73f00d92016-02-16 18:54:20 -0800257 acl = acls[build]
258 needs_copy = True
khmel@google.com96c193e2018-05-10 14:00:38 -0700259 retry_count = 2
David Riley73f00d92016-02-16 18:54:20 -0800260
khmel@google.com96c193e2018-05-10 14:00:38 -0700261 # Retry in case race condition when several boards trying to copy the
262 # same resource
263 while True:
264 # Check a pre-existing file with the original source.
265 if gs_context.Exists(arc_path):
266 if (gs_context.Stat(targetfile.url).hash_crc32c !=
267 gs_context.Stat(arc_path).hash_crc32c):
Mike Frysinger968c1142020-05-09 00:37:56 -0400268 logging.warning('Removing incorrect file %s', arc_path)
khmel@google.com96c193e2018-05-10 14:00:38 -0700269 gs_context.Remove(arc_path)
270 else:
271 logging.info('Skipping already copied file %s', arc_path)
272 needs_copy = False
David Riley73f00d92016-02-16 18:54:20 -0800273
khmel@google.com96c193e2018-05-10 14:00:38 -0700274 # Copy if necessary, and set the ACL unconditionally.
275 # The Stat() call above doesn't verify the ACL is correct and
276 # the ChangeACL should be relatively cheap compared to the copy.
277 # This covers the following caes:
278 # - handling an interrupted copy from a previous run.
279 # - rerunning the copy in case one of the googlestorage_acl_X.txt
280 # files changes (e.g. we add a new variant which reuses a build).
281 if needs_copy:
282 logging.info('Copying %s -> %s (acl %s)',
283 targetfile.url, arc_path, acl)
284 try:
285 gs_context.Copy(targetfile.url, arc_path, version=0)
286 except gs.GSContextPreconditionFailed as error:
287 if not retry_count:
288 raise error
289 # Retry one more time after a short delay
290 logging.warning('Will retry copying %s -> %s',
291 targetfile.url, arc_path)
292 time.sleep(5)
293 retry_count = retry_count - 1
294 continue
295 gs_context.ChangeACL(arc_path, acl_args_file=acl)
296 break
David Riley73f00d92016-02-16 18:54:20 -0800297
298
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900299def MirrorArtifacts(android_bucket_url, android_build_branch, arc_bucket_url,
300 acls, targets, version=None):
301 """Mirrors artifacts from Android bucket to ARC bucket.
302
303 First, this function identifies which build version should be copied,
304 if not given. Please see GetLatestBuild() and IsBuildIdValid() for details.
305
306 On build version identified, then copies target artifacts to the ARC bucket,
307 with setting ACLs.
308
309 Args:
310 android_bucket_url: URL of Android build gs bucket
311 android_build_branch: branch of Android builds
312 arc_bucket_url: URL of the target ARC build gs bucket
313 acls: ACLs dictionary for each build to copy.
314 targets: Dict from build key to (targe build suffix, artifact file pattern)
315 pair.
316 version: (optional) A string. The Android build id number to check.
317 If not passed, detect latest good build version.
318
319 Returns:
320 Mirrored version.
321 """
322 if version:
323 subpaths = IsBuildIdValid(
324 android_bucket_url, android_build_branch, version, targets)
325 if not subpaths:
Lann Martinffb95162018-08-28 12:02:54 -0600326 logging.error('Requested build %s is not valid', version)
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900327 else:
328 version, subpaths = GetLatestBuild(
329 android_bucket_url, android_build_branch, targets)
330
331 CopyToArcBucket(android_bucket_url, android_build_branch, version, subpaths,
332 targets, arc_bucket_url, acls)
khmel@google.com778a1cd2018-04-13 11:11:58 -0700333
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900334 return version
335
336
David Riley73f00d92016-02-16 18:54:20 -0800337def MakeAclDict(package_dir):
338 """Creates a dictionary of acl files for each build type.
339
340 Args:
341 package_dir: The path to where the package acl files are stored.
342
343 Returns:
344 Returns acls dictionary.
345 """
346 return dict(
347 (k, os.path.join(package_dir, v))
348 for k, v in constants.ARC_BUCKET_ACLS.items()
349 )
350
351
Qijiang Fan6588cc92019-11-20 13:26:04 +0900352def MakeBuildTargetDict(package_name, build_branch):
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700353 """Creates a dictionary of build targets.
354
Bernie Thompson63ed5612017-08-16 12:27:34 -0700355 Not all targets are common between branches, for example
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700356 sdk_google_cheets_x86 only exists on N.
357 This generates a dictionary listing the available build targets for a
358 specific branch.
359
360 Args:
Qijiang Fan6588cc92019-11-20 13:26:04 +0900361 package_name: package name of chromeos arc package.
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700362 build_branch: branch of Android builds.
363
364 Returns:
365 Returns build target dictionary.
366
367 Raises:
368 ValueError: if the Android build branch is invalid.
369 """
Qijiang Fan6588cc92019-11-20 13:26:04 +0900370 if constants.ANDROID_CONTAINER_PACKAGE_KEYWORD in package_name:
Federico 'Morg' Pareschi041ee652020-03-10 15:09:42 +0900371 target_list = {
372 constants.ANDROID_MST_BUILD_BRANCH:
373 constants.ANDROID_MST_BUILD_TARGETS,
Federico 'Morg' Pareschi041ee652020-03-10 15:09:42 +0900374 constants.ANDROID_PI_BUILD_BRANCH:
375 constants.ANDROID_PI_BUILD_TARGETS,
376 constants.ANDROID_QT_BUILD_BRANCH:
377 constants.ANDROID_QT_BUILD_TARGETS,
378 constants.ANDROID_RVC_BUILD_BRANCH:
379 constants.ANDROID_RVC_BUILD_TARGETS,
380 }
Qijiang Fan6588cc92019-11-20 13:26:04 +0900381 elif constants.ANDROID_VM_PACKAGE_KEYWORD in package_name:
Federico 'Morg' Pareschi041ee652020-03-10 15:09:42 +0900382 target_list = {
383 constants.ANDROID_VMPI_BUILD_BRANCH:
384 constants.ANDROID_VMPI_BUILD_TARGETS,
385 constants.ANDROID_VMMST_BUILD_BRANCH:
386 constants.ANDROID_VMMST_BUILD_TARGETS,
387 constants.ANDROID_VMRVC_BUILD_BRANCH:
388 constants.ANDROID_VMRVC_BUILD_TARGETS,
389 }
390 else:
391 raise ValueError('Unknown package: %s' % package_name)
392 target = target_list.get(build_branch)
393 if not target:
Qijiang Fan6588cc92019-11-20 13:26:04 +0900394 raise ValueError('Unknown branch: %s' % build_branch)
Federico 'Morg' Pareschi041ee652020-03-10 15:09:42 +0900395 return target
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700396
397
Shao-Chuan Lee085e3d72020-05-11 16:00:42 +0900398def PrintUprevMetadata(build_branch, stable_candidate, new_ebuild):
399 """Shows metadata on buildbot page at UprevAndroid step.
David Rileyc0da9d92016-02-01 12:11:01 -0800400
401 Args:
Shao-Chuan Lee085e3d72020-05-11 16:00:42 +0900402 build_branch: The branch of Android builds.
403 stable_candidate: The existing stable ebuild.
404 new_ebuild: The newly written ebuild.
David Rileyc0da9d92016-02-01 12:11:01 -0800405 """
Shao-Chuan Lee085e3d72020-05-11 16:00:42 +0900406 # Examples:
407 # "android-container-pi revved 6461825-r1 -> 6468247-r1"
408 # "android-container-pi revved 6461825-r1 -> 6461825-r2 (ebuild update only)"
409 msg = '%s revved %s -> %s' % (stable_candidate.pkgname,
410 stable_candidate.version,
411 new_ebuild.version)
412
413 old_android = stable_candidate.version_no_rev
414 new_android = new_ebuild.version_no_rev
415
416 if old_android == new_android:
417 msg += ' (ebuild update only)'
418 else:
419 ab_link = ('https://android-build.googleplex.com'
420 '/builds/%s/branches/%s/cls?end=%s'
421 % (new_android, build_branch, old_android))
422 logging.PrintBuildbotLink('Android changelog', ab_link)
423
424 logging.PrintBuildbotStepText(msg)
David Rileyc0da9d92016-02-01 12:11:01 -0800425
426
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900427def MarkAndroidEBuildAsStable(stable_candidate, unstable_ebuild,
428 android_package, android_version, package_dir,
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700429 build_branch, arc_bucket_url, build_targets):
David Rileyc0da9d92016-02-01 12:11:01 -0800430 r"""Uprevs the Android ebuild.
431
432 This is the main function that uprevs from a stable candidate
433 to its new version.
434
435 Args:
436 stable_candidate: ebuild that corresponds to the stable ebuild we are
437 revving from. If None, builds the a new ebuild given the version
438 with revision set to 1.
439 unstable_ebuild: ebuild corresponding to the unstable ebuild for Android.
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900440 android_package: android package name.
David Rileyc0da9d92016-02-01 12:11:01 -0800441 android_version: The \d+ build id of Android.
David Rileyc0da9d92016-02-01 12:11:01 -0800442 package_dir: Path to the android-container package dir.
David Riley73f00d92016-02-16 18:54:20 -0800443 build_branch: branch of Android builds.
444 arc_bucket_url: URL of the target ARC build gs bucket.
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700445 build_targets: build targets for this particular Android branch.
David Rileyc0da9d92016-02-01 12:11:01 -0800446
447 Returns:
448 Full portage version atom (including rc's, etc) that was revved.
449 """
450 def IsTheNewEBuildRedundant(new_ebuild, stable_ebuild):
451 """Returns True if the new ebuild is redundant.
452
453 This is True if there if the current stable ebuild is the exact same copy
454 of the new one.
455 """
456 if not stable_ebuild:
457 return False
458
David Riley676f5402016-02-12 17:24:23 -0800459 if stable_candidate.version_no_rev == new_ebuild.version_no_rev:
David Rileyc0da9d92016-02-01 12:11:01 -0800460 return filecmp.cmp(
461 new_ebuild.ebuild_path, stable_ebuild.ebuild_path, shallow=False)
462
463 # Case where we have the last stable candidate with same version just rev.
David Riley676f5402016-02-12 17:24:23 -0800464 if stable_candidate and stable_candidate.version_no_rev == android_version:
David Rileyc0da9d92016-02-01 12:11:01 -0800465 new_ebuild_path = '%s-r%d.ebuild' % (
466 stable_candidate.ebuild_path_no_revision,
467 stable_candidate.current_revision + 1)
468 else:
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900469 pf = '%s-%s-r1' % (android_package, android_version)
David Rileyc0da9d92016-02-01 12:11:01 -0800470 new_ebuild_path = os.path.join(package_dir, '%s.ebuild' % pf)
471
David Riley73f00d92016-02-16 18:54:20 -0800472 variables = {'BASE_URL': arc_bucket_url}
Mike Frysinger0bdbc102019-06-13 15:27:29 -0400473 for build, (target, _) in build_targets.items():
David Riley73f00d92016-02-16 18:54:20 -0800474 variables[build + '_TARGET'] = '%s-%s' % (build_branch, target)
David Rileyc0da9d92016-02-01 12:11:01 -0800475
476 portage_util.EBuild.MarkAsStable(
477 unstable_ebuild.ebuild_path, new_ebuild_path,
478 variables, make_stable=True)
479 new_ebuild = portage_util.EBuild(new_ebuild_path)
480
481 # Determine whether this is ebuild is redundant.
482 if IsTheNewEBuildRedundant(new_ebuild, stable_candidate):
483 msg = 'Previous ebuild with same version found and ebuild is redundant.'
484 logging.info(msg)
Shao-Chuan Lee085e3d72020-05-11 16:00:42 +0900485 logging.PrintBuildbotStepText('%s %s not revved'
486 % (stable_candidate.pkgname,
487 stable_candidate.version))
David Rileyc0da9d92016-02-01 12:11:01 -0800488 os.unlink(new_ebuild_path)
489 return None
490
Shao-Chuan Lee085e3d72020-05-11 16:00:42 +0900491 # PFQ runs should always be able to find a stable candidate.
David Rileyc0da9d92016-02-01 12:11:01 -0800492 if stable_candidate:
Shao-Chuan Lee085e3d72020-05-11 16:00:42 +0900493 PrintUprevMetadata(build_branch, stable_candidate, new_ebuild)
David Rileyc0da9d92016-02-01 12:11:01 -0800494
495 git.RunGit(package_dir, ['add', new_ebuild_path])
496 if stable_candidate and not stable_candidate.IsSticky():
497 git.RunGit(package_dir, ['rm', stable_candidate.ebuild_path])
498
499 # Update ebuild manifest and git add it.
500 gen_manifest_cmd = ['ebuild', new_ebuild_path, 'manifest', '--force']
Mike Frysinger45602c72019-09-22 02:15:11 -0400501 cros_build_lib.run(gen_manifest_cmd, extra_env=None, print_cmd=True)
David Rileyc0da9d92016-02-01 12:11:01 -0800502 git.RunGit(package_dir, ['add', 'Manifest'])
503
504 portage_util.EBuild.CommitChange(
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900505 _GIT_COMMIT_MESSAGE % {'android_package': android_package,
David Rileyc0da9d92016-02-01 12:11:01 -0800506 'android_version': android_version},
507 package_dir)
508
509 return '%s-%s' % (new_ebuild.package, new_ebuild.version)
510
511
512def GetParser():
513 """Creates the argument parser."""
514 parser = commandline.ArgumentParser()
515 parser.add_argument('-b', '--boards')
516 parser.add_argument('--android_bucket_url',
David Riley73f00d92016-02-16 18:54:20 -0800517 default=constants.ANDROID_BUCKET_URL,
518 type='gs_path')
David Rileyc0da9d92016-02-01 12:11:01 -0800519 parser.add_argument('--android_build_branch',
Shuhei Takahashi6d02c192017-04-05 14:01:24 +0900520 required=True,
521 help='Android branch to import from. '
522 'Ex: git_mnc-dr-arc-dev')
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900523 parser.add_argument('--android_package',
524 default=constants.ANDROID_PACKAGE_NAME)
David Riley73f00d92016-02-16 18:54:20 -0800525 parser.add_argument('--arc_bucket_url',
526 default=constants.ARC_BUCKET_URL,
527 type='gs_path')
David Rileyc0da9d92016-02-01 12:11:01 -0800528 parser.add_argument('-f', '--force_version',
529 help='Android build id to use')
530 parser.add_argument('-s', '--srcroot',
531 default=os.path.join(os.environ['HOME'], 'trunk', 'src'),
532 help='Path to the src directory')
533 parser.add_argument('-t', '--tracking_branch', default='cros/master',
534 help='Branch we are tracking changes against')
535 return parser
536
537
538def main(argv):
Hidehiko Abec9ecf262017-07-05 15:17:41 +0900539 logging.EnableBuildbotMarkers()
David Rileyc0da9d92016-02-01 12:11:01 -0800540 parser = GetParser()
541 options = parser.parse_args(argv)
542 options.Freeze()
543
544 overlay_dir = os.path.abspath(_OVERLAY_DIR % {'srcroot': options.srcroot})
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900545 android_package_dir = os.path.join(
546 overlay_dir,
547 portage_util.GetFullAndroidPortagePackageName(options.android_package))
David Rileyc0da9d92016-02-01 12:11:01 -0800548 version_to_uprev = None
David Rileyc0da9d92016-02-01 12:11:01 -0800549
550 (unstable_ebuild, stable_ebuilds) = FindAndroidCandidates(android_package_dir)
David Riley73f00d92016-02-16 18:54:20 -0800551 acls = MakeAclDict(android_package_dir)
Qijiang Fan6588cc92019-11-20 13:26:04 +0900552 build_targets = MakeBuildTargetDict(options.android_package,
553 options.android_build_branch)
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900554 # Mirror artifacts, i.e., images and some sdk tools (e.g., adb, aapt).
555 version_to_uprev = MirrorArtifacts(options.android_bucket_url,
556 options.android_build_branch,
557 options.arc_bucket_url, acls,
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700558 build_targets,
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900559 options.force_version)
560
David Rileyc0da9d92016-02-01 12:11:01 -0800561 stable_candidate = portage_util.BestEBuild(stable_ebuilds)
562
563 if stable_candidate:
Lann Martinffb95162018-08-28 12:02:54 -0600564 logging.info('Stable candidate found %s', stable_candidate.version)
David Rileyc0da9d92016-02-01 12:11:01 -0800565 else:
566 logging.info('No stable candidate found.')
567
568 tracking_branch = 'remotes/m/%s' % os.path.basename(options.tracking_branch)
569 existing_branch = git.GetCurrentBranch(android_package_dir)
570 work_branch = cros_mark_as_stable.GitBranch(constants.STABLE_EBUILD_BRANCH,
571 tracking_branch,
572 android_package_dir)
573 work_branch.CreateBranch()
574
575 # In the case of uprevving overlays that have patches applied to them,
576 # include the patched changes in the stabilizing branch.
577 if existing_branch:
578 git.RunGit(overlay_dir, ['rebase', existing_branch])
579
580 android_version_atom = MarkAndroidEBuildAsStable(
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900581 stable_candidate, unstable_ebuild, options.android_package,
David Riley73f00d92016-02-16 18:54:20 -0800582 version_to_uprev, android_package_dir,
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700583 options.android_build_branch, options.arc_bucket_url, build_targets)
David Rileyc0da9d92016-02-01 12:11:01 -0800584 if android_version_atom:
585 if options.boards:
586 cros_mark_as_stable.CleanStalePackages(options.srcroot,
587 options.boards.split(':'),
588 [android_version_atom])
589
590 # Explicit print to communicate to caller.
591 print('ANDROID_VERSION_ATOM=%s' % android_version_atom)