blob: f60aeaab89cd46a82ca98a515648479a88a5430a [file] [log] [blame]
# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can
# found in the LICENSE file.
# A general-purpose recipe for uploading third-party prebuilts to CIPD.
#
# This recipe assumes that
# (1) everything needed to produce a prebuilt can be obtained from a given
# jiri checkout.
# (2) in that checkout, a JSON file of "contents" is found that describes all
# of the file i/o that the recipe should perform from the checkout to a
# staging directory. The schema is that of CONTENTS_JSON_TEST_DATA below.
# (3) also in that checkout, there is a script that takes a single positional
# argument of a directory that it is meant to populate; this directory
# will be uploaded to CIPD after script invocation. The script may assume
# that the above staging directory will be set as its CWD.
#
from recipe_engine.recipe_api import Property
DEPS = [
'fuchsia/buildbucket_util',
'fuchsia/checkout',
'fuchsia/git',
'fuchsia/jiri',
'fuchsia/upload',
'recipe_engine/buildbucket',
'recipe_engine/cipd',
'recipe_engine/context',
'recipe_engine/file',
'recipe_engine/isolated',
'recipe_engine/path',
'recipe_engine/properties',
'recipe_engine/step',
]
PROPERTIES = {
'project':
Property(kind=str, help='Jiri remote manifest project'),
'manifest':
Property(kind=str, help='Jiri manifest to use'),
'remote':
Property(kind=str, help='Remote manifest repository'),
'content_manifest':
Property(
kind=str,
help='A JSON file describing the i/o that the recipe should undertake to prepare a staging directory.',
default='contents.json',
),
'packing_script':
Property(
kind=str,
help='A script that will consume a staging directory and populate another directory to be uploaded to CIPD.',
),
'cipd_pkg_name':
Property(
kind=str,
help='pairings of the form \'<src>=<CIPD path>\'; see recipe documentation for more details',
),
}
CONTENTS_JSON_TEST_DATA = [
{
# `destination` is a directory relative to the packing directory.
'destination': 'baz',
# `files` is a list of files to move to `destination`, each relative to
# the checkout root,
'files': ['data/bar.txt', 'data/foo.json'],
},
]
def RunSteps(api, project, manifest, remote, content_manifest, packing_script,
cipd_pkg_name):
checkout_root = api.path['start_dir'].join('3p_prebuilts')
with api.step.nest('checkout'):
with api.context(infra_steps=True):
api.checkout.with_options(
path=checkout_root,
manifest=manifest,
remote=remote,
project=project,
build_input=api.buildbucket.build_input,
)
with api.context(infra_steps=True, cwd=checkout_root):
revision = api.jiri.project([project]).json.output[0]['revision']
staging_dir = api.path.mkdtemp('3p_prebuilts.staging')
with api.step.nest('gather contents'):
contents = api.file.read_json(
'read %s' % api.path.basename(content_manifest),
checkout_root.join(content_manifest),
test_data=CONTENTS_JSON_TEST_DATA,
)
for entry in contents:
rel_dest = entry['destination']
dest = staging_dir.join(rel_dest)
with api.step.nest(rel_dest):
api.file.ensure_directory('ensure %s' % rel_dest, dest)
for rel_src in entry['files']:
src = checkout_root.join(rel_src)
api.file.copy('copy %s' % rel_src, src, dest)
output_dir = api.path.mkdtemp('3p_prebuilts.output')
with api.context(cwd=staging_dir):
api.step('pack contents', [checkout_root.join(packing_script), output_dir])
with api.step.nest(cipd_pkg_name):
if api.buildbucket_util.is_tryjob:
isolated = api.isolated.isolated(output_dir)
isolated.add_dir(output_dir)
isolated.archive('isolate prebuilts')
else:
api.upload.cipd_package(
pkg_name=cipd_pkg_name,
pkg_root=output_dir,
pkg_paths=[api.upload.DirectoryPath(output_dir)],
search_tag={'git_revision': revision},
)
def GenTests(api):
properties = api.properties(
project='third_party/prebuilts',
manifest='third_party/prebuilts',
remote='https://fuchsia.googlesource.com/manifest',
packing_script='generate.sh',
cipd_pkg_name='fuchsia/third_party/foo',
)
tryjob = api.buildbucket.try_build()
ci = api.buildbucket.ci_build()
yield api.test('try') + properties + tryjob
yield api.test('ci_cipd_up_to_date') + properties + ci
yield api.test('ci_cipd_new') + properties + ci + api.step_data(
'fuchsia/third_party/foo.cipd.cipd search fuchsia/third_party/foo git_revision:%s'
% api.jiri.example_revision,
api.cipd.example_search('fuchsia/third_party/foo', []))