blob: 5fa1aabac8cace6368b09cf7fe7425e49f4dc3c8 [file] [log] [blame]
# Copyright 2018 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Recipe for building and publishing CIPD prebuilts"""
from recipe_engine.config import Enum, List
from recipe_engine.recipe_api import Property
DEPS = [
'fuchsia/build',
'fuchsia/buildbucket_util',
'fuchsia/checkout',
'fuchsia/fuchsia',
'fuchsia/jiri',
'fuchsia/upload',
'recipe_engine/buildbucket',
'recipe_engine/cipd',
'recipe_engine/context',
'recipe_engine/json',
'recipe_engine/path',
'recipe_engine/properties',
'recipe_engine/step',
]
TARGETS = ['arm64', 'x64']
PROPERTIES = {
'cipd_pkg_prefix':
Property(
kind=str,
help='The CIPD prefix where the tool binaries should be uploaded',
default=None),
'cipd_pkg_name':
Property(
kind=str,
help='The exact CIPD path where the tool binaries should be uploaded (overrides cipd_pkg_prefix)',
default=None),
'manifest':
Property(kind=str, help='Jiri manifest to use'),
'ninja_targets':
Property(
kind=List(basestring),
help='Extra target args to pass to ninja',
default=[]),
'packages':
Property(kind=List(basestring), help='Packages to build', default=[]),
'product':
Property(kind=str, help='Product to build', default=None),
'board':
Property(kind=str, help='Board to build', default=None),
'target':
Property(kind=Enum(*TARGETS), help='Target to build'),
'remote':
Property(kind=str, help='Remote manifest repository'),
}
def get_bin_path_components(api, build_dir, ninja_target):
"""Returns a binary's path based on its ninja target.
Args:
api: The RecipeApi object
build_dir: The Fuchsia build output directory
ninja_target: A specific Ninja target that was built
Returns:
bin_dir: The absolute path to the parent directory of bin_name.
bin_name: The name of the tool binary
"""
if ninja_target.endswith('/'):
# This shouldn't happen and would be considered an user error
# Just in case, sanitize ninja_target for api.path.split()
# to prevent returning empty string as target_name
ninja_target = ninja_target[:-1]
# ninja_target can be expressed in two formats
# 1) path to binary (e.g. "tools/json_validator")
# 2) path to ninja target (e.g. "tools:validator.zip")
# The following logic supports both of these formats
target_dir, target_name = api.path.split(ninja_target)
bin_dir = build_dir if ':' in ninja_target else build_dir.join(target_dir)
bin_name = target_name.split(':')[-1]
return bin_dir, bin_name
def RunSteps(api, cipd_pkg_prefix, cipd_pkg_name, manifest, target,
ninja_targets, packages, product, board, remote):
with api.context(infra_steps=True):
assert manifest
assert remote
build = api.buildbucket.build
checkout = api.checkout.fuchsia_with_options(
path=api.path['start_dir'],
manifest=manifest,
remote=remote,
build=build)
revision = str(build.input.gitiles_commit.id)
assert revision
build = api.build.with_options(
build_dir=api.path['start_dir'].join('out'),
checkout=checkout,
target=target,
build_type='release',
packages=packages,
board=board,
product=product,
ninja_targets=ninja_targets,
build_images=False,
)
if not api.buildbucket_util.is_tryjob:
platform = '${platform}'
for ninja_target in ninja_targets:
bin_dir, bin_name = get_bin_path_components(api, build.fuchsia_build_dir,
ninja_target)
api.upload.cipd_package(
cipd_pkg_name or '%s/%s/%s' % (cipd_pkg_prefix, bin_name, platform),
bin_dir, [api.upload.FilePath(bin_dir.join(bin_name))],
{'git_revision': revision},
repository=remote,
install_mode=None)
def GenTests(api):
revision = api.jiri.example_revision
ci_build = api.buildbucket.ci_build(
git_repo='https://fuchsia.googlesource.com/build',
revision=revision,
)
yield api.test('default') + ci_build + api.properties(
cipd_pkg_prefix='fuchsia/tools',
manifest='manifest/build',
ninja_targets=['tools/json_validator'],
target='x64',
packages=['//build/packages:json_validator'],
project='build',
remote='https://fuchsia.googlesource.com/build',
) + api.step_data(
# Mock api.cipd.search(cipd_pkg_name, 'git_revision:' + revision)
# by expanding the internal step name and providing a result for the step
'cipd.cipd search fuchsia/tools/json_validator/${platform} git_revision:%s'
% revision,
api.json.output({'result': []}),
)
yield api.test(
'gn_target_with_trailing_fwd_slash'
) + ci_build + api.properties(
cipd_pkg_prefix='fuchsia/tools',
manifest='manifest/build',
ninja_targets=['tools/json_validator/'],
target='x64',
packages=['//build/packages:json_validator'],
project='build',
remote='https://fuchsia.googlesource.com/build',
) + api.step_data(
# Mock api.cipd.search(cipd_pkg_name, 'git_revision:' + revision)
# by expanding the internal step name and providing a result for the step
'cipd.cipd search fuchsia/tools/json_validator/${platform} git_revision:%s'
% revision,
api.json.output({'result': []}),
)
yield api.test('cipd_has_revision') + ci_build + api.properties(
cipd_pkg_prefix='fuchsia/tools',
manifest='manifest/build',
ninja_targets=['tools/json_validator'],
target='x64',
packages=['//build/packages:json_validator'],
project='build',
remote='https://fuchsia.googlesource.com/build',
) + api.step_data(
'cipd.cipd search fuchsia/tools/json_validator/${platform} git_revision:%s'
% revision,
api.cipd.example_search(
'fuchsia/tools/json_validator/${platform}:%s' % revision),
)
yield api.test('no_revision') + ci_build + api.properties(
cipd_pkg_prefix='fuchsia/tools',
manifest='manifest/build',
ninja_targets=['tools/json_validator'],
target='x64',
packages=['//build/packages:json_validator'],
project='build',
remote='https://fuchsia.googlesource.com/build',
)