load('@lib//arch_pkg:settings.star', 'default_settings') PLATFORMS = { 'aarch64': {'os': 'linux', 'arch': 'arm64'}, 'x86_64': {'os': 'linux', 'arch': 'amd64'}, 'armv7h': {'os': 'linux', 'arch': 'arm'}, 'i686': {'os': 'linux', 'arch': '386'}, 'i386': {'os': 'linux', 'arch': '386'}, 'pentium4': {'os': 'linux', 'arch': '386'} } # For debugging purposes since Drone CLI won't print anything unless you # give it a somewhat valid pipeline def _debug_bogus(*a, **kw): print(kw, *a) return { 'kind': 'pipeline', 'type': 'docker', } def generate(config): # "Unfreeze" config so we can add defaults and pass them around _cfg = {} _cfg.update(config) config = _cfg # Retrieve architectures with special configuration special_archs = {arch: cfg for arch, cfg in config.items() if arch in PLATFORMS.keys()} # Retrieve architectures with common configuration others = config.get("all") or config.get("others") or None # Apply pipeline-specific settings on top of defaults, if any settings = {} settings.update(default_settings) settings.update(config.get('settings', {})) config['settings'] = settings # Expand common config architectures into one dict, together with the # special architectures if others: # Ensure architectues are specified when using a generic config if "arch_matrix" not in config: print("arch_matrix is required if all/others is defined") return None matrix = config["arch_matrix"] # Ensure that arch_matrix won't override a specifically-defined arch for arch in matrix: if arch in special_archs: print("arch '{}' is defined in both arch_matrix and top level config".format(arch)) return None archs = {arch: others for arch in matrix} else: archs = {} archs.update(special_archs) pipelines = [] # Generate pipelines for every arch for arch, archconfig in archs.items(): pipelines.append(generate_pipeline(config, arch, archconfig)) if len(pipelines) == 1: return pipelines[0] else: return pipelines def generate_pipeline(config, arch, archconfig): settings = config['settings'] pipeline = {} pipeline.update(settings['pipeline']) pipeline.update({ 'name': arch, 'platform': PLATFORMS[arch] }) steps = [] # Add submodules step if config.get('clone_recursive'): steps.append({ 'name': 'submodules', 'image': 'alpine/git', 'commands': ['git submodule update --recursive --remote'] }) # Add packages steps pull_set = False for pkgconfig in archconfig: stepcfg = step_git(pkgconfig) if is_git(pkgconfig) else step_aur(pkgconfig) stepcfg['image'] = settings['images']['build'].format(arch=arch) if not pull_set: # Ensure the image is pulled in the first step stepcfg['pull'] = 'always' pull_set = True steps.append(stepcfg) # Add additional steps for step in settings.get('additional_steps', []): image = settings['images'][step].format(arch=arch) step_fn = ADDITIONAL_STEPS[step] steps.append(step_fn(image, arch, settings.get(step, {}))) # Allow builds only in the master branch by default if config.get('master_only', True): for step in steps: step['when'] = {'branch': ['master']} pipeline['steps'] = steps return pipeline def is_git(pkgconfig): if type(pkgconfig) == "dict": return 'git' in pkgconfig else: return pkgconfig == "." or "/" in pkgconfig def step_aur(pkgconfig): stepcfg = {'settings': {}} if type(pkgconfig) == "string": stepcfg['name'] = pkgconfig stepcfg['settings']['aur'] = pkgconfig elif type(pkgconfig) == "dict": if 'aur' not in pkgconfig: print("{} is not a valid aur package definition".format(pkgconfig)) return None stepcfg['name'] = pkgconfig.get('name') or pkgconfig['aur'] stepcfg['settings'].update({k: v for k, v in pkgconfig.items() if k != 'name'}) else: print("{} is not a valid aur package definition".format(pkgconfig)) return None return stepcfg def _gitname(repo_path): if repo_path == ".": # Local git repo, side-by-side with the Drone config using this module return "local" else: return repo_path.split('/')[-1].replace('.git', '') def step_git(pkgconfig): stepcfg = {'settings': {}} if type(pkgconfig) == "string": stepcfg['name'] = _gitname(pkgconfig) if pkgconfig != ".": stepcfg['settings']['git'] = pkgconfig elif type(pkgconfig) == "dict": if 'git' not in pkgconfig: print("{} is not a valid git package definition".format(pkgconfig)) return None stepcfg['name'] = pkgconfig.get('name') or _gitname(pkgconfig['git']) if pkgconfig['git'] != ".": stepcfg['settings']['git'] = pkgconfig['git'] stepcfg['settings'].update({k: v for k, v in pkgconfig.items() if k not in ('git', 'name')}) else: print("{} is not a valid git package definition".format(pkgconfig)) return None def sign_step(image, arch, settings): step = { 'name': 'sign', 'image': image, 'pull': 'always', 'settings': {} } step['settings'].update(settings) step['settings'].update({ 'sign_dir': 'out' }) return step def upload_step(image, arch, settings): step = { 'name': 'upload', 'image': image, 'pull': 'always', 'settings': {} } step['settings'].update(settings) step['settings'].update({ 'source': 'out/*', 'target': '/' + arch, 'strip_prefix': True }) return step ADDITIONAL_STEPS = { 'sign': sign_step, 'upload': upload_step }