def main(argv=sys.argv[1:]): parser = argparse.ArgumentParser(description="Generate a 'CI' script") # Positional add_argument_config_url(parser) add_argument_rosdistro_name(parser) add_argument_build_name(parser, 'ci') add_argument_os_name(parser) add_argument_os_code_name(parser) add_argument_arch(parser) add_argument_build_tool(parser) a1 = add_argument_package_selection_args(parser) a2 = add_argument_build_tool_args(parser) a3 = add_argument_build_tool_test_args(parser) add_argument_repos_file_urls(parser) add_argument_skip_cleanup(parser) add_argument_test_branch(parser) parser.add_argument( '--underlay-source-path', nargs='*', metavar='DIR_NAME', help='Path to one or more install spaces to use as an underlay') remainder_args = extract_multiple_remainders(argv, (a1, a2, a3)) args = parser.parse_args(argv) for k, v in remainder_args.items(): setattr(args, k, v) # collect all template snippets of specific types class IncludeHook(Hook): def __init__(self): Hook.__init__(self) self.scms = [] self.scripts = [] self.parameters = {} if args.skip_cleanup: self.parameters['skip_cleanup'] = 'true' if args.repos_file_urls is not None: self.parameters['repos_file_urls'] = ' '.join( args.repos_file_urls) if args.test_branch is not None: self.parameters['test_branch'] = args.test_branch if args.package_selection_args is not None: self.parameters['package_selection_args'] = ' '.join( args.package_selection_args) if args.build_tool_args is not None: self.parameters['build_tool_args'] = ' '.join( args.build_tool_args) if args.build_tool_test_args is not None: self.parameters['build_tool_test_args'] = ' '.join( args.build_tool_test_args) def beforeInclude(self, *_, **kwargs): template_path = kwargs['file'].name if template_path.endswith('/snippet/scm.xml.em'): self.scms.append( (kwargs['locals']['repo_spec'], kwargs['locals']['path'])) if template_path.endswith('/snippet/builder_shell.xml.em'): script = kwargs['locals']['script'] # reuse existing ros_buildfarm folder if it exists if 'Clone ros_buildfarm' in script: lines = script.splitlines() lines.insert(0, 'if [ ! -d "ros_buildfarm" ]; then') lines += [ 'else', 'echo "Using existing ros_buildfarm folder"', 'fi', ] script = '\n'.join(lines) if args.build_tool and ' --build-tool ' in script: script = script.replace( ' --build-tool catkin_make_isolated', ' --build-tool ' + args.build_tool) self.scripts.append(script) if template_path.endswith( '/snippet/property_parameters-definition.xml.em'): for parameter in reversed(kwargs['locals']['parameters']): name = parameter['name'] value_type = parameter['type'] if value_type in ['string', 'text']: default_value = parameter['default_value'] elif value_type == 'boolean': default_value = 'true' if parameter.get( 'default_value', False) else 'false' else: continue self.parameters.setdefault(name, default_value) hook = IncludeHook() from ros_buildfarm import templates templates.template_hooks = [hook] config = get_config_index(args.config_url) build_files = get_ci_build_files(config, args.rosdistro_name) build_file = build_files[args.ci_build_name] underlay_source_paths = [ os.path.abspath(p) for p in args.underlay_source_path or [] ] configure_ci_job(args.config_url, args.rosdistro_name, args.ci_build_name, args.os_name, args.os_code_name, args.arch, config=config, build_file=build_file, jenkins=False, views=False, underlay_source_paths=underlay_source_paths) templates.template_hooks = None ci_job_name = get_ci_job_name(args.rosdistro_name, args.os_name, args.os_code_name, args.arch, 'script') value = expand_template('ci/ci_script.sh.em', { 'ci_job_name': ci_job_name, 'scms': hook.scms, 'scripts': hook.scripts, 'build_tool': args.build_tool or build_file.build_tool, 'parameters': hook.parameters }, options={BANGPATH_OPT: False}) value = value.replace('python3 ', sys.executable + ' ') print(value)
def configure_ci_job(config_url, rosdistro_name, ci_build_name, os_name, os_code_name, arch, config=None, build_file=None, index=None, dist_file=None, jenkins=None, views=None, is_disabled=False, groovy_script=None, build_targets=None, dry_run=False, underlay_source_paths=None, trigger_timer=None): """ Configure a single Jenkins CI job. This includes the following steps: - clone the ros_buildfarm repository - write the distribution repository keys into files - invoke the ci/run_ci_job.py script """ if config is None: config = get_config_index(config_url) if build_file is None: build_files = get_ci_build_files(config, rosdistro_name) build_file = build_files[ci_build_name] # Overwrite build_file.targets if build_targets is specified if build_targets is not None: build_file.targets = build_targets if index is None: index = get_index(config.rosdistro_index_url) if dist_file is None: dist_file = get_distribution_file(index, rosdistro_name, build_file) if not dist_file: raise JobValidationError( 'No distribution file matches the build file') if os_name not in build_file.targets.keys(): raise JobValidationError("Invalid OS name '%s' " % os_name + 'choose one of the following: ' + ', '.join(sorted(build_file.targets.keys()))) if os_code_name not in build_file.targets[os_name].keys(): raise JobValidationError( "Invalid OS code name '%s' " % os_code_name + 'choose one of the following: ' + ', '.join(sorted(build_file.targets[os_name].keys()))) if arch not in build_file.targets[os_name][os_code_name]: raise JobValidationError( "Invalid architecture '%s' " % arch + 'choose one of the following: %s' % ', '.join(sorted(build_file.targets[os_name][os_code_name]))) underlay_source_jobs = [ get_ci_job_name(rosdistro_name, os_name, os_code_name, arch, underlay_job) for underlay_job in build_file.underlay_from_ci_jobs ] underlay_source_paths = (underlay_source_paths or []) + \ ['$UNDERLAY%d_JOB_SPACE' % (index + 1) for index in range(len(underlay_source_jobs))] trigger_jobs = [ get_ci_job_name(rosdistro_name, os_name, os_code_name, arch, trigger_job) for trigger_job in build_file.jenkins_job_upstream_triggers ] if jenkins is None: from ros_buildfarm.jenkins import connect jenkins = connect(config.jenkins_url) if views is None: view_name = get_ci_view_name(rosdistro_name) configure_ci_view(jenkins, view_name, dry_run=dry_run) job_name = get_ci_job_name(rosdistro_name, os_name, os_code_name, arch, ci_build_name) job_config = _get_ci_job_config(index, rosdistro_name, build_file, os_name, os_code_name, arch, build_file.repos_files, build_file.repository_names, underlay_source_jobs, underlay_source_paths, trigger_timer, trigger_jobs, is_disabled=is_disabled) # jenkinsapi.jenkins.Jenkins evaluates to false if job count is zero if isinstance(jenkins, object) and jenkins is not False: from ros_buildfarm.jenkins import configure_job configure_job(jenkins, job_name, job_config, dry_run=dry_run) return job_name, job_config
def main(argv=sys.argv[1:]): parser = argparse.ArgumentParser( description="Generate a 'CI' script") # Positional add_argument_config_url(parser) add_argument_rosdistro_name(parser) add_argument_build_name(parser, 'ci') add_argument_os_name(parser) add_argument_os_code_name(parser) add_argument_arch(parser) add_argument_build_ignore(parser) add_argument_build_tool(parser) add_argument_package_selection_args(parser) add_argument_repos_file_urls(parser) add_argument_skip_cleanup(parser) add_argument_test_branch(parser) parser.add_argument( '--underlay-source-path', nargs='*', metavar='DIR_NAME', help='Path to one or more install spaces to use as an underlay') args = parser.parse_args(argv) # collect all template snippets of specific types class IncludeHook(Hook): def __init__(self): Hook.__init__(self) self.scms = [] self.scripts = [] self.parameters = {} if args.skip_cleanup: self.parameters['skip_cleanup'] = 'true' if args.repos_file_urls is not None: self.parameters['repos_file_urls'] = ' '.join(args.repos_file_urls) if args.test_branch is not None: self.parameters['test_branch'] = args.test_branch if args.build_ignore is not None: self.parameters['build_ignore'] = ' '.join(args.build_ignore) if args.package_selection_args is not None: self.parameters['package_selection_args'] = ' '.join(args.package_selection_args) def beforeInclude(self, *_, **kwargs): template_path = kwargs['file'].name if template_path.endswith('/snippet/scm.xml.em'): self.scms.append( (kwargs['locals']['repo_spec'], kwargs['locals']['path'])) if template_path.endswith('/snippet/builder_shell.xml.em'): script = kwargs['locals']['script'] # reuse existing ros_buildfarm folder if it exists if 'Clone ros_buildfarm' in script: lines = script.splitlines() lines.insert(0, 'if [ ! -d "ros_buildfarm" ]; then') lines += [ 'else', 'echo "Using existing ros_buildfarm folder"', 'fi', ] script = '\n'.join(lines) if args.build_tool and ' --build-tool ' in script: script = script.replace( ' --build-tool catkin_make_isolated', ' --build-tool ' + args.build_tool) self.scripts.append(script) if template_path.endswith('/snippet/property_parameters-definition.xml.em'): for parameter in reversed(kwargs['locals']['parameters']): name = parameter['name'] value_type = parameter['type'] if value_type in ['string', 'text']: default_value = parameter['default_value'] elif value_type == 'boolean': default_value = 'true' if parameter.get( 'default_value', False) else 'false' else: continue self.parameters.setdefault(name, default_value) hook = IncludeHook() from ros_buildfarm import templates templates.template_hooks = [hook] config = get_config_index(args.config_url) build_files = get_ci_build_files(config, args.rosdistro_name) build_file = build_files[args.ci_build_name] underlay_source_paths = [os.path.abspath(p) for p in args.underlay_source_path or []] configure_ci_job( args.config_url, args.rosdistro_name, args.ci_build_name, args.os_name, args.os_code_name, args.arch, config=config, build_file=build_file, jenkins=False, views=False, underlay_source_paths=underlay_source_paths) templates.template_hooks = None ci_job_name = get_ci_job_name( args.rosdistro_name, args.os_name, args.os_code_name, args.arch, 'script') value = expand_template( 'ci/ci_script.sh.em', { 'ci_job_name': ci_job_name, 'scms': hook.scms, 'scripts': hook.scripts, 'build_tool': args.build_tool or build_file.build_tool, 'parameters': hook.parameters}, options={BANGPATH_OPT: False}) value = value.replace('python3 ', sys.executable + ' ') print(value)