blob: 1dfa7edb864e7a5a3071536a2b476f51bfe1e159 [file] [log] [blame]
# Copyright 2020 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Build a GN target and upload to CIPD."""
from __future__ import annotations
from typing import TYPE_CHECKING
from PB.recipes.pigweed.target_to_cipd import InputProperties
if TYPE_CHECKING: # pragma: no cover
from typing import Generator
from recipe_engine import recipe_test_api
DEPS = [
'fuchsia/buildbucket_util',
'pigweed/build',
'pigweed/checkout',
'pigweed/cipd_upload',
'pigweed/environment',
'pigweed/pw_presubmit',
'recipe_engine/buildbucket',
'recipe_engine/file',
'recipe_engine/path',
'recipe_engine/properties',
'recipe_engine/scheduler',
'recipe_engine/step',
]
PROPERTIES = InputProperties
def RunSteps(api, props):
checkout = api.checkout(props.checkout_options)
env = api.environment.init(checkout, props.environment_options)
with env():
if props.artifacts:
build = api.build.create(checkout.root, props.build_options)
api.build(build)
export_dir = build.root / props.pw_presubmit_options.export_dir_name
else:
presubmit = api.pw_presubmit.init(
checkout, props.pw_presubmit_options
)
# Presubmit steps from this recipe only make sense if there's only
# one, so complain if there's more than one.
assert len(presubmit.steps) == 1
# If using steps we use the entirety of export_dir_name instead of
# artifact globs.
assert not props.artifacts
# OrderedDict.values() is not subscriptable, so iterate over the
# single value instead of using steps[0].
for step in presubmit.steps:
assert step.export_dir
log_dir = api.path.start_dir / 'logs'
api.pw_presubmit.run(presubmit, step, log_dir=log_dir)
build_dir = step.dir
export_dir = step.export_dir
break # Not required but makes flow clearer at a glance.
pkg_dir = api.path.start_dir / 'cipd-package'
if props.artifacts:
api.file.ensure_directory('mkdir cipd-package', pkg_dir)
for glob in props.artifacts:
with api.step.nest(glob):
sources = api.file.glob_paths(
'glob', build.root, glob, test_data=(glob,)
)
if not sources: # pragma: no cover
api.file.listdir('ls build', build.root, recursive=True)
raise api.step.StepFailure(f'no matches for {glob}')
for source in sources:
with api.step.nest('source') as pres:
pres.step_summary_text = '\n'.join(
(str(source), str(build.root))
)
relpath = api.path.relpath(source, build.root)
for replacement in props.replacements:
relpath = relpath.replace(
replacement.old, replacement.new
)
dest = pkg_dir / relpath
pres.step_summary_text += f'\n{dest}'
dirname = api.path.dirname(dest)
api.file.ensure_directory(f'mkdir {dirname}', dirname)
api.file.copy(f'copy {source} {dest}', source, dest)
else:
if api.path.isdir(export_dir):
api.file.copytree('copy', export_dir, pkg_dir)
if checkout.options.use_repo:
api.file.write_text(
'write manifest',
pkg_dir / 'manifest.xml',
checkout.manifest_snapshot(),
)
files = api.file.listdir('ls package-dir', pkg_dir, recursive=True)
if not files: # pragma: no cover
raise api.step.StepFailure('no files in package-dir')
if not props.dry_run and not api.buildbucket_util.is_tryjob:
assert checkout.changes
change = checkout.changes[0]
search_tag = {'git_revision': change.ref}
api.cipd_upload(
cipd_path=props.cipd_path,
package_root=pkg_dir,
search_tag=search_tag,
repository=checkout.options.remote,
add_platform=props.add_cipd_platform,
)
if props.roller_name:
api.scheduler.emit_trigger(
api.scheduler.GitilesTrigger(
change.remote,
f'refs/heads/{change.branch}',
change.ref,
),
api.buildbucket.build.builder.project,
(props.roller_name,),
f'trigger {props.roller_name}',
)
def GenTests(api) -> Generator[recipe_test_api.TestData, None, None]:
def properties(**kwargs):
kwargs.setdefault('cipd_path', 'pigweed/cipd/path')
kwargs.setdefault('dry_run', False)
kwargs.setdefault('roller_name', 'ROLL')
props = InputProperties(**kwargs)
return api.properties(props)
yield api.test(
'success',
properties(
artifacts=['foo/bar/baz'],
replacements=[{'old': '/bar/', 'new': '/replacement/'}],
checkout_options=api.checkout.repo_options(),
build_options=api.build.options(ninja_targets=['foo', 'bar']),
),
api.checkout.ci_test_data(api.checkout.manifest_repo),
api.checkout.manifest_test_data(name='pigweed'),
api.step_data('ls package-dir', api.file.listdir(('foo', 'bar'))),
)
yield api.test(
'pw-presubmit',
properties(
checkout_options=api.checkout.git_options(),
pw_presubmit_options=api.pw_presubmit.options(step=['step']),
),
api.step_data('ls package-dir', api.file.listdir(('foo', 'bar'))),
)