cdk-factory 0.15.15__tar.gz → 0.15.17__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of cdk-factory might be problematic. Click here for more details.

Files changed (158) hide show
  1. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/PKG-INFO +1 -1
  2. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/pyproject.toml +1 -1
  3. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/pipeline_stage.py +29 -5
  4. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/pipeline/pipeline_factory.py +205 -24
  5. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/ecs/ecs_service_stack.py +1 -1
  6. cdk_factory-0.15.17/src/cdk_factory/version.py +1 -0
  7. cdk_factory-0.15.15/src/cdk_factory/version.py +0 -1
  8. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/.gitignore +0 -0
  9. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/.windsurfrules +0 -0
  10. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/LICENSE +0 -0
  11. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/README.md +0 -0
  12. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/archive/README.md +0 -0
  13. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/archive/migrate_to_enhanced_ssm.py +0 -0
  14. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/examples/json-imports/README.md +0 -0
  15. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/examples/separate-api-gateway/README.md +0 -0
  16. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/examples/separate-api-gateway/api-gateway-stack.json +0 -0
  17. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/examples/separate-api-gateway/config.json +0 -0
  18. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/examples/separate-api-gateway/lambda-stack.json +0 -0
  19. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/mypy.ini +0 -0
  20. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/publish_to_pypi.py +0 -0
  21. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/publish_to_pypi.sh +0 -0
  22. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/pysetup.py +0 -0
  23. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/pysetup.sh +0 -0
  24. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/requirements.dev.txt +0 -0
  25. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/requirements.tests.txt +0 -0
  26. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/requirements.txt +0 -0
  27. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/run-checks.sh +0 -0
  28. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/run-tests-clean-venv.sh +0 -0
  29. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/run-tests.sh +0 -0
  30. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/scripts/cloudfront-cleanup.sh +0 -0
  31. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/__init__.py +0 -0
  32. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/app.py +0 -0
  33. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/builds/README.md +0 -0
  34. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/cdk.json +0 -0
  35. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/cli.py +0 -0
  36. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/commands/command_loader.py +0 -0
  37. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/base_config.py +0 -0
  38. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/cdk_config.py +0 -0
  39. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/deployment.py +0 -0
  40. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/deployment_wave.py +0 -0
  41. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/devops.py +0 -0
  42. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/enhanced_base_config.py +0 -0
  43. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/enhanced_ssm_config.py +0 -0
  44. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/management.py +0 -0
  45. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/pipeline.py +0 -0
  46. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/_resources.py +0 -0
  47. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/api_gateway.py +0 -0
  48. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/apigateway_route_config.py +0 -0
  49. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/auto_scaling.py +0 -0
  50. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/cloudfront.py +0 -0
  51. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/cloudwatch_widget.py +0 -0
  52. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/code_artifact.py +0 -0
  53. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/code_artifact_login.py +0 -0
  54. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/code_repository.py +0 -0
  55. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/cognito.py +0 -0
  56. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/docker.py +0 -0
  57. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/dynamodb.py +0 -0
  58. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/ecr.py +0 -0
  59. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/ecs_service.py +0 -0
  60. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/exisiting.py +0 -0
  61. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/lambda_edge.py +0 -0
  62. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/lambda_function.py +0 -0
  63. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/lambda_layers.py +0 -0
  64. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/lambda_triggers.py +0 -0
  65. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/load_balancer.py +0 -0
  66. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/monitoring.py +0 -0
  67. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/rds.py +0 -0
  68. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/resource_mapping.py +0 -0
  69. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/resource_naming.py +0 -0
  70. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/resource_types.py +0 -0
  71. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/route53.py +0 -0
  72. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/route53_hosted_zone.py +0 -0
  73. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/rum.py +0 -0
  74. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/s3.py +0 -0
  75. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/security_group.py +0 -0
  76. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/security_group_full_stack.py +0 -0
  77. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/sqs.py +0 -0
  78. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/resources/vpc.py +0 -0
  79. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/stack.py +0 -0
  80. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/configurations/workload.py +0 -0
  81. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/constructs/cloudfront/cloudfront_distribution_construct.py +0 -0
  82. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/constructs/ecr/ecr_construct.py +0 -0
  83. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/constructs/lambdas/lambda_function_construct.py +0 -0
  84. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/constructs/lambdas/lambda_function_docker_construct.py +0 -0
  85. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/constructs/lambdas/lambda_function_role_construct.py +0 -0
  86. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/constructs/lambdas/policies/policy_docs.py +0 -0
  87. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/constructs/lambdas/policies/policy_statements.py +0 -0
  88. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/constructs/s3_buckets/s3_bucket_construct.py +0 -0
  89. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/constructs/s3_buckets/s3_bucket_replication_destination_construct.py +0 -0
  90. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/constructs/s3_buckets/s3_bucket_replication_source_construct.py +0 -0
  91. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/constructs/sqs/policies/sqs_policies.py +0 -0
  92. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/interfaces/enhanced_ssm_parameter_mixin.py +0 -0
  93. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/interfaces/istack.py +0 -0
  94. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/interfaces/live_ssm_resolver.py +0 -0
  95. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/interfaces/ssm_parameter_mixin.py +0 -0
  96. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/lambdas/edge/ip_gate/handler.py +0 -0
  97. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/lambdas/health_handler.py +0 -0
  98. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/pipeline/path_utils.py +0 -0
  99. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/pipeline/security/policies.py +0 -0
  100. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/pipeline/security/roles.py +0 -0
  101. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/pipeline/stage.py +0 -0
  102. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack/istack.py +0 -0
  103. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack/stack_factory.py +0 -0
  104. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack/stack_module_loader.py +0 -0
  105. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack/stack_module_registry.py +0 -0
  106. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack/stack_modules.py +0 -0
  107. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/__init__.py +0 -0
  108. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/api_gateway/api_gateway_stack.py +0 -0
  109. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/auto_scaling/__init__.py +0 -0
  110. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/auto_scaling/auto_scaling_stack.py +0 -0
  111. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/aws_lambdas/lambda_stack.py +0 -0
  112. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/buckets/README.md +0 -0
  113. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/buckets/bucket_stack.py +0 -0
  114. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/cloudfront/__init__.py +0 -0
  115. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/cloudfront/cloudfront_stack.py +0 -0
  116. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/code_artifact/code_artifact_stack.py +0 -0
  117. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/cognito/cognito_stack.py +0 -0
  118. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/dynamodb/dynamodb_stack.py +0 -0
  119. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/ecr/README.md +0 -0
  120. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/ecr/ecr_stack.py +0 -0
  121. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/ecs/__init__.py +0 -0
  122. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/lambda_edge/__init__.py +0 -0
  123. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/lambda_edge/lambda_edge_stack.py +0 -0
  124. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/load_balancer/__init__.py +0 -0
  125. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/load_balancer/load_balancer_stack.py +0 -0
  126. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/monitoring/__init__.py +0 -0
  127. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/monitoring/monitoring_stack.py +0 -0
  128. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/rds/__init__.py +0 -0
  129. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/rds/rds_stack.py +0 -0
  130. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/route53/__init__.py +0 -0
  131. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/route53/route53_stack.py +0 -0
  132. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/rum/__init__.py +0 -0
  133. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/rum/rum_stack.py +0 -0
  134. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/security_group/__init__.py +0 -0
  135. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/security_group/security_group_full_stack.py +0 -0
  136. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/security_group/security_group_stack.py +0 -0
  137. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/simple_queue_service/sqs_stack.py +0 -0
  138. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/stack_base.py +0 -0
  139. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/vpc/__init__.py +0 -0
  140. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/vpc/vpc_stack.py +0 -0
  141. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stack_library/websites/static_website_stack.py +0 -0
  142. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/stages/websites/static_website_stage.py +0 -0
  143. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/templates/README.md +0 -0
  144. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/templates/app.py.template +0 -0
  145. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/templates/cdk.json.template +0 -0
  146. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/utilities/api_gateway_integration_utility.py +0 -0
  147. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/utilities/commandline_args.py +0 -0
  148. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/utilities/configuration_loader.py +0 -0
  149. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/utilities/docker_utilities.py +0 -0
  150. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/utilities/environment_services.py +0 -0
  151. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/utilities/file_operations.py +0 -0
  152. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/utilities/git_utilities.py +0 -0
  153. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/utilities/json_loading_utility.py +0 -0
  154. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/utilities/lambda_function_utilities.py +0 -0
  155. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/utilities/os_execute.py +0 -0
  156. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/utils/api_gateway_utilities.py +0 -0
  157. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/cdk_factory/workload/workload_factory.py +0 -0
  158. {cdk_factory-0.15.15 → cdk_factory-0.15.17}/src/handlers/test/handler.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cdk_factory
