diff --git a/packages/@aws-cdk/pipelines/README.md b/packages/@aws-cdk/pipelines/README.md index e350d4a0862f5..3dd74c1450883 100644 --- a/packages/@aws-cdk/pipelines/README.md +++ b/packages/@aws-cdk/pipelines/README.md @@ -666,6 +666,7 @@ new pipelines.CodeBuildStep('Synth', { buildEnvironment: { computeType: codebuild.ComputeType.LARGE, }, + timeout: Duration.minutes(90), // Control Elastic Network Interface creation vpc: vpc, diff --git a/packages/@aws-cdk/pipelines/lib/codepipeline/_codebuild-factory.ts b/packages/@aws-cdk/pipelines/lib/codepipeline/_codebuild-factory.ts index 75c800aeb84c1..294a8844b81bb 100644 --- a/packages/@aws-cdk/pipelines/lib/codepipeline/_codebuild-factory.ts +++ b/packages/@aws-cdk/pipelines/lib/codepipeline/_codebuild-factory.ts @@ -137,16 +137,16 @@ export class CodeBuildFactory implements ICodePipelineActionFactory { const factory = CodeBuildFactory.fromShellStep(constructId, step, { projectName: step.projectName, role: step.role, - projectOptions: { + ...additional, + projectOptions: mergeCodeBuildOptions(additional?.projectOptions, { buildEnvironment: step.buildEnvironment, rolePolicy: step.rolePolicyStatements, securityGroups: step.securityGroups, partialBuildSpec: step.partialBuildSpec, vpc: step.vpc, subnetSelection: step.subnetSelection, - ...additional?.projectOptions, - }, - ...additional, + timeout: step.timeout, + }), }); return { @@ -279,6 +279,7 @@ export class CodeBuildFactory implements ICodePipelineActionFactory { securityGroups: projectOptions.securityGroups, buildSpec: projectBuildSpec, role: this.props.role, + timeout: projectOptions.timeout, }); if (this.props.additionalDependable) { @@ -393,6 +394,7 @@ export function mergeCodeBuildOptions(...opts: Array { }); }); +test('long duration steps are supported', () => { + // WHEN + new cdkp.CodePipeline(pipelineStack, 'Pipeline', { + synth: new cdkp.CodeBuildStep('Synth', { + commands: ['/bin/true'], + input: cdkp.CodePipelineSource.gitHub('test/test', 'main'), + additionalInputs: { + 'some/deep/directory': cdkp.CodePipelineSource.gitHub('test2/test2', 'main'), + }, + timeout: Duration.minutes(180), + }), + }); + + // THEN + Template.fromStack(pipelineStack).hasResourceProperties('AWS::CodeBuild::Project', { + TimeoutInMinutes: 180, + }); +}); + +test('timeout can be configured as part of defaults', () => { + // WHEN + new cdkp.CodePipeline(pipelineStack, 'Pipeline', { + synth: new cdkp.CodeBuildStep('Synth', { + commands: ['/bin/true'], + input: cdkp.CodePipelineSource.gitHub('test/test', 'main'), + additionalInputs: { + 'some/deep/directory': cdkp.CodePipelineSource.gitHub('test2/test2', 'main'), + }, + }), + codeBuildDefaults: { + timeout: Duration.minutes(180), + }, + }); + + // THEN + Template.fromStack(pipelineStack).hasResourceProperties('AWS::CodeBuild::Project', { + TimeoutInMinutes: 180, + }); +}); + +test('timeout from defaults can be overridden', () => { + // WHEN + new cdkp.CodePipeline(pipelineStack, 'Pipeline', { + synth: new cdkp.CodeBuildStep('Synth', { + commands: ['/bin/true'], + input: cdkp.CodePipelineSource.gitHub('test/test', 'main'), + additionalInputs: { + 'some/deep/directory': cdkp.CodePipelineSource.gitHub('test2/test2', 'main'), + }, + timeout: Duration.minutes(888), + }), + codeBuildDefaults: { + timeout: Duration.minutes(180), + }, + }); + + // THEN + Template.fromStack(pipelineStack).hasResourceProperties('AWS::CodeBuild::Project', { + TimeoutInMinutes: 888, + }); +}); + test('envFromOutputs works even with very long stage and stack names', () => { const pipeline = new ModernTestGitHubNpmPipeline(pipelineStack, 'Cdk');