| # 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', [])) |