3
- Version: 0.15.15
3
+ Version: 0.15.17
4
4
  Summary: CDK Factory. A QuickStarter and best practices setup for CDK projects
5
5
  Author-email: Eric Wilson <eric.wilson@geekcafe.com>
6
6
  License: MIT License
@@ -33,7 +33,7 @@ markers = [
33
33
  [project]
34
34
 
35
35
  name = "cdk_factory"
36
- version = "0.15.15"
36
+ version = "0.15.17"
37
37
  authors = [
38
38
  { name="Eric Wilson", email="eric.wilson@geekcafe.com" }
39
39
  ]
@@ -117,8 +117,32 @@ class PipelineStageConfig:
117
117
  @property
118
118
  def builds(self) -> List[Dict[str, Any]]:
119
119
  """
120
- Returns the stages for this pipeline
121
- """
122
- builds = self.workload.get("builds", [])
123
-
124
- return builds
120
+ Returns the builds configured for this stage.
121
+
122
+ If the stage has a "builds" array of strings, resolve them to the
123
+ corresponding build objects defined at workload["builds"].
124
+ Otherwise, return an empty list.
125
+ """
126
+ stage_build_refs = self.dictionary.get("builds", [])
127
+ if not stage_build_refs:
128
+ return []
129
+
130
+ workload_builds: List[Dict[str, Any]] = self.workload.get("builds", [])
131
+ by_name: Dict[str, Dict[str, Any]] = {}
132
+ for b in workload_builds:
133
+ name = b.get("name") or b.get("id")
134
+ if name:
135
+ by_name[name] = b
136
+
137
+ resolved: List[Dict[str, Any]] = []
138
+ for ref in stage_build_refs:
139
+ if isinstance(ref, str):
140
+ if ref in by_name:
141
+ resolved.append(by_name[ref])
142
+ else:
143
+ raise ValueError(f"Build '{ref}' referenced by stage '{self.name}' not found in workload.builds")
144
+ elif isinstance(ref, dict):
145
+ # Allow inline build definitions at the stage level as a fallback
146
+ resolved.append(ref)
147
+
148
+ return resolved
@@ -84,6 +84,9 @@ class PipelineFactoryStack(IStack):
84
84
 
85
85
  self.deployment_waves: Dict[str, pipelines.Wave] = {}
86
86
 
87
+ # Cache created sources keyed by repo+branch to avoid duplicate node IDs
88
+ self._source_cache: Dict[str, pipelines.CodePipelineSource] = {}
89
+
87
90
  @property
88
91
  def aws_code_pipeline(self) -> pipelines.CodePipeline:
89
92
  """AWS Code Pipeline"""
@@ -207,8 +210,8 @@ class PipelineFactoryStack(IStack):
207
210
  stage_config=stage, pipeline_stage=pipeline_stage, deployment=deployment
208
211
  )
209
212
  # add the stacks to a wave or a regular
210
- pre_steps = self._get_pre_steps(stage)
211
- post_steps = self._get_post_steps(stage)
213
+ pre_steps = self._get_pre_steps(stage, deployment)
214
+ post_steps = self._get_post_steps(stage, deployment)
212
215
  wave_name = stage.wave_name
213
216
 
214
217
  # if we don't have any stacks we'll need to use the wave
@@ -237,16 +240,16 @@ class PipelineFactoryStack(IStack):
237
240
  )
238
241
 
239
242
  def _get_pre_steps(
240
- self, stage_config: PipelineStageConfig
243
+ self, stage_config: PipelineStageConfig, deployment: DeploymentConfig
241
244
  ) -> List[pipelines.ShellStep]:
242
- return self._get_steps("pre_steps", stage_config)
245
+ return self._get_steps("pre_steps", stage_config, deployment)
243
246
 
244
247
  def _get_post_steps(
245
- self, stage_config: PipelineStageConfig
248
+ self, stage_config: PipelineStageConfig, deployment: DeploymentConfig
246
249
  ) -> List[pipelines.ShellStep]:
247
- return self._get_steps("post_steps", stage_config)
250
+ return self._get_steps("post_steps", stage_config, deployment)
248
251
 
249
- def _get_steps(self, key: str, stage_config: PipelineStageConfig):
252
+ def _get_steps(self, key: str, stage_config: PipelineStageConfig, deployment: DeploymentConfig):
250
253
  """
251
254
  Gets the build steps from the config.json.
252
255
 
@@ -255,29 +258,207 @@ class PipelineFactoryStack(IStack):
255
258
  - A single multi-line string (treated as a single script block)
256
259
 
257
260
  This allows support for complex shell constructs like if blocks, loops, etc.
261
+
262
+ For builds with source/buildspec/environment, creates CodeBuildStep instead of ShellStep.
258
263
  """
259
- shell_steps: List[pipelines.ShellStep] = []
264
+ shell_steps: List[pipelines.Step] = []
265
+
266
+ # Only process builds if this stage explicitly defines them
267
+ if not stage_config.dictionary.get("builds"):
268
+ return shell_steps
260
269
 
261
270
  for build in stage_config.builds:
262
271
  if str(build.get("enabled", "true")).lower() == "true":
263
- steps = build.get(key, [])
264
- step: Dict[str, Any]
265
- for step in steps:
266
- step_id = step.get("id") or step.get("name")
267
- commands = step.get("commands", [])
268
-
269
- # Normalize commands to a list
270
- # If commands is a single string, wrap it in a list
271
- if isinstance(commands, str):
272
- commands = [commands]
273
-
274
- shell_step = pipelines.ShellStep(
275
- id=step_id,
276
- commands=commands,
277
- )
278
- shell_steps.append(shell_step)
272
+ # Check if this is a CodeBuild step (has source, buildspec, or environment)
273
+ if build.get("source") or build.get("buildspec") or build.get("environment"):
274
+ # Create CodeBuildStep for external builds
275
+ codebuild_step = self._create_codebuild_step(build, key, deployment, stage_config.name)
276
+ if codebuild_step:
277
+ shell_steps.append(codebuild_step)
278
+ else:
279
+ # Create traditional ShellStep for inline commands
280
+ steps = build.get(key, [])
281
+ step: Dict[str, Any]
282
+ for step in steps:
283
+ step_id = step.get("id") or step.get("name")
284
+ commands = step.get("commands", [])
285
+
286
+ # Normalize commands to a list
287
+ # If commands is a single string, wrap it in a list
288
+ if isinstance(commands, str):
289
+ commands = [commands]
290
+
291
+ shell_step = pipelines.ShellStep(
292
+ id=step_id,
293
+ commands=commands,
294
+ )
295
+ shell_steps.append(shell_step)
279
296
 
280
297
  return shell_steps
298
+
299
+ def _create_codebuild_step(self, build: Dict[str, Any], key: str, deployment: DeploymentConfig, stage_name: str) -> pipelines.CodeBuildStep:
300
+ """
301
+ Creates a CodeBuildStep for builds that specify source, buildspec, or environment.
302
+
303
+ Supports:
304
+ - External GitHub repositories (public and private)
305
+ - Custom buildspec files
306
+ - Environment configuration (compute type, image, privileged mode)
307
+ - Environment variables
308
+ - GitHub authentication via CodeConnections
309
+ """
310
+ build_name = build.get("name", "custom-build")
311
+
312
+ # Parse source configuration
313
+ source_config = build.get("source", {})
314
+ source_type = source_config.get("type", "GITHUB").upper()
315
+ source_location = source_config.get("location")
316
+ source_branch = source_config.get("branch", "main")
317
+
318
+ # Determine if this is the right step type (pre or post)
319
+ # Only create the step if it's supposed to run at this point
320
+ # For now, assume CodeBuild steps run as pre_steps by default
321
+ if key != "pre_steps":
322
+ return None
323
+
324
+ if not source_location:
325
+ logger.warning(f"Build '{build_name}' has no source location specified, skipping")
326
+ return None
327
+
328
+ # Parse buildspec
329
+ # For CodeBuildStep with external source, buildspec.yml is read automatically from the repo
330
+ # We only need to create a custom buildspec if using inline commands
331
+ buildspec_path = build.get("buildspec")
332
+ buildspec = None
333
+
334
+ if not buildspec_path:
335
+ # No buildspec specified - check for inline commands
336
+ commands = build.get("commands", [])
337
+ if isinstance(commands, str):
338
+ commands = [commands]
339
+ if commands:
340
+ # Create inline buildspec from commands
341
+ buildspec = codebuild.BuildSpec.from_object({
342
+ "version": "0.2",
343
+ "phases": {
344
+ "build": {
345
+ "commands": commands
346
+ }
347
+ }
348
+ })
349
+ # If buildspec_path is specified, CodeBuildStep will automatically read it from the source repo
350
+ # No need to load it explicitly
351
+
352
+ # Parse environment configuration
353
+ env_config = build.get("environment", {})
354
+ compute_type_str = env_config.get("compute_type", "BUILD_GENERAL1_SMALL")
355
+
356
+ # Map string to CDK enum
357
+ compute_type_map = {
358
+ "BUILD_GENERAL1_SMALL": codebuild.ComputeType.SMALL,
359
+ "BUILD_GENERAL1_MEDIUM": codebuild.ComputeType.MEDIUM,
360
+ "BUILD_GENERAL1_LARGE": codebuild.ComputeType.LARGE,
361
+ "BUILD_GENERAL1_2XLARGE": codebuild.ComputeType.X2_LARGE,
362
+ }
363
+ compute_type = compute_type_map.get(compute_type_str, codebuild.ComputeType.SMALL)
364
+
365
+ build_image_str = env_config.get("image", "aws/codebuild/standard:7.0")
366
+ privileged_mode = env_config.get("privileged_mode", False)
367
+
368
+ # Parse build image
369
+ if build_image_str.startswith("aws/codebuild/standard:"):
370
+ version = build_image_str.split(":")[-1]
371
+ build_image = codebuild.LinuxBuildImage.from_code_build_image_id(f"aws/codebuild/standard:{version}")
372
+ else:
373
+ build_image = codebuild.LinuxBuildImage.from_code_build_image_id(build_image_str)
374
+
375
+ # Parse environment variables
376
+ env_vars_list = build.get("environment_variables", [])
377
+ env_vars = {}
378
+ for env_var in env_vars_list:
379
+ var_name = env_var.get("name")
380
+ var_value = env_var.get("value")
381
+ var_type = env_var.get("type", "PLAINTEXT")
382
+
383
+ if var_name and var_value is not None:
384
+ if var_type == "PLAINTEXT":
385
+ env_vars[var_name] = codebuild.BuildEnvironmentVariable(value=str(var_value))
386
+ elif var_type == "PARAMETER_STORE":
387
+ env_vars[var_name] = codebuild.BuildEnvironmentVariable(
388
+ value=str(var_value),
389
+ type=codebuild.BuildEnvironmentVariableType.PARAMETER_STORE
390
+ )
391
+ elif var_type == "SECRETS_MANAGER":
392
+ env_vars[var_name] = codebuild.BuildEnvironmentVariable(
393
+ value=str(var_value),
394
+ type=codebuild.BuildEnvironmentVariableType.SECRETS_MANAGER
395
+ )
396
+
397
+ # Create build environment
398
+ build_environment = codebuild.BuildEnvironment(
399
+ build_image=build_image,
400
+ compute_type=compute_type,
401
+ privileged=privileged_mode,
402
+ environment_variables=env_vars
403
+ )
404
+
405
+ # Determine input source
406
+ if source_type == "GITHUB":
407
+ # GitHub source - supports both public and private repos
408
+ # For private repos, use the workload's code repository connection
409
+ repo_string = self._parse_github_repo_string(source_location)
410
+ cache_key = f"{repo_string}:{source_branch}"
411
+ input_source = self._source_cache.get(cache_key)
412
+ if not input_source:
413
+ input_source = pipelines.CodePipelineSource.connection(
414
+ repo_string=repo_string,
415
+ branch=source_branch,
416
+ connection_arn=self.workload.devops.code_repository.connector_arn,
417
+ action_name=f"{build_name}",
418
+ )
419
+ self._source_cache[cache_key] = input_source
420
+ else:
421
+ logger.warning(f"Unsupported source type '{source_type}' for build '{build_name}'")
422
+ return None
423
+
424
+ # Create CodeBuildStep
425
+ logger.info(f"Creating CodeBuildStep '{build_name}' with source from {source_location}")
426
+
427
+ # CodeBuildStep requires commands even when using partial_build_spec
428
+ # Provide placeholder since either:
429
+ # 1. buildspec.yml in the repo handles the build, or
430
+ # 2. inline buildspec (partial_build_spec) handles the build
431
+ commands = ["echo 'Build configuration from buildspec'"]
432
+
433
+ codebuild_step = pipelines.CodeBuildStep(
434
+ id=f"{build_name}-{stage_name}",
435
+ input=input_source,
436
+ commands=commands,
437
+ build_environment=build_environment,
438
+ partial_build_spec=buildspec,
439
+ )
440
+
441
+ return codebuild_step
442
+
443
+ def _parse_github_repo_string(self, location: str) -> str:
444
+ """
445
+ Converts GitHub URL to org/repo format.
446
+
447
+ Examples:
448
+ - https://github.com/geekcafe/myrepo.git -> geekcafe/myrepo
449
+ - https://github.com/geekcafe/myrepo -> geekcafe/myrepo
450
+ - geekcafe/myrepo -> geekcafe/myrepo
451
+ """
452
+ if location.startswith("https://github.com/"):
453
+ # Remove https://github.com/ prefix
454
+ repo_string = location.replace("https://github.com/", "")
455
+ # Remove .git suffix if present
456
+ if repo_string.endswith(".git"):
457
+ repo_string = repo_string[:-4]
458
+ return repo_string
459
+ else:
460
+ # Assume it's already in org/repo format
461
+ return location
281
462
 
282
463
  def __setup_stacks(
283
464
  self,
@@ -74,7 +74,7 @@ class EcsServiceStack(IStack, EnhancedSsmParameterMixin):
74
74
 
75
75
  # Load ECS configuration
76
76
  self.ecs_config = EcsServiceConfig(
77
- stack_config.dictionary.get("ecs_service", {})
77
+ stack_config.dictionary.get("ecs_service") or stack_config.dictionary.get("ecs", {})
78
78
  )
79
79
 
80
80
  service_name = deployment.build_resource_name(self.ecs_config.name)
@@ -0,0 +1 @@
1
+ __version__ = "0.15.17"
@@ -1 +0,0 @@
1
- __version__ = "0.15.15"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes