def _render(self, definition_descriptor): effective_definition = definition_descriptor.pipeline_definition # handle inheritance for override in definition_descriptor.override_definitions: effective_definition = merge_dicts(effective_definition, override) template_name = definition_descriptor.template_name() template_contents = self.template_retriever.template_contents( template_name) pipeline_name = definition_descriptor.pipeline_name pipeline_definition = RawPipelineDefinitionDescriptor( name=pipeline_name, base_definition=effective_definition.get('base_definition', {}), variants=effective_definition.get('jobs', {}), template=template_name, ) factory = DefinitionFactory( raw_definition_descriptor=pipeline_definition, cfg_set=self.cfg_set, ) pipeline_metadata = dict() pipeline_metadata['definition'] = factory.create_pipeline_definition() pipeline_metadata['name'] = pipeline_definition.name pipeline_metadata[ 'target_team'] = definition_descriptor.concourse_target_team generated_model = pipeline_metadata.get('definition') if bg := effective_definition.get('background_image'): pipeline_metadata['background_image'] = bg
def _render(self, definition_descriptor): effective_definition = definition_descriptor.pipeline_definition # handle inheritance for override in definition_descriptor.override_definitions: effective_definition = merge_dicts(effective_definition, override) template_name = definition_descriptor.template_name() template_contents = self.template_retriever.template_contents(template_name) pipeline_name = definition_descriptor.pipeline_name # support declaring jobs by either 'jobs' or 'variants' # TODO: Add deprecation message for old 'variants' syntax. jobs = effective_definition.get('jobs', {}) variants = effective_definition.get('variants', {}) if jobs and variants: raise RuntimeError( f"Both 'jobs' and 'variants' are defined in pipeline '{pipeline_name}'" ) pipeline_definition = RawPipelineDefinitionDescriptor( name=pipeline_name, base_definition=effective_definition.get('base_definition', {}), variants=jobs or variants, template=template_name, ) factory = DefinitionFactory(raw_definition_descriptor=pipeline_definition) pipeline_metadata = dict() pipeline_metadata['definition'] = factory.create_pipeline_definition() pipeline_metadata['name'] = pipeline_definition.name pipeline_metadata['target_team'] = definition_descriptor.concourse_target_team generated_model = pipeline_metadata.get('definition') # determine pipeline name (if there is main-repo, append the configured branch name) for variant in pipeline_metadata.get('definition').variants(): # hack: take the first "main_repository" we find if not variant.has_main_repository(): continue main_repo = variant.main_repository() pipeline_metadata['pipeline_name'] = '-'.join( [pipeline_definition.name, main_repo.branch()] ) break else: # fallback in case no main_repository was found pipeline_metadata['pipeline_name'] = pipeline_definition.name main_repo = None t = mako.template.Template(template_contents, lookup=self.lookup) definition_descriptor.pipeline = t.render( instance_args=generated_model, config_set=self.cfg_set, pipeline=pipeline_metadata, ) return definition_descriptor
def test_valid_validation(self): # "OK case" descriptor = DefDescriptor(name='a_name', base_definition=None, variants={'foo': 42}) DefinitionFactory(raw_definition_descriptor=descriptor) with self.assertRaises(ValueError): DefinitionFactory(raw_definition_descriptor=None)
def _render(self, definition_descriptor): effective_definition = definition_descriptor.pipeline_definition # handle inheritance for override in definition_descriptor.override_definitions: effective_definition = merge_dicts(effective_definition, override) template_name = definition_descriptor.template_name() template_contents = self.template_retriever.template_contents( template_name) pipeline_name = definition_descriptor.pipeline_name pipeline_definition = RawPipelineDefinitionDescriptor( name=pipeline_name, base_definition=effective_definition.get('base_definition', {}), jobs=effective_definition.get('jobs', {}), template=template_name, ) factory = DefinitionFactory( raw_definition_descriptor=pipeline_definition, cfg_set=self.cfg_set, ) pipeline_metadata = { 'definition': factory.create_pipeline_definition(), 'name': pipeline_definition.name, 'target_team': definition_descriptor.concourse_target_team, 'secret_cfg': definition_descriptor.secret_cfg, 'job_mapping': definition_descriptor.job_mapping, 'render_origin': self.render_origin.value, 'cc_utils_version': _cc_utils_version(), 'pipeline_definition_committish': definition_descriptor.pipeline_definition_committish, } # also pass pipeline name if this was rendered by a replication job. Will be printed # in the meta-step later if (self.render_origin is RenderOrigin.PIPELINE_REPLICATION and (pipeline_name := os.environ.get('PIPELINE_NAME'))): pipeline_metadata['replication_pipeline_name'] = pipeline_name
def test_inheritance(self): base_def = {'foo': 'bar', 123: 555} variants = {'variant_a': {'foo': 42}, 'variant_b': {'xxx': 31}} descriptor = DefDescriptor(name='x_name', base_definition=base_def, variants=variants) factory = DefinitionFactory(raw_definition_descriptor=descriptor) merged_variants = factory._create_variants_dict(descriptor) self.assertEqual(set(merged_variants.keys()), {'variant_a', 'variant_b'}) variant_a = merged_variants['variant_a'] variant_b = merged_variants['variant_b'] # variants may overwrite values self.assertEqual(variant_a, {'foo': 42, 123: 555}) # variants may add attributes self.assertEqual(variant_b, {'foo': 'bar', 123: 555, 'xxx': 31})
def test_repository_triggers_logic(self): ''' if a repository "triggers" a build, it will (apart from triggering the given build) receive a webhook configuration. By default, only the 'main' repository "triggers". Triggering can be explicitly configured using the 'trigger' attribute. Ensure that different trigger configurations for the same repository will be honoured properly for each variant. ''' base_def = { 'repo': { 'name': 'main_repo', 'branch': 'dontcare', 'path': 'foo/bar' } } variants = { 'variant2': { 'repo': { 'name': 'main_repo', 'trigger': False }, 'repos': [{ 'name': 'other_repo', 'branch': 'x_branch', 'path': 'x/path', 'trigger': True }] }, 'variant1': { 'repos': [{ 'name': 'other_repo', 'branch': 'x_branch', 'path': 'b/path' }] }, 'variant3': { 'repo': { 'name': 'main_repo', 'trigger': False } }, } descriptor = DefDescriptor(name='foo', base_definition=base_def, variants=variants) cfg_set = model.ConfigurationSet('dummy', 'dummy', raw_dict={}) cfg_set.github = unittest.mock.MagicMock( return_value=model.github.GithubConfig( name='dontcare', raw_dict={'available_protocols': ('https', )}), ) factory = DefinitionFactory( raw_definition_descriptor=descriptor, cfg_set=cfg_set, ) result = factory.create_pipeline_definition() variant = result.variant('variant1') main_repo = variant.repository('main_repo') other_repo = variant.repository('other_repo') # main_repo should "trigger" the job (and thus a webhook ought to be generated for it) self.assertTrue(main_repo.should_trigger()) # non-main repos should not "trigger" self.assertFalse(other_repo.should_trigger()) variant2 = result.variant('variant2') main_repo_v2 = variant2.repository('main_repo') other_repo_v2 = variant2.repository('other_repo') self.assertFalse(main_repo_v2.should_trigger()) self.assertTrue(other_repo_v2.should_trigger()) # ensure different trigger logic in resource_registry: # if any variant declares a repository to be triggering, this should be the result registry = result.resource_registry() main_repo_from_registry = registry.resource( main_repo.resource_identifier()) self.assertTrue(main_repo_from_registry.should_trigger())