Skip to content

Commit

Permalink
feat(stepfunctions-tasks): support overriding all properties of CodeB…
Browse files Browse the repository at this point in the history
…uild StartBuild integration (#10356)


closes #10302 

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
zxkane authored Nov 12, 2020
1 parent 025992b commit 58efbad
Show file tree
Hide file tree
Showing 6 changed files with 682 additions and 29 deletions.
61 changes: 40 additions & 21 deletions packages/@aws-cdk/aws-codebuild/lib/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -396,14 +396,11 @@ abstract class ProjectBase extends Resource implements IProject {
}
}

export interface CommonProjectProps {
/**
* A description of the project. Use the description to identify the purpose
* of the project.
*
* @default - No description.
*/
readonly description?: string;
/**
* Common override properties of the CodeBuild project
* TODO: add properties `queuedTimeoutInMinutes`, `logsConfig`
*/
interface CommonStartBuildOptions {

/**
* Filename or contents of buildspec in JSON format.
Expand All @@ -413,13 +410,6 @@ export interface CommonProjectProps {
*/
readonly buildSpec?: BuildSpec;

/**
* Service Role to assume while running the build.
*
* @default - A role will be created.
*/
readonly role?: iam.IRole;

/**
* Encryption key to use to read and write artifacts.
*
Expand All @@ -442,13 +432,11 @@ export interface CommonProjectProps {
readonly environment?: BuildEnvironment;

/**
* Indicates whether AWS CodeBuild generates a publicly accessible URL for
* your project's build badge. For more information, see Build Badges Sample
* in the AWS CodeBuild User Guide.
* Service Role to assume while running the build.
*
* @default false
* @default - A role will be created.
*/
readonly badge?: boolean;
readonly role?: iam.IRole;

/**
* The number of minutes after which AWS CodeBuild stops the build if it's
Expand All @@ -465,6 +453,28 @@ export interface CommonProjectProps {
* @default - No additional environment variables are specified.
*/
readonly environmentVariables?: { [name: string]: BuildEnvironmentVariable };
}

/**
* Common properties of the CodeBuild project
*/
export interface CommonProjectProps extends CommonStartBuildOptions {
/**
* A description of the project. Use the description to identify the purpose
* of the project.
*
* @default - No description.
*/
readonly description?: string;

/**
* Indicates whether AWS CodeBuild generates a publicly accessible URL for
* your project's build badge. For more information, see Build Badges Sample
* in the AWS CodeBuild User Guide.
*
* @default false
*/
readonly badge?: boolean;

/**
* The physical, human-readable name of the CodeBuild Project.
Expand Down Expand Up @@ -540,7 +550,10 @@ export interface CommonProjectProps {
readonly grantReportGroupPermissions?: boolean;
}

export interface ProjectProps extends CommonProjectProps {
/**
* Override properties of the CodeBuild project
*/
export interface StartBuildOptions extends CommonStartBuildOptions {
/**
* The source of the build.
* *Note*: if {@link NoSource} is given as the source,
Expand Down Expand Up @@ -577,6 +590,12 @@ export interface ProjectProps extends CommonProjectProps {
readonly secondaryArtifacts?: IArtifacts[];
}

/**
* Properties of the CodeBuild project
*/
export interface ProjectProps extends StartBuildOptions, CommonProjectProps {
}

/**
* The extra options passed to the {@link IProject.bindToCodePipeline} method.
*/
Expand Down
15 changes: 11 additions & 4 deletions packages/@aws-cdk/aws-stepfunctions-tasks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -342,11 +342,18 @@ const codebuildProject = new codebuild.Project(stack, 'Project', {
const task = new tasks.CodeBuildStartBuild(stack, 'Task', {
project: codebuildProject,
integrationPattern: sfn.IntegrationPattern.RUN_JOB,
environmentVariablesOverride: {
ZONE: {
type: codebuild.BuildEnvironmentVariableType.PLAINTEXT,
value: sfn.JsonPath.stringAt('$.envVariables.zone'),
overrides: {
environmentVariables: {
ZONE: {
type: codebuild.BuildEnvironmentVariableType.PLAINTEXT,
value: sfn.JsonPath.stringAt('$.envVariables.zone'),
},
},
source: codebuild.Source.gitHub({
branchOrRef: sfn.JsonPath.stringAt('$.commitHash'),
owner,
repo,
}),
},
});
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,26 @@ import * as cdk from '@aws-cdk/core';
import { Construct } from 'constructs';
import { integrationResourceArn, validatePatternSupported } from '../private/task-utils';

/**
* Override properties for CodeBuildStartBuild
*
*/
export interface OverrideProjectProps extends codebuild.StartBuildOptions {
/**
* Specifies if session debugging is enabled for this build.
*
* @default - the session debugging is disabled.
*/
readonly debugSessionEnabled?: boolean;

/**
* A unique, case sensitive identifier you provide to ensure the idempotency of the StartBuild request.
*
* @default - no idempotency token.
*/
readonly idempotencyToken?: string;
}

/**
* Properties for CodeBuildStartBuild
*/
Expand All @@ -13,12 +33,21 @@ export interface CodeBuildStartBuildProps extends sfn.TaskStateBaseProps {
* CodeBuild project to start
*/
readonly project: codebuild.IProject;

/**
* A set of environment variables to be used for this build only.
*
* @deprecated - use {@link OverrideProjectProps.environmentVariables} instead
* @default - the latest environment variables already defined in the build project.
*/
readonly environmentVariablesOverride?: { [name: string]: codebuild.BuildEnvironmentVariable };

/**
* Override properties of the build of CodeBuild.
*
* @default - no override properties.
*/
readonly overrides?: OverrideProjectProps;
}

/**
Expand All @@ -42,6 +71,7 @@ export class CodeBuildStartBuild extends sfn.TaskStateBase {
this.integrationPattern = props.integrationPattern ?? sfn.IntegrationPattern.REQUEST_RESPONSE;

validatePatternSupported(this.integrationPattern, CodeBuildStartBuild.SUPPORTED_INTEGRATION_PATTERNS);
this.validateOverridingParameters(props);

this.taskMetrics = {
metricPrefixSingular: 'CodeBuildProject',
Expand Down Expand Up @@ -91,13 +121,52 @@ export class CodeBuildStartBuild extends sfn.TaskStateBase {
* @internal
*/
protected _renderTask(): any {
const sourceConfig = this.props.overrides?.source?.bind(this.props.project.stack, this.props.project);
const secondarySources = this.props.overrides?.secondarySources?.map(source => source.bind(this.props.project.stack, this.props.project));
return {
Resource: integrationResourceArn('codebuild', 'startBuild', this.integrationPattern),
Parameters: sfn.FieldUtils.renderObject({
ProjectName: this.props.project.projectName,
EnvironmentVariablesOverride: this.props.environmentVariablesOverride
? this.serializeEnvVariables(this.props.environmentVariablesOverride)
: undefined,
ArtifactsOverride: this.props.overrides?.artifacts?.bind(this.props.project.stack, this.props.project).artifactsProperty,
BuildspecOverride: this.props.overrides?.buildSpec?.toBuildSpec(),
BuildStatusConfigOverride: sourceConfig?.sourceProperty.buildStatusConfig,
ComputeTypeOverride: this.props.overrides?.environment?.computeType,
DebugSessionEnabled: this.props.overrides?.debugSessionEnabled,
EncryptionKeyOverride: this.props.overrides?.encryptionKey?.keyArn,
EnvironmentTypeOverride: this.props.overrides?.environment?.buildImage?.type,
EnvironmentVariablesOverride: this.props.overrides?.environmentVariables ?
this.serializeEnvVariables(this.props.overrides?.environmentVariables!) :
(this.props.environmentVariablesOverride
? this.serializeEnvVariables(this.props.environmentVariablesOverride)
: undefined),
GitCloneDepthOverride: sourceConfig?.sourceProperty.gitCloneDepth,
GitSubmodulesConfigOverride: sourceConfig?.sourceProperty.gitSubmodulesConfig,
IdempotencyToken: this.props.overrides?.idempotencyToken,
ImageOverride: this.props.overrides?.environment?.buildImage?.imageId,
ImagePullCredentialsTypeOverride: this.props.overrides?.environment?.buildImage?.imagePullPrincipalType,
InsecureSslOverride: sourceConfig?.sourceProperty.insecureSsl,
PrivilegedModeOverride: this.props.overrides?.environment?.privileged,
RegistryCredentialOverride: this.props.overrides?.environment?.buildImage?.secretsManagerCredentials ? {
credentialProvider: 'SECRETS_MANAGER',
credential: this.props.overrides!.environment!.buildImage!.secretsManagerCredentials.secretArn,
} : undefined,
ReportBuildStatusOverride: sourceConfig?.sourceProperty.reportBuildStatus,
SecondaryArtifactsOverride: this.props.overrides?.secondaryArtifacts?.map(artifact =>
artifact.bind(this.props.project.stack, this.props.project).artifactsProperty,
),
SecondarySourcesOverride: secondarySources?.map(source => source.sourceProperty),
SecondarySourcesVersionOverride: secondarySources?.map(source => {
return {
sourceIdentifier: source.sourceProperty.sourceIdentifier,
sourceVersion: source.sourceVersion,
};
}),
ServiceRoleOverride: this.props.overrides?.role?.roleArn,
SourceAuthOverride: sourceConfig?.sourceProperty.auth,
SourceLocationOverride: sourceConfig?.sourceProperty.location,
SourceTypeOverride: this.props.overrides?.source?.type,
SourceVersion: sourceConfig?.sourceVersion,
TimeoutInMinutesOverride: this.props.overrides?.timeout?.toMinutes(),
}),
};
}
Expand All @@ -109,4 +178,17 @@ export class CodeBuildStartBuild extends sfn.TaskStateBase {
Value: environmentVariables[name].value,
}));
}

private validateOverridingParameters(props: CodeBuildStartBuildProps) {
if (props.overrides?.secondaryArtifacts && props.overrides!.secondaryArtifacts!.length > 12) {
throw new Error(`The maximum overrides that can be specified for 'secondaryArtifacts' is 12. Received: ${props.overrides!.secondaryArtifacts!.length}`);
}
if (props.overrides?.secondarySources && props.overrides!.secondarySources!.length > 12) {
throw new Error(`The maximum overrides that can be specified for 'secondarySources' is 12. Received: ${props.overrides!.secondarySources!.length}`);
}
if (props.overrides?.timeout && (props.overrides!.timeout!.toMinutes() < 5
|| props.overrides!.timeout!.toMinutes() > 480)) {
throw new Error('The value of override property "timeout" must be between 5 and 480 minutes.');
}
}
}
Loading

0 comments on commit 58efbad

Please sign in to comment.