blob: 3a5fa9425a483e8b266a2db18736fddc4538cc9d [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 \
13 --android_package=android-container \
14 --android_build_branch=git_mnc-dr-arc-dev \
15 --android_gts_build_branch=git_mnc-dev
16
David Rileyc0da9d92016-02-01 12:11:01 -080017Returns chromeos-base/android-container-2559197
18
19emerge-veyron_minnie-cheets =chromeos-base/android-container-2559197-r1
20"""
21
22from __future__ import print_function
23
24import filecmp
25import glob
26import os
Hidehiko Abe12727dd2016-05-27 23:23:45 +090027import re
David Rileyc0da9d92016-02-01 12:11:01 -080028
Aviv Keshetb7519e12016-10-04 00:50:00 -070029from chromite.lib import constants
David Rileyc0da9d92016-02-01 12:11:01 -080030from chromite.lib import commandline
31from chromite.lib import cros_build_lib
32from chromite.lib import cros_logging as logging
33from chromite.lib import git
34from chromite.lib import gs
35from chromite.lib import portage_util
36from chromite.scripts import cros_mark_as_stable
37
38
39# Dir where all the action happens.
40_OVERLAY_DIR = '%(srcroot)s/private-overlays/project-cheets-private/'
41
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +090042_GIT_COMMIT_MESSAGE = ('Marking latest for %(android_package)s ebuild '
David Rileyc0da9d92016-02-01 12:11:01 -080043 'with version %(android_version)s as stable.')
44
45# URLs that print lists of Android revisions between two build ids.
46_ANDROID_VERSION_URL = ('http://android-build-uber.corp.google.com/repo.html?'
47 'last_bid=%(old)s&bid=%(new)s&branch=%(branch)s')
48
49
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +090050def IsBuildIdValid(bucket_url, build_branch, build_id, targets):
David Rileyc0da9d92016-02-01 12:11:01 -080051 """Checks that a specific build_id is valid.
52
53 Looks for that build_id for all builds. Confirms that the subpath can
54 be found and that the zip file is present in that subdirectory.
55
56 Args:
57 bucket_url: URL of Android build gs bucket
58 build_branch: branch of Android builds
59 build_id: A string. The Android build id number to check.
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +090060 targets: Dict from build key to (targe build suffix, artifact file pattern)
61 pair.
David Rileyc0da9d92016-02-01 12:11:01 -080062
63 Returns:
64 Returns subpaths dictionary if build_id is valid.
65 None if the build_id is not valid.
66 """
67 gs_context = gs.GSContext()
68 subpaths_dict = {}
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +090069 for build, (target, _) in targets.iteritems():
David Rileyc0da9d92016-02-01 12:11:01 -080070 build_dir = '%s-%s' % (build_branch, target)
71 build_id_path = os.path.join(bucket_url, build_dir, build_id)
72
73 # Find name of subpath.
74 try:
75 subpaths = gs_context.List(build_id_path)
76 except gs.GSNoSuchKey:
77 logging.warn(
78 'Directory [%s] does not contain any subpath, ignoring it.',
79 build_id_path)
80 return None
81 if len(subpaths) > 1:
82 logging.warn(
83 'Directory [%s] contains more than one subpath, ignoring it.',
84 build_id_path)
85 return None
86
87 subpath_dir = subpaths[0].url.rstrip('/')
88 subpath_name = os.path.basename(subpath_dir)
89
90 # Look for a zipfile ending in the build_id number.
91 try:
Hidehiko Abe12727dd2016-05-27 23:23:45 +090092 gs_context.List(subpath_dir)
David Rileyc0da9d92016-02-01 12:11:01 -080093 except gs.GSNoSuchKey:
94 logging.warn(
Hidehiko Abe12727dd2016-05-27 23:23:45 +090095 'Did not find a file for build id [%s] in directory [%s].',
David Rileyc0da9d92016-02-01 12:11:01 -080096 build_id, subpath_dir)
97 return None
98
99 # Record subpath for the build.
100 subpaths_dict[build] = subpath_name
101
102 # If we got here, it means we found an appropriate build for all platforms.
103 return subpaths_dict
104
105
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900106def GetLatestBuild(bucket_url, build_branch, targets):
David Rileyc0da9d92016-02-01 12:11:01 -0800107 """Searches the gs bucket for the latest green build.
108
109 Args:
110 bucket_url: URL of Android build gs bucket
111 build_branch: branch of Android builds
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900112 targets: Dict from build key to (targe build suffix, artifact file pattern)
113 pair.
David Rileyc0da9d92016-02-01 12:11:01 -0800114
115 Returns:
116 Tuple of (latest version string, subpaths dictionary)
117 If no latest build can be found, returns None, None
118 """
119 gs_context = gs.GSContext()
120 common_build_ids = None
121 # Find builds for each target.
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900122 for target, _ in targets.itervalues():
David Rileyc0da9d92016-02-01 12:11:01 -0800123 build_dir = '-'.join((build_branch, target))
124 base_path = os.path.join(bucket_url, build_dir)
125 build_ids = []
126 for gs_result in gs_context.List(base_path):
127 # Remove trailing slashes and get the base name, which is the build_id.
128 build_id = os.path.basename(gs_result.url.rstrip('/'))
129 if not build_id.isdigit():
130 logging.warn('Directory [%s] does not look like a valid build_id.',
131 gs_result.url)
132 continue
133 build_ids.append(build_id)
134
135 # Update current list of builds.
136 if common_build_ids is None:
137 # First run, populate it with the first platform.
138 common_build_ids = set(build_ids)
139 else:
140 # Already populated, find the ones that are common.
141 common_build_ids.intersection_update(build_ids)
142
143 if common_build_ids is None:
144 logging.warn('Did not find a build_id common to all platforms.')
145 return None, None
146
147 # Otherwise, find the most recent one that is valid.
148 for build_id in sorted(common_build_ids, key=int, reverse=True):
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900149 subpaths = IsBuildIdValid(bucket_url, build_branch, build_id, targets)
David Rileyc0da9d92016-02-01 12:11:01 -0800150 if subpaths:
151 return build_id, subpaths
152
153 # If not found, no build_id is valid.
154 logging.warn('Did not find a build_id valid on all platforms.')
155 return None, None
156
157
158def FindAndroidCandidates(package_dir):
159 """Return a tuple of Android's unstable ebuild and stable ebuilds.
160
161 Args:
162 package_dir: The path to where the package ebuild is stored.
163
164 Returns:
165 Tuple [unstable_ebuild, stable_ebuilds].
166
167 Raises:
168 Exception: if no unstable ebuild exists for Android.
169 """
170 stable_ebuilds = []
171 unstable_ebuilds = []
172 for path in glob.glob(os.path.join(package_dir, '*.ebuild')):
173 ebuild = portage_util.EBuild(path)
174 if ebuild.version == '9999':
175 unstable_ebuilds.append(ebuild)
176 else:
177 stable_ebuilds.append(ebuild)
178
179 # Apply some sanity checks.
180 if not unstable_ebuilds:
181 raise Exception('Missing 9999 ebuild for %s' % package_dir)
182 if not stable_ebuilds:
183 logging.warning('Missing stable ebuild for %s' % package_dir)
184
185 return portage_util.BestEBuild(unstable_ebuilds), stable_ebuilds
186
187
Nicolas Norvezb08f54d2016-12-05 17:58:54 -0800188def _GetArcBasename(build, basename):
189 """Tweaks filenames between Android bucket and ARC++ bucket.
190
191 Android builders create build artifacts with the same name for -user and
192 -userdebug builds, which breaks the android-container ebuild (b/33072485).
193 When copying the artifacts from the Android bucket to the ARC++ bucket some
194 artifacts will be renamed from the usual pattern
195 *cheets_${ARCH}-target_files-S{VERSION}.zip to
196 cheets_${BUILD_NAME}-target_files-S{VERSION}.zip which will typically look
197 like cheets_(${LABEL})*${ARCH}_userdebug-target_files-S{VERSION}.zip.
198
199 Args:
200 build: the build being mirrored, e.g. 'X86', 'ARM', 'X86_USERDEBUG'.
201 basename: the basename of the artifact to copy.
202
203 Returns:
204 The basename of the destination.
205 """
206 if build not in constants.ARC_BUILDS_NEED_ARTIFACTS_RENAMED:
207 return basename
208 to_discard, sep, to_keep = basename.partition('-')
209 if not sep:
210 logging.error(('Build %s: Could not find separator "-" in artifact'
211 ' basename %s'), build, basename)
212 return basename
Bernie Thompson63ed5612017-08-16 12:27:34 -0700213 if 'cheets_' in to_discard:
214 return 'cheets_%s-%s' % (build.lower(), to_keep)
215 elif 'bertha_' in to_discard:
216 return 'bertha_%s-%s' % (build.lower(), to_keep)
217 logging.error('Build %s: Unexpected artifact basename %s',
218 build, basename)
219 return basename
Nicolas Norvezb08f54d2016-12-05 17:58:54 -0800220
221
David Riley73f00d92016-02-16 18:54:20 -0800222def CopyToArcBucket(android_bucket_url, build_branch, build_id, subpaths,
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900223 targets, arc_bucket_url, acls):
David Riley73f00d92016-02-16 18:54:20 -0800224 """Copies from source Android bucket to ARC++ specific bucket.
225
226 Copies each build to the ARC bucket eliminating the subpath.
227 Applies build specific ACLs for each file.
228
229 Args:
230 android_bucket_url: URL of Android build gs bucket
231 build_branch: branch of Android builds
232 build_id: A string. The Android build id number to check.
233 subpaths: Subpath dictionary for each build to copy.
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900234 targets: Dict from build key to (targe build suffix, artifact file pattern)
235 pair.
David Riley73f00d92016-02-16 18:54:20 -0800236 arc_bucket_url: URL of the target ARC build gs bucket
237 acls: ACLs dictionary for each build to copy.
238 """
239 gs_context = gs.GSContext()
240 for build, subpath in subpaths.iteritems():
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900241 target, pattern = targets[build]
David Riley73f00d92016-02-16 18:54:20 -0800242 build_dir = '%s-%s' % (build_branch, target)
243 android_dir = os.path.join(android_bucket_url, build_dir, build_id, subpath)
244 arc_dir = os.path.join(arc_bucket_url, build_dir, build_id)
245
Hidehiko Abe12727dd2016-05-27 23:23:45 +0900246 # Copy all target files from android_dir to arc_dir, setting ACLs.
247 for targetfile in gs_context.List(android_dir):
248 if re.search(pattern, targetfile.url):
249 basename = os.path.basename(targetfile.url)
Nicolas Norvezb08f54d2016-12-05 17:58:54 -0800250 arc_path = os.path.join(arc_dir, _GetArcBasename(build, basename))
David Riley73f00d92016-02-16 18:54:20 -0800251 acl = acls[build]
252 needs_copy = True
253
254 # Check a pre-existing file with the original source.
255 if gs_context.Exists(arc_path):
Hidehiko Abe12727dd2016-05-27 23:23:45 +0900256 if (gs_context.Stat(targetfile.url).hash_crc32c !=
Elijah Taylorbfc30692016-04-22 14:05:23 -0700257 gs_context.Stat(arc_path).hash_crc32c):
David Riley73f00d92016-02-16 18:54:20 -0800258 logging.warn('Removing incorrect file %s', arc_path)
259 gs_context.Remove(arc_path)
260 else:
261 logging.info('Skipping already copied file %s', arc_path)
262 needs_copy = False
263
264 # Copy if necessary, and set the ACL unconditionally.
265 # The Stat() call above doesn't verify the ACL is correct and
266 # the ChangeACL should be relatively cheap compared to the copy.
267 # This covers the following caes:
268 # - handling an interrupted copy from a previous run.
269 # - rerunning the copy in case one of the googlestorage_acl_X.txt
270 # files changes (e.g. we add a new variant which reuses a build).
271 if needs_copy:
Hidehiko Abe12727dd2016-05-27 23:23:45 +0900272 logging.info('Copying %s -> %s (acl %s)',
273 targetfile.url, arc_path, acl)
274 gs_context.Copy(targetfile.url, arc_path, version=0)
David Riley73f00d92016-02-16 18:54:20 -0800275 gs_context.ChangeACL(arc_path, acl_args_file=acl)
276
277
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900278def MirrorArtifacts(android_bucket_url, android_build_branch, arc_bucket_url,
279 acls, targets, version=None):
280 """Mirrors artifacts from Android bucket to ARC bucket.
281
282 First, this function identifies which build version should be copied,
283 if not given. Please see GetLatestBuild() and IsBuildIdValid() for details.
284
285 On build version identified, then copies target artifacts to the ARC bucket,
286 with setting ACLs.
287
288 Args:
289 android_bucket_url: URL of Android build gs bucket
290 android_build_branch: branch of Android builds
291 arc_bucket_url: URL of the target ARC build gs bucket
292 acls: ACLs dictionary for each build to copy.
293 targets: Dict from build key to (targe build suffix, artifact file pattern)
294 pair.
295 version: (optional) A string. The Android build id number to check.
296 If not passed, detect latest good build version.
297
298 Returns:
299 Mirrored version.
300 """
301 if version:
302 subpaths = IsBuildIdValid(
303 android_bucket_url, android_build_branch, version, targets)
304 if not subpaths:
305 logging.error('Requested build %s is not valid' % version)
306 else:
307 version, subpaths = GetLatestBuild(
308 android_bucket_url, android_build_branch, targets)
309
310 CopyToArcBucket(android_bucket_url, android_build_branch, version, subpaths,
311 targets, arc_bucket_url, acls)
312 return version
313
314
David Riley73f00d92016-02-16 18:54:20 -0800315def MakeAclDict(package_dir):
316 """Creates a dictionary of acl files for each build type.
317
318 Args:
319 package_dir: The path to where the package acl files are stored.
320
321 Returns:
322 Returns acls dictionary.
323 """
324 return dict(
325 (k, os.path.join(package_dir, v))
326 for k, v in constants.ARC_BUCKET_ACLS.items()
327 )
328
329
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700330def MakeBuildTargetDict(build_branch):
331 """Creates a dictionary of build targets.
332
Bernie Thompson63ed5612017-08-16 12:27:34 -0700333 Not all targets are common between branches, for example
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700334 sdk_google_cheets_x86 only exists on N.
335 This generates a dictionary listing the available build targets for a
336 specific branch.
337
338 Args:
339 build_branch: branch of Android builds.
340
341 Returns:
342 Returns build target dictionary.
343
344 Raises:
345 ValueError: if the Android build branch is invalid.
346 """
Bernie Thompson54650022018-01-12 10:03:20 -0800347 if build_branch == constants.ANDROID_MST_BUILD_BRANCH:
348 return constants.ANDROID_MST_BUILD_TARGETS
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700349 elif build_branch == constants.ANDROID_NYC_BUILD_BRANCH:
Bernie Thompson63ed5612017-08-16 12:27:34 -0700350 return constants.ANDROID_NYC_BUILD_TARGETS
Ben Linb8499402018-03-08 16:54:00 -0800351 elif build_branch == constants.ANDROID_PI_BUILD_BRANCH:
352 return constants.ANDROID_PI_BUILD_TARGETS
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700353 else:
354 raise ValueError('Unknown branch: %s' % build_branch)
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700355
356
David Rileyc0da9d92016-02-01 12:11:01 -0800357def GetAndroidRevisionListLink(build_branch, old_android, new_android):
358 """Returns a link to the list of revisions between two Android versions
359
360 Given two AndroidEBuilds, generate a link to a page that prints the
361 Android changes between those two revisions, inclusive.
362
363 Args:
364 build_branch: branch of Android builds
365 old_android: ebuild for the version to diff from
366 new_android: ebuild for the version to which to diff
367
368 Returns:
369 The desired URL.
370 """
371 return _ANDROID_VERSION_URL % {'branch': build_branch,
Hidehiko Abec9ecf262017-07-05 15:17:41 +0900372 'old': old_android.version_no_rev,
373 'new': new_android.version_no_rev}
David Rileyc0da9d92016-02-01 12:11:01 -0800374
375
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900376def MarkAndroidEBuildAsStable(stable_candidate, unstable_ebuild,
377 android_package, android_version, package_dir,
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700378 build_branch, arc_bucket_url, build_targets):
David Rileyc0da9d92016-02-01 12:11:01 -0800379 r"""Uprevs the Android ebuild.
380
381 This is the main function that uprevs from a stable candidate
382 to its new version.
383
384 Args:
385 stable_candidate: ebuild that corresponds to the stable ebuild we are
386 revving from. If None, builds the a new ebuild given the version
387 with revision set to 1.
388 unstable_ebuild: ebuild corresponding to the unstable ebuild for Android.
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900389 android_package: android package name.
David Rileyc0da9d92016-02-01 12:11:01 -0800390 android_version: The \d+ build id of Android.
David Rileyc0da9d92016-02-01 12:11:01 -0800391 package_dir: Path to the android-container package dir.
David Riley73f00d92016-02-16 18:54:20 -0800392 build_branch: branch of Android builds.
393 arc_bucket_url: URL of the target ARC build gs bucket.
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700394 build_targets: build targets for this particular Android branch.
David Rileyc0da9d92016-02-01 12:11:01 -0800395
396 Returns:
397 Full portage version atom (including rc's, etc) that was revved.
398 """
399 def IsTheNewEBuildRedundant(new_ebuild, stable_ebuild):
400 """Returns True if the new ebuild is redundant.
401
402 This is True if there if the current stable ebuild is the exact same copy
403 of the new one.
404 """
405 if not stable_ebuild:
406 return False
407
David Riley676f5402016-02-12 17:24:23 -0800408 if stable_candidate.version_no_rev == new_ebuild.version_no_rev:
David Rileyc0da9d92016-02-01 12:11:01 -0800409 return filecmp.cmp(
410 new_ebuild.ebuild_path, stable_ebuild.ebuild_path, shallow=False)
411
412 # Case where we have the last stable candidate with same version just rev.
David Riley676f5402016-02-12 17:24:23 -0800413 if stable_candidate and stable_candidate.version_no_rev == android_version:
David Rileyc0da9d92016-02-01 12:11:01 -0800414 new_ebuild_path = '%s-r%d.ebuild' % (
415 stable_candidate.ebuild_path_no_revision,
416 stable_candidate.current_revision + 1)
417 else:
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900418 pf = '%s-%s-r1' % (android_package, android_version)
David Rileyc0da9d92016-02-01 12:11:01 -0800419 new_ebuild_path = os.path.join(package_dir, '%s.ebuild' % pf)
420
David Riley73f00d92016-02-16 18:54:20 -0800421 variables = {'BASE_URL': arc_bucket_url}
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700422 for build, (target, _) in build_targets.iteritems():
David Riley73f00d92016-02-16 18:54:20 -0800423 variables[build + '_TARGET'] = '%s-%s' % (build_branch, target)
David Rileyc0da9d92016-02-01 12:11:01 -0800424
425 portage_util.EBuild.MarkAsStable(
426 unstable_ebuild.ebuild_path, new_ebuild_path,
427 variables, make_stable=True)
428 new_ebuild = portage_util.EBuild(new_ebuild_path)
429
430 # Determine whether this is ebuild is redundant.
431 if IsTheNewEBuildRedundant(new_ebuild, stable_candidate):
432 msg = 'Previous ebuild with same version found and ebuild is redundant.'
433 logging.info(msg)
434 os.unlink(new_ebuild_path)
435 return None
436
437 if stable_candidate:
438 logging.PrintBuildbotLink('Android revisions',
439 GetAndroidRevisionListLink(build_branch,
440 stable_candidate,
441 new_ebuild))
442
443 git.RunGit(package_dir, ['add', new_ebuild_path])
444 if stable_candidate and not stable_candidate.IsSticky():
445 git.RunGit(package_dir, ['rm', stable_candidate.ebuild_path])
446
447 # Update ebuild manifest and git add it.
448 gen_manifest_cmd = ['ebuild', new_ebuild_path, 'manifest', '--force']
449 cros_build_lib.RunCommand(gen_manifest_cmd,
450 extra_env=None, print_cmd=True)
451 git.RunGit(package_dir, ['add', 'Manifest'])
452
453 portage_util.EBuild.CommitChange(
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900454 _GIT_COMMIT_MESSAGE % {'android_package': android_package,
David Rileyc0da9d92016-02-01 12:11:01 -0800455 'android_version': android_version},
456 package_dir)
457
458 return '%s-%s' % (new_ebuild.package, new_ebuild.version)
459
460
461def GetParser():
462 """Creates the argument parser."""
463 parser = commandline.ArgumentParser()
464 parser.add_argument('-b', '--boards')
465 parser.add_argument('--android_bucket_url',
David Riley73f00d92016-02-16 18:54:20 -0800466 default=constants.ANDROID_BUCKET_URL,
467 type='gs_path')
David Rileyc0da9d92016-02-01 12:11:01 -0800468 parser.add_argument('--android_build_branch',
Shuhei Takahashi6d02c192017-04-05 14:01:24 +0900469 required=True,
470 help='Android branch to import from. '
471 'Ex: git_mnc-dr-arc-dev')
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900472 parser.add_argument('--android_gts_build_branch',
Shuhei Takahashi6d02c192017-04-05 14:01:24 +0900473 help='Android GTS branch to copy artifacts from. '
474 'Ex: git_mnc-dev')
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900475 parser.add_argument('--android_package',
476 default=constants.ANDROID_PACKAGE_NAME)
David Riley73f00d92016-02-16 18:54:20 -0800477 parser.add_argument('--arc_bucket_url',
478 default=constants.ARC_BUCKET_URL,
479 type='gs_path')
David Rileyc0da9d92016-02-01 12:11:01 -0800480 parser.add_argument('-f', '--force_version',
481 help='Android build id to use')
482 parser.add_argument('-s', '--srcroot',
483 default=os.path.join(os.environ['HOME'], 'trunk', 'src'),
484 help='Path to the src directory')
485 parser.add_argument('-t', '--tracking_branch', default='cros/master',
486 help='Branch we are tracking changes against')
487 return parser
488
489
490def main(argv):
Hidehiko Abec9ecf262017-07-05 15:17:41 +0900491 logging.EnableBuildbotMarkers()
David Rileyc0da9d92016-02-01 12:11:01 -0800492 parser = GetParser()
493 options = parser.parse_args(argv)
494 options.Freeze()
495
496 overlay_dir = os.path.abspath(_OVERLAY_DIR % {'srcroot': options.srcroot})
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900497 android_package_dir = os.path.join(
498 overlay_dir,
499 portage_util.GetFullAndroidPortagePackageName(options.android_package))
David Rileyc0da9d92016-02-01 12:11:01 -0800500 version_to_uprev = None
David Rileyc0da9d92016-02-01 12:11:01 -0800501
502 (unstable_ebuild, stable_ebuilds) = FindAndroidCandidates(android_package_dir)
David Riley73f00d92016-02-16 18:54:20 -0800503 acls = MakeAclDict(android_package_dir)
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700504 build_targets = MakeBuildTargetDict(options.android_build_branch)
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900505 # Mirror artifacts, i.e., images and some sdk tools (e.g., adb, aapt).
506 version_to_uprev = MirrorArtifacts(options.android_bucket_url,
507 options.android_build_branch,
508 options.arc_bucket_url, acls,
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700509 build_targets,
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900510 options.force_version)
511
512 # Mirror GTS.
Hidehiko Abee8cd06c2017-05-12 23:32:19 +0900513 if options.android_gts_build_branch:
514 MirrorArtifacts(options.android_bucket_url,
515 options.android_gts_build_branch,
516 options.arc_bucket_url, acls,
517 constants.ANDROID_GTS_BUILD_TARGETS)
David Riley73f00d92016-02-16 18:54:20 -0800518
David Rileyc0da9d92016-02-01 12:11:01 -0800519 stable_candidate = portage_util.BestEBuild(stable_ebuilds)
520
521 if stable_candidate:
David Riley676f5402016-02-12 17:24:23 -0800522 logging.info('Stable candidate found %s' % stable_candidate.version)
David Rileyc0da9d92016-02-01 12:11:01 -0800523 else:
524 logging.info('No stable candidate found.')
525
526 tracking_branch = 'remotes/m/%s' % os.path.basename(options.tracking_branch)
527 existing_branch = git.GetCurrentBranch(android_package_dir)
528 work_branch = cros_mark_as_stable.GitBranch(constants.STABLE_EBUILD_BRANCH,
529 tracking_branch,
530 android_package_dir)
531 work_branch.CreateBranch()
532
533 # In the case of uprevving overlays that have patches applied to them,
534 # include the patched changes in the stabilizing branch.
535 if existing_branch:
536 git.RunGit(overlay_dir, ['rebase', existing_branch])
537
538 android_version_atom = MarkAndroidEBuildAsStable(
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900539 stable_candidate, unstable_ebuild, options.android_package,
David Riley73f00d92016-02-16 18:54:20 -0800540 version_to_uprev, android_package_dir,
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700541 options.android_build_branch, options.arc_bucket_url, build_targets)
David Rileyc0da9d92016-02-01 12:11:01 -0800542 if android_version_atom:
543 if options.boards:
544 cros_mark_as_stable.CleanStalePackages(options.srcroot,
545 options.boards.split(':'),
546 [android_version_atom])
547
548 # Explicit print to communicate to caller.
549 print('ANDROID_VERSION_ATOM=%s' % android_version_atom)