blob: a16e3f4a52b2bd6cabde925447320ac2ec0a8ab4 [file] [log] [blame]
David Rileyc0da9d92016-02-01 12:11:01 -08001# Copyright 2016 The Chromium OS Authors. All rights reserved.
2# 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
7After calling, it prints outs ANDROID_VERSION_ATOM=(version atom string). A
8caller could then use this atom with emerge to build the newly uprevved version
9of Android e.g.
10
Shuhei Takahashi6d02c192017-04-05 14:01:24 +090011./cros_mark_android_as_stable \
12 --android_package=android-container \
13 --android_build_branch=git_mnc-dr-arc-dev \
14 --android_gts_build_branch=git_mnc-dev
15
David Rileyc0da9d92016-02-01 12:11:01 -080016Returns chromeos-base/android-container-2559197
17
18emerge-veyron_minnie-cheets =chromeos-base/android-container-2559197-r1
19"""
20
21from __future__ import print_function
22
23import filecmp
24import glob
25import os
Hidehiko Abe12727dd2016-05-27 23:23:45 +090026import re
David Rileyc0da9d92016-02-01 12:11:01 -080027
Aviv Keshetb7519e12016-10-04 00:50:00 -070028from chromite.lib import constants
David Rileyc0da9d92016-02-01 12:11:01 -080029from chromite.lib import commandline
30from chromite.lib import cros_build_lib
31from chromite.lib import cros_logging as logging
32from chromite.lib import git
33from chromite.lib import gs
34from chromite.lib import portage_util
35from chromite.scripts import cros_mark_as_stable
36
37
38# Dir where all the action happens.
39_OVERLAY_DIR = '%(srcroot)s/private-overlays/project-cheets-private/'
40
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +090041_GIT_COMMIT_MESSAGE = ('Marking latest for %(android_package)s ebuild '
David Rileyc0da9d92016-02-01 12:11:01 -080042 'with version %(android_version)s as stable.')
43
44# URLs that print lists of Android revisions between two build ids.
45_ANDROID_VERSION_URL = ('http://android-build-uber.corp.google.com/repo.html?'
46 'last_bid=%(old)s&bid=%(new)s&branch=%(branch)s')
47
48
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +090049def IsBuildIdValid(bucket_url, build_branch, build_id, targets):
David Rileyc0da9d92016-02-01 12:11:01 -080050 """Checks that a specific build_id is valid.
51
52 Looks for that build_id for all builds. Confirms that the subpath can
53 be found and that the zip file is present in that subdirectory.
54
55 Args:
56 bucket_url: URL of Android build gs bucket
57 build_branch: branch of Android builds
58 build_id: A string. The Android build id number to check.
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +090059 targets: Dict from build key to (targe build suffix, artifact file pattern)
60 pair.
David Rileyc0da9d92016-02-01 12:11:01 -080061
62 Returns:
63 Returns subpaths dictionary if build_id is valid.
64 None if the build_id is not valid.
65 """
66 gs_context = gs.GSContext()
67 subpaths_dict = {}
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +090068 for build, (target, _) in targets.iteritems():
David Rileyc0da9d92016-02-01 12:11:01 -080069 build_dir = '%s-%s' % (build_branch, target)
70 build_id_path = os.path.join(bucket_url, build_dir, build_id)
71
72 # Find name of subpath.
73 try:
74 subpaths = gs_context.List(build_id_path)
75 except gs.GSNoSuchKey:
76 logging.warn(
77 'Directory [%s] does not contain any subpath, ignoring it.',
78 build_id_path)
79 return None
80 if len(subpaths) > 1:
81 logging.warn(
82 'Directory [%s] contains more than one subpath, ignoring it.',
83 build_id_path)
84 return None
85
86 subpath_dir = subpaths[0].url.rstrip('/')
87 subpath_name = os.path.basename(subpath_dir)
88
89 # Look for a zipfile ending in the build_id number.
90 try:
Hidehiko Abe12727dd2016-05-27 23:23:45 +090091 gs_context.List(subpath_dir)
David Rileyc0da9d92016-02-01 12:11:01 -080092 except gs.GSNoSuchKey:
93 logging.warn(
Hidehiko Abe12727dd2016-05-27 23:23:45 +090094 'Did not find a file for build id [%s] in directory [%s].',
David Rileyc0da9d92016-02-01 12:11:01 -080095 build_id, subpath_dir)
96 return None
97
98 # Record subpath for the build.
99 subpaths_dict[build] = subpath_name
100
101 # If we got here, it means we found an appropriate build for all platforms.
102 return subpaths_dict
103
104
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900105def GetLatestBuild(bucket_url, build_branch, targets):
David Rileyc0da9d92016-02-01 12:11:01 -0800106 """Searches the gs bucket for the latest green build.
107
108 Args:
109 bucket_url: URL of Android build gs bucket
110 build_branch: branch of Android builds
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900111 targets: Dict from build key to (targe build suffix, artifact file pattern)
112 pair.
David Rileyc0da9d92016-02-01 12:11:01 -0800113
114 Returns:
115 Tuple of (latest version string, subpaths dictionary)
116 If no latest build can be found, returns None, None
117 """
118 gs_context = gs.GSContext()
119 common_build_ids = None
120 # Find builds for each target.
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900121 for target, _ in targets.itervalues():
David Rileyc0da9d92016-02-01 12:11:01 -0800122 build_dir = '-'.join((build_branch, target))
123 base_path = os.path.join(bucket_url, build_dir)
124 build_ids = []
125 for gs_result in gs_context.List(base_path):
126 # Remove trailing slashes and get the base name, which is the build_id.
127 build_id = os.path.basename(gs_result.url.rstrip('/'))
128 if not build_id.isdigit():
129 logging.warn('Directory [%s] does not look like a valid build_id.',
130 gs_result.url)
131 continue
132 build_ids.append(build_id)
133
134 # Update current list of builds.
135 if common_build_ids is None:
136 # First run, populate it with the first platform.
137 common_build_ids = set(build_ids)
138 else:
139 # Already populated, find the ones that are common.
140 common_build_ids.intersection_update(build_ids)
141
142 if common_build_ids is None:
143 logging.warn('Did not find a build_id common to all platforms.')
144 return None, None
145
146 # Otherwise, find the most recent one that is valid.
147 for build_id in sorted(common_build_ids, key=int, reverse=True):
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900148 subpaths = IsBuildIdValid(bucket_url, build_branch, build_id, targets)
David Rileyc0da9d92016-02-01 12:11:01 -0800149 if subpaths:
150 return build_id, subpaths
151
152 # If not found, no build_id is valid.
153 logging.warn('Did not find a build_id valid on all platforms.')
154 return None, None
155
156
157def FindAndroidCandidates(package_dir):
158 """Return a tuple of Android's unstable ebuild and stable ebuilds.
159
160 Args:
161 package_dir: The path to where the package ebuild is stored.
162
163 Returns:
164 Tuple [unstable_ebuild, stable_ebuilds].
165
166 Raises:
167 Exception: if no unstable ebuild exists for Android.
168 """
169 stable_ebuilds = []
170 unstable_ebuilds = []
171 for path in glob.glob(os.path.join(package_dir, '*.ebuild')):
172 ebuild = portage_util.EBuild(path)
173 if ebuild.version == '9999':
174 unstable_ebuilds.append(ebuild)
175 else:
176 stable_ebuilds.append(ebuild)
177
178 # Apply some sanity checks.
179 if not unstable_ebuilds:
180 raise Exception('Missing 9999 ebuild for %s' % package_dir)
181 if not stable_ebuilds:
182 logging.warning('Missing stable ebuild for %s' % package_dir)
183
184 return portage_util.BestEBuild(unstable_ebuilds), stable_ebuilds
185
186
Nicolas Norvezb08f54d2016-12-05 17:58:54 -0800187def _GetArcBasename(build, basename):
188 """Tweaks filenames between Android bucket and ARC++ bucket.
189
190 Android builders create build artifacts with the same name for -user and
191 -userdebug builds, which breaks the android-container ebuild (b/33072485).
192 When copying the artifacts from the Android bucket to the ARC++ bucket some
193 artifacts will be renamed from the usual pattern
194 *cheets_${ARCH}-target_files-S{VERSION}.zip to
195 cheets_${BUILD_NAME}-target_files-S{VERSION}.zip which will typically look
196 like cheets_(${LABEL})*${ARCH}_userdebug-target_files-S{VERSION}.zip.
197
198 Args:
199 build: the build being mirrored, e.g. 'X86', 'ARM', 'X86_USERDEBUG'.
200 basename: the basename of the artifact to copy.
201
202 Returns:
203 The basename of the destination.
204 """
205 if build not in constants.ARC_BUILDS_NEED_ARTIFACTS_RENAMED:
206 return basename
207 to_discard, sep, to_keep = basename.partition('-')
208 if not sep:
209 logging.error(('Build %s: Could not find separator "-" in artifact'
210 ' basename %s'), build, basename)
211 return basename
Bernie Thompson63ed5612017-08-16 12:27:34 -0700212 if 'cheets_' in to_discard:
213 return 'cheets_%s-%s' % (build.lower(), to_keep)
214 elif 'bertha_' in to_discard:
215 return 'bertha_%s-%s' % (build.lower(), to_keep)
216 logging.error('Build %s: Unexpected artifact basename %s',
217 build, basename)
218 return basename
Nicolas Norvezb08f54d2016-12-05 17:58:54 -0800219
220
David Riley73f00d92016-02-16 18:54:20 -0800221def CopyToArcBucket(android_bucket_url, build_branch, build_id, subpaths,
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900222 targets, arc_bucket_url, acls):
David Riley73f00d92016-02-16 18:54:20 -0800223 """Copies from source Android bucket to ARC++ specific bucket.
224
225 Copies each build to the ARC bucket eliminating the subpath.
226 Applies build specific ACLs for each file.
227
228 Args:
229 android_bucket_url: URL of Android build gs bucket
230 build_branch: branch of Android builds
231 build_id: A string. The Android build id number to check.
232 subpaths: Subpath dictionary for each build to copy.
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900233 targets: Dict from build key to (targe build suffix, artifact file pattern)
234 pair.
David Riley73f00d92016-02-16 18:54:20 -0800235 arc_bucket_url: URL of the target ARC build gs bucket
236 acls: ACLs dictionary for each build to copy.
237 """
238 gs_context = gs.GSContext()
239 for build, subpath in subpaths.iteritems():
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900240 target, pattern = targets[build]
David Riley73f00d92016-02-16 18:54:20 -0800241 build_dir = '%s-%s' % (build_branch, target)
242 android_dir = os.path.join(android_bucket_url, build_dir, build_id, subpath)
243 arc_dir = os.path.join(arc_bucket_url, build_dir, build_id)
244
Hidehiko Abe12727dd2016-05-27 23:23:45 +0900245 # Copy all target files from android_dir to arc_dir, setting ACLs.
246 for targetfile in gs_context.List(android_dir):
247 if re.search(pattern, targetfile.url):
248 basename = os.path.basename(targetfile.url)
Nicolas Norvezb08f54d2016-12-05 17:58:54 -0800249 arc_path = os.path.join(arc_dir, _GetArcBasename(build, basename))
David Riley73f00d92016-02-16 18:54:20 -0800250 acl = acls[build]
251 needs_copy = True
252
253 # Check a pre-existing file with the original source.
254 if gs_context.Exists(arc_path):
Hidehiko Abe12727dd2016-05-27 23:23:45 +0900255 if (gs_context.Stat(targetfile.url).hash_crc32c !=
Elijah Taylorbfc30692016-04-22 14:05:23 -0700256 gs_context.Stat(arc_path).hash_crc32c):
David Riley73f00d92016-02-16 18:54:20 -0800257 logging.warn('Removing incorrect file %s', arc_path)
258 gs_context.Remove(arc_path)
259 else:
260 logging.info('Skipping already copied file %s', arc_path)
261 needs_copy = False
262
263 # Copy if necessary, and set the ACL unconditionally.
264 # The Stat() call above doesn't verify the ACL is correct and
265 # the ChangeACL should be relatively cheap compared to the copy.
266 # This covers the following caes:
267 # - handling an interrupted copy from a previous run.
268 # - rerunning the copy in case one of the googlestorage_acl_X.txt
269 # files changes (e.g. we add a new variant which reuses a build).
270 if needs_copy:
Hidehiko Abe12727dd2016-05-27 23:23:45 +0900271 logging.info('Copying %s -> %s (acl %s)',
272 targetfile.url, arc_path, acl)
273 gs_context.Copy(targetfile.url, arc_path, version=0)
David Riley73f00d92016-02-16 18:54:20 -0800274 gs_context.ChangeACL(arc_path, acl_args_file=acl)
275
276
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900277def MirrorArtifacts(android_bucket_url, android_build_branch, arc_bucket_url,
278 acls, targets, version=None):
279 """Mirrors artifacts from Android bucket to ARC bucket.
280
281 First, this function identifies which build version should be copied,
282 if not given. Please see GetLatestBuild() and IsBuildIdValid() for details.
283
284 On build version identified, then copies target artifacts to the ARC bucket,
285 with setting ACLs.
286
287 Args:
288 android_bucket_url: URL of Android build gs bucket
289 android_build_branch: branch of Android builds
290 arc_bucket_url: URL of the target ARC build gs bucket
291 acls: ACLs dictionary for each build to copy.
292 targets: Dict from build key to (targe build suffix, artifact file pattern)
293 pair.
294 version: (optional) A string. The Android build id number to check.
295 If not passed, detect latest good build version.
296
297 Returns:
298 Mirrored version.
299 """
300 if version:
301 subpaths = IsBuildIdValid(
302 android_bucket_url, android_build_branch, version, targets)
303 if not subpaths:
304 logging.error('Requested build %s is not valid' % version)
305 else:
306 version, subpaths = GetLatestBuild(
307 android_bucket_url, android_build_branch, targets)
308
309 CopyToArcBucket(android_bucket_url, android_build_branch, version, subpaths,
310 targets, arc_bucket_url, acls)
311 return version
312
313
David Riley73f00d92016-02-16 18:54:20 -0800314def MakeAclDict(package_dir):
315 """Creates a dictionary of acl files for each build type.
316
317 Args:
318 package_dir: The path to where the package acl files are stored.
319
320 Returns:
321 Returns acls dictionary.
322 """
323 return dict(
324 (k, os.path.join(package_dir, v))
325 for k, v in constants.ARC_BUCKET_ACLS.items()
326 )
327
328
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700329def MakeBuildTargetDict(build_branch):
330 """Creates a dictionary of build targets.
331
Bernie Thompson63ed5612017-08-16 12:27:34 -0700332 Not all targets are common between branches, for example
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700333 sdk_google_cheets_x86 only exists on N.
334 This generates a dictionary listing the available build targets for a
335 specific branch.
336
337 Args:
338 build_branch: branch of Android builds.
339
340 Returns:
341 Returns build target dictionary.
342
343 Raises:
344 ValueError: if the Android build branch is invalid.
345 """
Bernie Thompson63ed5612017-08-16 12:27:34 -0700346 if build_branch == constants.ANDROID_MASTER_ARC_DEV_BUILD_BRANCH:
347 return constants.ANDROID_MASTER_ARC_DEV_BUILD_TARGETS
348 elif build_branch == constants.ANDROID_MNC_BUILD_BRANCH:
349 return constants.ANDROID_MNC_BUILD_TARGETS
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700350 elif build_branch == constants.ANDROID_NYC_BUILD_BRANCH:
Bernie Thompson63ed5612017-08-16 12:27:34 -0700351 return constants.ANDROID_NYC_BUILD_TARGETS
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700352 else:
353 raise ValueError('Unknown branch: %s' % build_branch)
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700354
355
David Rileyc0da9d92016-02-01 12:11:01 -0800356def GetAndroidRevisionListLink(build_branch, old_android, new_android):
357 """Returns a link to the list of revisions between two Android versions
358
359 Given two AndroidEBuilds, generate a link to a page that prints the
360 Android changes between those two revisions, inclusive.
361
362 Args:
363 build_branch: branch of Android builds
364 old_android: ebuild for the version to diff from
365 new_android: ebuild for the version to which to diff
366
367 Returns:
368 The desired URL.
369 """
370 return _ANDROID_VERSION_URL % {'branch': build_branch,
Hidehiko Abec9ecf262017-07-05 15:17:41 +0900371 'old': old_android.version_no_rev,
372 'new': new_android.version_no_rev}
David Rileyc0da9d92016-02-01 12:11:01 -0800373
374
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900375def MarkAndroidEBuildAsStable(stable_candidate, unstable_ebuild,
376 android_package, android_version, package_dir,
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700377 build_branch, arc_bucket_url, build_targets):
David Rileyc0da9d92016-02-01 12:11:01 -0800378 r"""Uprevs the Android ebuild.
379
380 This is the main function that uprevs from a stable candidate
381 to its new version.
382
383 Args:
384 stable_candidate: ebuild that corresponds to the stable ebuild we are
385 revving from. If None, builds the a new ebuild given the version
386 with revision set to 1.
387 unstable_ebuild: ebuild corresponding to the unstable ebuild for Android.
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900388 android_package: android package name.
David Rileyc0da9d92016-02-01 12:11:01 -0800389 android_version: The \d+ build id of Android.
David Rileyc0da9d92016-02-01 12:11:01 -0800390 package_dir: Path to the android-container package dir.
David Riley73f00d92016-02-16 18:54:20 -0800391 build_branch: branch of Android builds.
392 arc_bucket_url: URL of the target ARC build gs bucket.
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700393 build_targets: build targets for this particular Android branch.
David Rileyc0da9d92016-02-01 12:11:01 -0800394
395 Returns:
396 Full portage version atom (including rc's, etc) that was revved.
397 """
398 def IsTheNewEBuildRedundant(new_ebuild, stable_ebuild):
399 """Returns True if the new ebuild is redundant.
400
401 This is True if there if the current stable ebuild is the exact same copy
402 of the new one.
403 """
404 if not stable_ebuild:
405 return False
406
David Riley676f5402016-02-12 17:24:23 -0800407 if stable_candidate.version_no_rev == new_ebuild.version_no_rev:
David Rileyc0da9d92016-02-01 12:11:01 -0800408 return filecmp.cmp(
409 new_ebuild.ebuild_path, stable_ebuild.ebuild_path, shallow=False)
410
411 # Case where we have the last stable candidate with same version just rev.
David Riley676f5402016-02-12 17:24:23 -0800412 if stable_candidate and stable_candidate.version_no_rev == android_version:
David Rileyc0da9d92016-02-01 12:11:01 -0800413 new_ebuild_path = '%s-r%d.ebuild' % (
414 stable_candidate.ebuild_path_no_revision,
415 stable_candidate.current_revision + 1)
416 else:
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900417 pf = '%s-%s-r1' % (android_package, android_version)
David Rileyc0da9d92016-02-01 12:11:01 -0800418 new_ebuild_path = os.path.join(package_dir, '%s.ebuild' % pf)
419
David Riley73f00d92016-02-16 18:54:20 -0800420 variables = {'BASE_URL': arc_bucket_url}
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700421 for build, (target, _) in build_targets.iteritems():
David Riley73f00d92016-02-16 18:54:20 -0800422 variables[build + '_TARGET'] = '%s-%s' % (build_branch, target)
David Rileyc0da9d92016-02-01 12:11:01 -0800423
424 portage_util.EBuild.MarkAsStable(
425 unstable_ebuild.ebuild_path, new_ebuild_path,
426 variables, make_stable=True)
427 new_ebuild = portage_util.EBuild(new_ebuild_path)
428
429 # Determine whether this is ebuild is redundant.
430 if IsTheNewEBuildRedundant(new_ebuild, stable_candidate):
431 msg = 'Previous ebuild with same version found and ebuild is redundant.'
432 logging.info(msg)
433 os.unlink(new_ebuild_path)
434 return None
435
436 if stable_candidate:
437 logging.PrintBuildbotLink('Android revisions',
438 GetAndroidRevisionListLink(build_branch,
439 stable_candidate,
440 new_ebuild))
441
442 git.RunGit(package_dir, ['add', new_ebuild_path])
443 if stable_candidate and not stable_candidate.IsSticky():
444 git.RunGit(package_dir, ['rm', stable_candidate.ebuild_path])
445
446 # Update ebuild manifest and git add it.
447 gen_manifest_cmd = ['ebuild', new_ebuild_path, 'manifest', '--force']
448 cros_build_lib.RunCommand(gen_manifest_cmd,
449 extra_env=None, print_cmd=True)
450 git.RunGit(package_dir, ['add', 'Manifest'])
451
452 portage_util.EBuild.CommitChange(
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900453 _GIT_COMMIT_MESSAGE % {'android_package': android_package,
David Rileyc0da9d92016-02-01 12:11:01 -0800454 'android_version': android_version},
455 package_dir)
456
457 return '%s-%s' % (new_ebuild.package, new_ebuild.version)
458
459
460def GetParser():
461 """Creates the argument parser."""
462 parser = commandline.ArgumentParser()
463 parser.add_argument('-b', '--boards')
464 parser.add_argument('--android_bucket_url',
David Riley73f00d92016-02-16 18:54:20 -0800465 default=constants.ANDROID_BUCKET_URL,
466 type='gs_path')
David Rileyc0da9d92016-02-01 12:11:01 -0800467 parser.add_argument('--android_build_branch',
Shuhei Takahashi6d02c192017-04-05 14:01:24 +0900468 required=True,
469 help='Android branch to import from. '
470 'Ex: git_mnc-dr-arc-dev')
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900471 parser.add_argument('--android_gts_build_branch',
Shuhei Takahashi6d02c192017-04-05 14:01:24 +0900472 help='Android GTS branch to copy artifacts from. '
473 'Ex: git_mnc-dev')
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900474 parser.add_argument('--android_package',
475 default=constants.ANDROID_PACKAGE_NAME)
David Riley73f00d92016-02-16 18:54:20 -0800476 parser.add_argument('--arc_bucket_url',
477 default=constants.ARC_BUCKET_URL,
478 type='gs_path')
David Rileyc0da9d92016-02-01 12:11:01 -0800479 parser.add_argument('-f', '--force_version',
480 help='Android build id to use')
481 parser.add_argument('-s', '--srcroot',
482 default=os.path.join(os.environ['HOME'], 'trunk', 'src'),
483 help='Path to the src directory')
484 parser.add_argument('-t', '--tracking_branch', default='cros/master',
485 help='Branch we are tracking changes against')
486 return parser
487
488
489def main(argv):
Hidehiko Abec9ecf262017-07-05 15:17:41 +0900490 logging.EnableBuildbotMarkers()
David Rileyc0da9d92016-02-01 12:11:01 -0800491 parser = GetParser()
492 options = parser.parse_args(argv)
493 options.Freeze()
494
495 overlay_dir = os.path.abspath(_OVERLAY_DIR % {'srcroot': options.srcroot})
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900496 android_package_dir = os.path.join(
497 overlay_dir,
498 portage_util.GetFullAndroidPortagePackageName(options.android_package))
David Rileyc0da9d92016-02-01 12:11:01 -0800499 version_to_uprev = None
David Rileyc0da9d92016-02-01 12:11:01 -0800500
501 (unstable_ebuild, stable_ebuilds) = FindAndroidCandidates(android_package_dir)
David Riley73f00d92016-02-16 18:54:20 -0800502 acls = MakeAclDict(android_package_dir)
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700503 build_targets = MakeBuildTargetDict(options.android_build_branch)
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900504 # Mirror artifacts, i.e., images and some sdk tools (e.g., adb, aapt).
505 version_to_uprev = MirrorArtifacts(options.android_bucket_url,
506 options.android_build_branch,
507 options.arc_bucket_url, acls,
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700508 build_targets,
Hidehiko Abe1ebc25d2016-07-28 02:24:37 +0900509 options.force_version)
510
511 # Mirror GTS.
Hidehiko Abee8cd06c2017-05-12 23:32:19 +0900512 if options.android_gts_build_branch:
513 MirrorArtifacts(options.android_bucket_url,
514 options.android_gts_build_branch,
515 options.arc_bucket_url, acls,
516 constants.ANDROID_GTS_BUILD_TARGETS)
David Riley73f00d92016-02-16 18:54:20 -0800517
David Rileyc0da9d92016-02-01 12:11:01 -0800518 stable_candidate = portage_util.BestEBuild(stable_ebuilds)
519
520 if stable_candidate:
David Riley676f5402016-02-12 17:24:23 -0800521 logging.info('Stable candidate found %s' % stable_candidate.version)
David Rileyc0da9d92016-02-01 12:11:01 -0800522 else:
523 logging.info('No stable candidate found.')
524
525 tracking_branch = 'remotes/m/%s' % os.path.basename(options.tracking_branch)
526 existing_branch = git.GetCurrentBranch(android_package_dir)
527 work_branch = cros_mark_as_stable.GitBranch(constants.STABLE_EBUILD_BRANCH,
528 tracking_branch,
529 android_package_dir)
530 work_branch.CreateBranch()
531
532 # In the case of uprevving overlays that have patches applied to them,
533 # include the patched changes in the stabilizing branch.
534 if existing_branch:
535 git.RunGit(overlay_dir, ['rebase', existing_branch])
536
537 android_version_atom = MarkAndroidEBuildAsStable(
Hidehiko Abe4fd94ae2017-01-24 18:59:55 +0900538 stable_candidate, unstable_ebuild, options.android_package,
David Riley73f00d92016-02-16 18:54:20 -0800539 version_to_uprev, android_package_dir,
Nicolas Norvez4bd854f2017-05-23 10:04:45 -0700540 options.android_build_branch, options.arc_bucket_url, build_targets)
David Rileyc0da9d92016-02-01 12:11:01 -0800541 if android_version_atom:
542 if options.boards:
543 cros_mark_as_stable.CleanStalePackages(options.srcroot,
544 options.boards.split(':'),
545 [android_version_atom])
546
547 # Explicit print to communicate to caller.
548 print('ANDROID_VERSION_ATOM=%s' % android_version_atom)