diff --git a/docs/providers-guide.md b/docs/providers-guide.md index 2ba6210b4..9df7e21e8 100644 --- a/docs/providers-guide.md +++ b/docs/providers-guide.md @@ -87,6 +87,10 @@ Provider type: `codecommit`. > > By default, it will trigger on changes using the event triggered by > CodeCommit when an update to the repository took place. +- *output_artifact_format* - *(String)* default: `CODE_ZIP` + > The output artifact format. Values can be either CODEBUILD_CLONE_REF or CODE_ZIP. If unspecified, the default is CODE_ZIP. + > If you are using CODEBUILD_CLONE_REF, you need to ensure that the IAM role passed in via the *role* property has the CodeCommit:GitPull permission. + > NB: The CODEBUILD_CLONE_REF value can only be used by CodeBuild downstream actions. ### GitHub diff --git a/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/cdk/cdk_constructs/adf_codepipeline.py b/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/cdk/cdk_constructs/adf_codepipeline.py index 549ebe943..cad7a847a 100644 --- a/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/cdk/cdk_constructs/adf_codepipeline.py +++ b/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/cdk/cdk_constructs/adf_codepipeline.py @@ -264,7 +264,7 @@ def _generate_configuration(self): #pylint: disable=R0912, R0911, R0915 'deployment_group_name') } if self.provider == "CodeCommit": - return { + props = { "BranchName": self.map_params['default_providers']['source'].get('properties', {}).get('branch', 'master'), "RepositoryName": self.map_params['default_providers']['source'].get('properties', {}).get('repository', {}) or self.map_params['name'], "PollForSourceChanges": ( @@ -272,6 +272,10 @@ def _generate_configuration(self): #pylint: disable=R0912, R0911, R0915 and self.map_params['default_providers']['source'].get('properties', {}).get('poll_for_changes', False) ) } + output_artifact_format = self.map_params['default_providers']['source'].get('properties', {}).get('output_artifact_format', None) + if output_artifact_format: + props["OutputArtifactFormat"] = output_artifact_format + return props raise Exception("{0} is not a valid provider".format(self.provider)) def _generate_codepipeline_access_role(self): # pylint: disable=R0911 diff --git a/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/cdk/cdk_stacks/tests/test_pipeline_creation.py b/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/cdk/cdk_stacks/tests/test_pipeline_creation.py index c1c421f9a..23a743ff9 100644 --- a/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/cdk/cdk_stacks/tests/test_pipeline_creation.py +++ b/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/cdk/cdk_stacks/tests/test_pipeline_creation.py @@ -139,8 +139,62 @@ def test_pipeline_creation_outputs_as_expected_when_source_is_codecommit_and_bui assert build_stage_action['ActionTypeId']['Owner'] == "AWS" assert build_stage_action['ActionTypeId']['Provider'] == "CodeBuild" + assert "OutputArtifactFormat" not in source_stage_action['Configuration'] + + assert len(build_stage['Actions']) == 1 + + +def test_pipeline_creation_outputs_as_expected_when_source_is_codecommit_with_codebuild_clone_ref_and_build_is_codebuild(): + region_name = "eu-central-1" + acount_id = "123456789012" + + stack_input = { + "input": {"params": {}, "default_providers": {}, "regions": {}}, + "ssm_params": {"fake-region": {}}, + } + + stack_input["input"]["name"] = "test-stack" + + stack_input["input"]["default_providers"]["source"] = { + "provider": "codecommit", + "properties": {"account_id": "123456789012", "output_artifact_format": "CODEBUILD_CLONE_REF"}, + } + stack_input["input"]["default_providers"]["build"] = { + "provider": "codebuild", + "properties": {"account_id": "123456789012"}, + } + + stack_input["ssm_params"][region_name] = { + "modules": "fake-bucket-name", + "kms": f"arn:aws:kms:{region_name}:{acount_id}:key/my-unique-kms-key-id", + } + app = core.App() + PipelineStack(app, stack_input) + + cloud_assembly = app.synth() + resources = {k[0:-8]: v for k, v in cloud_assembly.stacks[0].template['Resources'].items()} + code_pipeline = resources['codepipeline'] + assert code_pipeline['Type'] == "AWS::CodePipeline::Pipeline" + assert len(code_pipeline["Properties"]["Stages"]) == 2 + + source_stage = code_pipeline['Properties']["Stages"][0] + assert len(source_stage['Actions']) == 1 + + source_stage_action = source_stage['Actions'][0] + assert source_stage_action['ActionTypeId']['Category'] == "Source" + assert source_stage_action['ActionTypeId']['Owner'] == "AWS" + assert source_stage_action['ActionTypeId']['Provider'] == "CodeCommit" + assert source_stage_action['Configuration']['OutputArtifactFormat'] == "CODEBUILD_CLONE_REF" + + build_stage = code_pipeline['Properties']["Stages"][1] + build_stage_action = build_stage['Actions'][0] + assert build_stage_action['ActionTypeId']['Category'] == "Build" + assert build_stage_action['ActionTypeId']['Owner'] == "AWS" + assert build_stage_action['ActionTypeId']['Provider'] == "CodeBuild" + assert len(build_stage['Actions']) == 1 + def test_pipeline_creation_outputs_as_expected_when_notification_endpoint_is_chatbot(): region_name = "eu-central-1" acount_id = "123456789012" diff --git a/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/schema_validation.py b/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/schema_validation.py index e62450468..2dabcbb8b 100644 --- a/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/schema_validation.py +++ b/src/lambda_codebase/initial_commit/bootstrap_repository/adf-build/shared/schema_validation.py @@ -56,6 +56,7 @@ Optional("owner"): str, Optional("role"): str, Optional("trigger_on_changes"): bool, + Optional("output_artifact_format", default=None): Or("CODEBUILD_CLONE_REF", "CODE_ZIP", None) } CODECOMMIT_SOURCE = { "provider": 'codecommit',