diff --git a/packages/@aws-cdk/aws-cloudformation/lib/pipeline-actions.ts b/packages/@aws-cdk/aws-cloudformation/lib/pipeline-actions.ts index fd0e445debf37..678d12bfc463c 100644 --- a/packages/@aws-cdk/aws-cloudformation/lib/pipeline-actions.ts +++ b/packages/@aws-cdk/aws-cloudformation/lib/pipeline-actions.ts @@ -38,13 +38,13 @@ export interface PipelineCloudFormationActionProps extends codepipeline.CommonAc /** * Base class for Actions that execute CloudFormation */ -export abstract class PipelineCloudFormationAction extends codepipeline.DeployAction { +export abstract class PipelineCloudFormationAction extends codepipeline.Action { /** * Output artifact containing the CloudFormation call response * * Only present if configured by passing `outputFileName`. */ - public artifact?: codepipeline.Artifact; + public outputArtifact?: codepipeline.Artifact; constructor(parent: cdk.Construct, id: string, props: PipelineCloudFormationActionProps, configuration?: any) { super(parent, id, { @@ -57,6 +57,7 @@ export abstract class PipelineCloudFormationAction extends codepipeline.DeployAc maxOutputs: 1, }, provider: 'CloudFormation', + category: codepipeline.ActionCategory.Deploy, configuration: { StackName: props.stackName, OutputFileName: props.outputFileName, @@ -65,7 +66,7 @@ export abstract class PipelineCloudFormationAction extends codepipeline.DeployAc }); if (props.outputFileName) { - this.artifact = this.addOutputArtifact(props.outputArtifactName || + this.outputArtifact = this.addOutputArtifact(props.outputArtifactName || (props.stage.name + this.id + 'Artifact')); } } diff --git a/packages/@aws-cdk/aws-cloudformation/test/test.pipeline-actions.ts b/packages/@aws-cdk/aws-cloudformation/test/test.pipeline-actions.ts index 24b8044c4e362..4e0a81b614c57 100644 --- a/packages/@aws-cdk/aws-cloudformation/test/test.pipeline-actions.ts +++ b/packages/@aws-cdk/aws-cloudformation/test/test.pipeline-actions.ts @@ -32,7 +32,7 @@ export = nodeunit.testCase({ _assertPermissionGranted(test, pipelineRole.statements, 'cloudformation:CreateChangeSet', stackArn, changeSetCondition); _assertPermissionGranted(test, pipelineRole.statements, 'cloudformation:DeleteChangeSet', stackArn, changeSetCondition); - test.deepEqual(action.inputArtifacts, [artifact], + test.deepEqual(action._inputArtifacts, [artifact], 'The inputArtifact was correctly registered'); _assertActionMatches(test, stage.actions, 'AWS', 'CloudFormation', 'Deploy', { @@ -145,10 +145,11 @@ function _isOrContains(entity: string | string[], value: string): boolean { return false; } -class StageDouble implements cpapi.IStage { +class StageDouble implements cpapi.IStage, cpapi.IInternalStage { public readonly name: string; public readonly pipelineArn: string; public readonly pipelineRole: iam.Role; + public readonly _internal = this; public readonly actions = new Array(); @@ -165,6 +166,14 @@ class StageDouble implements cpapi.IStage { public _attachAction(action: cpapi.Action) { this.actions.push(action); } + + public _generateOutputArtifactName(): string { + throw new Error('Unsupported'); + } + + public _findInputArtifact(): cpapi.Artifact { + throw new Error('Unsupported'); + } } class RoleDouble extends iam.Role { diff --git a/packages/@aws-cdk/aws-codebuild/README.md b/packages/@aws-cdk/aws-codebuild/README.md index 59df68315b53e..c477fdd6beeba 100644 --- a/packages/@aws-cdk/aws-codebuild/README.md +++ b/packages/@aws-cdk/aws-codebuild/README.md @@ -50,21 +50,12 @@ const project = new codebuild.PipelineProject(this, 'MyProject'); const pipeline = new codepipeline.Pipeline(this, 'MyPipeline'); -const sourceStage = new codepipeline.Stage(this, 'Source', { - pipeline, -}); -const sourceAction = new codecommit.PipelineSourceAction(this, 'CodeCommit', { - stage: sourceStage, - artifactName: 'SourceOutput', - repository, -}); +const sourceStage = pipeline.addStage('Source'); +repository.addToPipeline(sourceStage, 'CodeCommit'); -const buildStage = new codepipeline.Stage(this, 'Build', { - pipeline, -}); +const buildStage = pipeline.addStage('Build'); new codebuild.PipelineBuildAction(this, 'CodeBuild', { stage: buildStage, - inputArtifact: sourceAction.artifact, project, }); ``` @@ -84,9 +75,7 @@ You can also add the Project to the Pipeline directly: ```ts // equivalent to the code above: -project.addBuildToPipeline(buildStage, 'CodeBuild', { - inputArtifact: sourceAction.artifact, -}) +project.addBuildToPipeline(buildStage, 'CodeBuild'); ``` ### Using Project as an event target diff --git a/packages/@aws-cdk/aws-codebuild/lib/pipeline-actions.ts b/packages/@aws-cdk/aws-codebuild/lib/pipeline-actions.ts index 8cbe6e463a661..6a9d0a2aed24d 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/pipeline-actions.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/pipeline-actions.ts @@ -10,14 +10,18 @@ import { ProjectRef } from './project'; */ export interface CommonPipelineBuildActionProps extends codepipeline.CommonActionProps { /** - * The source to use as input for this build + * The source to use as input for this build. + * + * @default CodePipeline will use the output of the last Action from a previous Stage as input */ - inputArtifact: codepipeline.Artifact; + inputArtifact?: codepipeline.Artifact; /** - * The name of the build's output artifact + * The name of the build's output artifact. + * + * @default an auto-generated name will be used */ - artifactName?: string; + outputArtifactName?: string; } /** @@ -44,7 +48,7 @@ export class PipelineBuildAction extends codepipeline.BuildAction { runOrder: props.runOrder, provider: 'CodeBuild', inputArtifact: props.inputArtifact, - artifactName: props.artifactName, + outputArtifactName: props.outputArtifactName, configuration: { ProjectName: props.project.projectName } diff --git a/packages/@aws-cdk/aws-codebuild/lib/project.ts b/packages/@aws-cdk/aws-codebuild/lib/project.ts index 11c7f63c0e7fb..7886d9d33c566 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/project.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/project.ts @@ -89,8 +89,8 @@ export abstract class ProjectRef extends cdk.Construct implements events.IEventR * @param props the properties of the new Action * @returns the newly created {@link PipelineBuildAction} build Action */ - public addBuildToPipeline(stage: codepipeline.IStage, name: string, props: CommonPipelineBuildActionProps): PipelineBuildAction { - return new PipelineBuildAction(this.parent!, name, { + public addBuildToPipeline(stage: codepipeline.IStage, name: string, props: CommonPipelineBuildActionProps = {}): PipelineBuildAction { + return new PipelineBuildAction(this, name, { stage, project: this, ...props, diff --git a/packages/@aws-cdk/aws-codecommit/README.md b/packages/@aws-cdk/aws-codecommit/README.md index 7586fafcf47f8..b8b4753296a07 100644 --- a/packages/@aws-cdk/aws-codecommit/README.md +++ b/packages/@aws-cdk/aws-codecommit/README.md @@ -5,22 +5,17 @@ To add a CodeCommit Repository to your stack: ```ts import codecommit = require('@aws-cdk/aws-codecommit'); -const repository = new codecommit.Repository(this, 'Repository' ,{ - repositoryName: 'MyRepositoryName' +const repo = new codecommit.Repository(this, 'Repository' ,{ + repositoryName: 'MyRepositoryName', + description: 'Some description.', // optional property }); ``` To add an SNS trigger to your repository: ```ts -import codecommit = require('@aws-cdk/aws-codecommit'); - -const repository = new codecommit.Repository(this, 'Repository', { - repositoryName: 'MyRepositoryName' -}); - // trigger is established for all repository actions on all branches by default. -repository.notify('arn:aws:sns:*:123456789012:my_topic'); +repo.notify('arn:aws:sns:*:123456789012:my_topic'); ``` ### CodePipeline @@ -28,34 +23,23 @@ repository.notify('arn:aws:sns:*:123456789012:my_topic'); To use a CodeCommit Repository in a CodePipeline: ```ts -import codecommit = require('@aws-cdk/aws-codecommit'); import codepipeline = require('@aws-cdk/aws-codepipeline'); -// see above for the details... -const repository = new codecommit.Repository( // ... -); - const pipeline = new codepipeline.Pipeline(this, 'MyPipeline', { pipelineName: 'MyPipeline', }); -const sourceStage = new codepipeline.Stage(this, 'Source', { - pipeline, -}); +const sourceStage = pipeline.addStage('Source'); const sourceAction = new codecommit.PipelineSourceAction(this, 'CodeCommit', { stage: sourceStage, - artifactName: 'SourceOutput', // name can be arbitrary - repository, + repository: repo, }); -// use sourceAction.artifact as the inputArtifact to later Actions... ``` You can also add the Repository to the Pipeline directly: ```ts // equivalent to the code above: -const sourceAction = repository.addToPipeline(sourceStage, 'CodeCommit', { - artifactName: 'SourceOutput', -}); +const sourceAction = repo.addToPipeline(sourceStage, 'CodeCommit'); ``` ### Events diff --git a/packages/@aws-cdk/aws-codecommit/lib/pipeline-action.ts b/packages/@aws-cdk/aws-codecommit/lib/pipeline-action.ts index 017c649bbab87..87027af072e1e 100644 --- a/packages/@aws-cdk/aws-codecommit/lib/pipeline-action.ts +++ b/packages/@aws-cdk/aws-codecommit/lib/pipeline-action.ts @@ -12,8 +12,10 @@ export interface CommonPipelineSourceActionProps extends codepipeline.CommonActi /** * The name of the source's output artifact. * Output artifacts are used by CodePipeline as inputs into other actions. + * + * @default a name will be auto-generated */ - artifactName: string; + outputArtifactName?: string; /** * @default 'master' @@ -54,7 +56,7 @@ export class PipelineSourceAction extends codepipeline.SourceAction { BranchName: props.branch || 'master', PollForSourceChanges: props.pollForSourceChanges !== undefined ? props.pollForSourceChanges : true }, - artifactName: props.artifactName + outputArtifactName: props.outputArtifactName }); // https://docs.aws.amazon.com/codecommit/latest/userguide/auth-and-access-control-permissions-reference.html#aa-acp diff --git a/packages/@aws-cdk/aws-codecommit/lib/repository.ts b/packages/@aws-cdk/aws-codecommit/lib/repository.ts index 465c25cb76b6f..76dc46cf834d9 100644 --- a/packages/@aws-cdk/aws-codecommit/lib/repository.ts +++ b/packages/@aws-cdk/aws-codecommit/lib/repository.ts @@ -68,8 +68,8 @@ export abstract class RepositoryRef extends cdk.Construct { * @param props the properties of the new Action * @returns the newly created {@link PipelineSourceAction} */ - public addToPipeline(stage: actions.IStage, name: string, props: CommonPipelineSourceActionProps): PipelineSourceAction { - return new PipelineSourceAction(this.parent!, name, { + public addToPipeline(stage: actions.IStage, name: string, props: CommonPipelineSourceActionProps = {}): PipelineSourceAction { + return new PipelineSourceAction(this, name, { stage, repository: this, ...props, diff --git a/packages/@aws-cdk/aws-codecommit/package.json b/packages/@aws-cdk/aws-codecommit/package.json index e8fa85d9838dd..2e8eacd1e458c 100644 --- a/packages/@aws-cdk/aws-codecommit/package.json +++ b/packages/@aws-cdk/aws-codecommit/package.json @@ -41,7 +41,7 @@ }, "nyc": { "lines": 30, - "branches": 48 + "branches": 40 }, "keywords": [ "aws", diff --git a/packages/@aws-cdk/aws-codedeploy/README.md b/packages/@aws-cdk/aws-codedeploy/README.md index fbbb404a1af01..0e0ec2c5798ce 100644 --- a/packages/@aws-cdk/aws-codedeploy/README.md +++ b/packages/@aws-cdk/aws-codedeploy/README.md @@ -137,12 +137,9 @@ const pipeline = new codepipeline.Pipeline(this, 'MyPipeline', { // add the source and build Stages to the Pipeline... -const deployStage = new codepipeline.Stage(this, 'Deploy', { - pipeline, -})); +const deployStage = pipeline.addStage('Deploy'); new codedeploy.PipelineDeployAction(this, 'CodeDeploy', { stage: deployStage, - inputArtifact: buildAction.artifact, // taken from a build Action in a previous Stage applicationName: 'YourCodeDeployApplicationName', deploymentGroupName: 'YourCodeDeployDeploymentGroupName', }); diff --git a/packages/@aws-cdk/aws-codedeploy/lib/pipeline-action.ts b/packages/@aws-cdk/aws-codedeploy/lib/pipeline-action.ts index 3bf08af45f42c..647abd1ae93c7 100644 --- a/packages/@aws-cdk/aws-codedeploy/lib/pipeline-action.ts +++ b/packages/@aws-cdk/aws-codedeploy/lib/pipeline-action.ts @@ -25,8 +25,10 @@ export interface PipelineDeployActionProps extends codepipeline.CommonActionProp /** * The source to use as input for deployment. + * + * @default CodePipeline will use the output of the last Action from a previous Stage as input */ - inputArtifact: codepipeline.Artifact; + inputArtifact?: codepipeline.Artifact; } export class PipelineDeployAction extends codepipeline.DeployAction { diff --git a/packages/@aws-cdk/aws-codepipeline-api/lib/action.ts b/packages/@aws-cdk/aws-codepipeline-api/lib/action.ts index 85bd766a6d9a0..d3fa2ba3b3ea4 100644 --- a/packages/@aws-cdk/aws-codepipeline-api/lib/action.ts +++ b/packages/@aws-cdk/aws-codepipeline-api/lib/action.ts @@ -36,6 +36,37 @@ export function defaultBounds(): ActionArtifactBounds { }; } +/** + * The API of Stage used internally by the CodePipeline Construct. + * You should never need to call any of the methods inside of it yourself. + */ +export interface IInternalStage { + /** + * Adds an Action to this Stage. + * + * @param action the Action to add to this Stage + */ + _attachAction(action: Action): void; + + /** + * Generates a unique output artifact name for the given Action. + * + * @param action the Action to generate the output artifact name for + */ + _generateOutputArtifactName(action: Action): string; + + /** + * Finds an input artifact for the given Action. + * The chosen artifact will be the output artifact of the + * last Action in the Pipeline + * (up to the Stage this Action belongs to) + * with the highest runOrder that has an output artifact. + * + * @param action the Action to find the input artifact for + */ + _findInputArtifact(action: Action): Artifact; +} + /** * The abstract interface of a Pipeline Stage that is used by Actions. */ @@ -56,21 +87,17 @@ export interface IStage { readonly pipelineRole: iam.Role; /** - * Grants read & write permissions to the Pipeline's S3 Bucket to the given Identity. - * - * @param identity the IAM Identity to grant the permissions to + * The API of Stage used internally by the CodePipeline Construct. + * You should never need to call any of the methods inside of it yourself. */ - grantPipelineBucketReadWrite(identity: iam.IPrincipal): void; + readonly _internal: IInternalStage; /** - * Adds an Action to this Stage. - * This is an internal operation - - * an Action is added to a Stage when it's constructed, - * so there's no need to call this method explicitly. + * Grants read & write permissions to the Pipeline's S3 Bucket to the given Identity. * - * @param action the Action to add to this Stage + * @param identity the IAM Identity to grant the permissions to */ - _attachAction(action: Action): void; + grantPipelineBucketReadWrite(identity: iam.IPrincipal): void; } /** @@ -146,8 +173,8 @@ export abstract class Action extends cdk.Construct { public readonly owner: string; public readonly version: string; - private readonly _inputArtifacts = new Array(); - private readonly _outputArtifacts = new Array(); + private readonly inputArtifacts = new Array(); + private readonly outputArtifacts = new Array(); private readonly artifactBounds: ActionArtifactBounds; private readonly stage: IStage; @@ -165,13 +192,13 @@ export abstract class Action extends cdk.Construct { this.runOrder = props.runOrder === undefined ? 1 : props.runOrder; this.stage = props.stage; - this.stage._attachAction(this); + this.stage._internal._attachAction(this); } public validate(): string[] { - return validation.validateArtifactBounds('input', this._inputArtifacts, this.artifactBounds.minInputs, + return validation.validateArtifactBounds('input', this.inputArtifacts, this.artifactBounds.minInputs, this.artifactBounds.maxInputs, this.category, this.provider) - .concat(validation.validateArtifactBounds('output', this._outputArtifacts, this.artifactBounds.minOutputs, + .concat(validation.validateArtifactBounds('output', this.outputArtifacts, this.artifactBounds.minOutputs, this.artifactBounds.maxOutputs, this.category, this.provider) ); } @@ -191,28 +218,22 @@ export abstract class Action extends cdk.Construct { return rule; } - public get inputArtifacts(): Artifact[] { - return this._inputArtifacts.slice(); + public get _inputArtifacts(): Artifact[] { + return this.inputArtifacts.slice(); } - public get outputArtifacts(): Artifact[] { - return this._outputArtifacts.slice(); - } - - protected addChild(child: cdk.Construct, name: string) { - super.addChild(child, name); - if (child instanceof Artifact) { - this._outputArtifacts.push(child); - } + public get _outputArtifacts(): Artifact[] { + return this.outputArtifacts.slice(); } - protected addOutputArtifact(name: string): Artifact { + protected addOutputArtifact(name: string = this.stage._internal._generateOutputArtifactName(this)): Artifact { const artifact = new Artifact(this, name); + this.outputArtifacts.push(artifact); return artifact; } - protected addInputArtifact(artifact: Artifact): Action { - this._inputArtifacts.push(artifact); + protected addInputArtifact(artifact: Artifact = this.stage._internal._findInputArtifact(this)): Action { + this.inputArtifacts.push(artifact); return this; } } diff --git a/packages/@aws-cdk/aws-codepipeline-api/lib/build-action.ts b/packages/@aws-cdk/aws-codepipeline-api/lib/build-action.ts index 8184ffa39f646..441b9a4d4445f 100644 --- a/packages/@aws-cdk/aws-codepipeline-api/lib/build-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-api/lib/build-action.ts @@ -9,17 +9,24 @@ export interface BuildActionProps extends CommonActionProps, CommonActionConstru /** * The source to use as input for this build. */ - inputArtifact: Artifact; + inputArtifact?: Artifact; /** * The service provider that the action calls. For example, a valid provider for Source actions is CodeBuild. */ provider: string; + /** + * The source action owner (could be 'AWS', 'ThirdParty' or 'Custom'). + * + * @default 'AWS' + */ + owner?: string; + /** * The name of the build's output artifact. */ - artifactName?: string; + outputArtifactName?: string; /** * The action's configuration. These are key-value pairs that specify input values for an action. @@ -36,21 +43,16 @@ export interface BuildActionProps extends CommonActionProps, CommonActionConstru * such as {@link codebuild.PipelineBuildAction}. */ export abstract class BuildAction extends Action { - public readonly artifact?: Artifact; + public readonly outputArtifact: Artifact; constructor(parent: cdk.Construct, name: string, props: BuildActionProps) { super(parent, name, { - stage: props.stage, - runOrder: props.runOrder, - artifactBounds: { minInputs: 1, maxInputs: 1, minOutputs: 0, maxOutputs: 1 }, category: ActionCategory.Build, - provider: props.provider, - configuration: props.configuration + artifactBounds: { minInputs: 1, maxInputs: 1, minOutputs: 0, maxOutputs: 1 }, + ...props, }); this.addInputArtifact(props.inputArtifact); - if (props.artifactName) { - this.artifact = this.addOutputArtifact(props.artifactName); - } + this.outputArtifact = this.addOutputArtifact(props.outputArtifactName); } } diff --git a/packages/@aws-cdk/aws-codepipeline-api/lib/deploy-action.ts b/packages/@aws-cdk/aws-codepipeline-api/lib/deploy-action.ts index 81a352157e031..7e678020b9be0 100644 --- a/packages/@aws-cdk/aws-codepipeline-api/lib/deploy-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-api/lib/deploy-action.ts @@ -5,6 +5,8 @@ import { Artifact } from './artifact'; export interface DeployActionProps extends CommonActionProps, CommonActionConstructProps { provider: string; + owner?: string; + artifactBounds: ActionArtifactBounds; inputArtifact?: Artifact; @@ -15,16 +17,10 @@ export interface DeployActionProps extends CommonActionProps, CommonActionConstr export abstract class DeployAction extends Action { constructor(parent: cdk.Construct, name: string, props: DeployActionProps) { super(parent, name, { - stage: props.stage, - runOrder: props.runOrder, category: ActionCategory.Deploy, - provider: props.provider, - artifactBounds: props.artifactBounds, - configuration: props.configuration, + ...props, }); - if (props.inputArtifact) { - this.addInputArtifact(props.inputArtifact); - } + this.addInputArtifact(props.inputArtifact); } } diff --git a/packages/@aws-cdk/aws-codepipeline-api/lib/source-action.ts b/packages/@aws-cdk/aws-codepipeline-api/lib/source-action.ts index 188df78d37ec7..83c2a355b4f1e 100644 --- a/packages/@aws-cdk/aws-codepipeline-api/lib/source-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-api/lib/source-action.ts @@ -23,8 +23,10 @@ export interface SourceActionProps extends CommonActionProps, CommonActionConstr /** * The name of the source's output artifact. * Output artifacts are used by CodePipeline as inputs into other actions. + * + * @default a name will be auto-generated */ - artifactName: string; + outputArtifactName?: string; /** * The service provider that the action calls. @@ -48,20 +50,15 @@ export interface SourceActionProps extends CommonActionProps, CommonActionConstr * {@link codecommit.PipelineSourceAction}. */ export abstract class SourceAction extends Action { - public readonly artifact: Artifact; + public readonly outputArtifact: Artifact; constructor(parent: cdk.Construct, name: string, props: SourceActionProps) { super(parent, name, { - stage: props.stage, - runOrder: props.runOrder, category: ActionCategory.Source, - owner: props.owner, - provider: props.provider, - version: props.version, artifactBounds: { minInputs: 0, maxInputs: 0, minOutputs: 1, maxOutputs: 1 }, - configuration: props.configuration + ...props, }); - this.artifact = this.addOutputArtifact(props.artifactName); + this.outputArtifact = this.addOutputArtifact(props.outputArtifactName); } } diff --git a/packages/@aws-cdk/aws-codepipeline/README.md b/packages/@aws-cdk/aws-codepipeline/README.md index 177f95b91969d..3cb57219713a4 100644 --- a/packages/@aws-cdk/aws-codepipeline/README.md +++ b/packages/@aws-cdk/aws-codepipeline/README.md @@ -1,14 +1,26 @@ -## AWS CodePipeline construct library +## AWS CodePipeline Construct Library -Construct an empty Pipeline: +### Pipeline + +To construct an empty Pipeline: + +```ts +import codepipeline = require('@aws-cdk/aws-codepipeline'); + +const pipeline = new codepipeline.Pipeline(this, 'MyFirstPipeline'); +``` + +To give the Pipeline a nice, human-readable name: ```ts -const pipeline = new Pipeline(this, 'MyFirstPipeline', { - pipelineName: 'MyFirstPipeline', +const pipeline = new codepipeline.Pipeline(this, 'MyFirstPipeline', { + pipelineName: 'MyPipeline', }); ``` -Append a Stage to the Pipeline: +### Stages + +To append a Stage to a Pipeline: ```ts const sourceStage = pipeline.addStage('Source'); @@ -21,28 +33,47 @@ You can insert the new Stage at an arbitrary point in the Pipeline: ```ts const sourceStage = pipeline.addStage('Source', { - placement: { - // note: you can only specify one of the below properties - rightBefore: anotherStage, - justAfter: anotherStage, - atIndex: 3, // indexing starts at 0 - // pipeline.stageCount returns the number of Stages currently in the Pipeline - } + placement: { + // note: you can only specify one of the below properties + rightBefore: anotherStage, + justAfter: anotherStage, + atIndex: 3, // indexing starts at 0 + // pipeline.stageCount returns the number of Stages currently in the Pipeline + } }); ``` -Add an Action to a Stage: +### Actions + +To add an Action to a Stage: ```ts -new codecommit.PipelineSourceAction(this, 'Source', { - stage: sourceStage, - artifactName: 'MyPackageSourceArtifact', - repository: codecommit.RepositoryRef.import(this, 'MyExistingRepository', { - repositoryName: new codecommit.RepositoryName('MyExistingRepository'), - }), +new codepipeline.GitHubSourceAction(this, 'GitHub_Source', { + stage: sourceStage, + owner: 'awslabs', + repo: 'aws-cdk', + branch: 'develop', // default: 'master' + oauthToken: ..., }) ``` +The Pipeline construct will automatically generate and wire together the artifact names CodePipeline uses. +If you need, you can also name the artifacts explicitly: + +```ts +const sourceAction = new codepipeline.GitHubSourceAction(this, 'GitHub_Source', { + // other properties as above... + outputArtifactName: 'SourceOutput', // this will be the name of the output artifact in the Pipeline +}); + +// in a build Action later... + +new codepipeline.JenkinsBuildAction(this, 'Jenkins_Build', { + // other properties... + inputArtifact: sourceAction.outputArtifact, +}); +``` + ### Events #### Using a pipeline as an event target diff --git a/packages/@aws-cdk/aws-codepipeline/lib/github-source-action.ts b/packages/@aws-cdk/aws-codepipeline/lib/github-source-action.ts index d73b7168f9bea..953c497d7008e 100644 --- a/packages/@aws-cdk/aws-codepipeline/lib/github-source-action.ts +++ b/packages/@aws-cdk/aws-codepipeline/lib/github-source-action.ts @@ -9,8 +9,10 @@ export interface GitHubSourceActionProps extends actions.CommonActionProps, /** * The name of the source's output artifact. Output artifacts are used by CodePipeline as * inputs into other actions. + * + * @default a name will be auto-generated */ - artifactName: string; + outputArtifactName?: string; /** * The GitHub account/user that owns the repo. @@ -66,7 +68,7 @@ export class GitHubSourceAction extends actions.SourceAction { OAuthToken: props.oauthToken, PollForSourceChanges: props.pollForSourceChanges || true }, - artifactName: props.artifactName + outputArtifactName: props.outputArtifactName }); } } diff --git a/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts b/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts index f83cac1f4a161..3672521b19b56 100644 --- a/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts +++ b/packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts @@ -245,6 +245,47 @@ export class Pipeline extends cdk.Construct implements events.IEventRuleTarget { this.stages.splice(index, 0, stage); } + // ignore unused private method (it's actually used in Stage) + // @ts-ignore + private _generateOutputArtifactName(stage: actions.IStage, action: actions.Action): string { + // generate the artifact name based on the Action's full logical ID, + // thus guaranteeing uniqueness + return 'Artifact_' + action.uniqueId; + } + + /** + * Finds an input artifact for the given Action. + * The chosen artifact will be the output artifact of the + * last Action in the Pipeline + * (up to the Stage this Action belongs to), + * with the highest runOrder, that has an output artifact. + * + * @param stage the Stage `action` belongs to + * @param action the Action to find the input artifact for + */ + // ignore unused private method (it's actually used in Stage) + // @ts-ignore + private _findInputArtifact(stage: actions.IStage, action: actions.Action): actions.Artifact { + // search for the first Action that has an outputArtifact, + // and return that + const startIndex = this.stages.findIndex(s => s === stage); + for (let i = startIndex; i >= 0; i--) { + const currentStage = this.stages[i]; + + // get all of the Actions in the Stage, sorted by runOrder, descending + const currentActions = currentStage.actions.sort((a1, a2) => -(a1.runOrder - a2.runOrder)); + for (const currentAction of currentActions) { + // for the first Stage (the one that `action` belongs to) + // we need to only take into account Actions with a smaller runOrder than `action` + if ((i !== startIndex || currentAction.runOrder < action.runOrder) && currentAction._outputArtifacts.length > 0) { + return currentAction._outputArtifacts[0]; + } + } + } + throw new Error(`Could not determine the input artifact for Action with name '${action.id}'. ` + + 'Please provide it explicitly with the inputArtifact property.'); + } + private calculateInsertIndexFromPlacement(placement: StagePlacement): number { // check if at most one placement property was provided const providedPlacementProps = ['rightBefore', 'justAfter', 'atIndex'] diff --git a/packages/@aws-cdk/aws-codepipeline/lib/stage.ts b/packages/@aws-cdk/aws-codepipeline/lib/stage.ts index 44c7c699577a5..665992e32d757 100644 --- a/packages/@aws-cdk/aws-codepipeline/lib/stage.ts +++ b/packages/@aws-cdk/aws-codepipeline/lib/stage.ts @@ -72,13 +72,19 @@ export interface StageProps extends CommonStageProps { * pipeline: myPipeline, * }); */ -export class Stage extends cdk.Construct implements actions.IStage { +export class Stage extends cdk.Construct implements actions.IStage, actions.IInternalStage { /** * The Pipeline this Stage is a part of. */ public readonly pipeline: Pipeline; public readonly name: string; + /** + * The API of Stage used internally by the CodePipeline Construct. + * You should never need to call any of the methods inside of it yourself. + */ + public readonly _internal = this; + private readonly _actions = new Array(); /** @@ -146,10 +152,18 @@ export class Stage extends cdk.Construct implements actions.IStage { } } + public _generateOutputArtifactName(action: actions.Action): string { + return (this.pipeline as any)._generateOutputArtifactName(this, action); + } + + public _findInputArtifact(action: actions.Action): actions.Artifact { + return (this.pipeline as any)._findInputArtifact(this, action); + } + private renderAction(action: actions.Action): cloudformation.PipelineResource.ActionDeclarationProperty { return { name: action.id, - inputArtifacts: action.inputArtifacts.map(a => ({ name: a.name })), + inputArtifacts: action._inputArtifacts.map(a => ({ name: a.name })), actionTypeId: { category: action.category.toString(), version: action.version, @@ -157,7 +171,7 @@ export class Stage extends cdk.Construct implements actions.IStage { provider: action.provider, }, configuration: action.configuration, - outputArtifacts: action.outputArtifacts.map(a => ({ name: a.name })), + outputArtifacts: action._outputArtifacts.map(a => ({ name: a.name })), runOrder: action.runOrder, }; } diff --git a/packages/@aws-cdk/aws-codepipeline/test/integ.cfn-template-from-repo.lit.ts b/packages/@aws-cdk/aws-codepipeline/test/integ.cfn-template-from-repo.lit.ts index d5ae5c5dc6546..99c9cdb23dc2f 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/integ.cfn-template-from-repo.lit.ts +++ b/packages/@aws-cdk/aws-codepipeline/test/integ.cfn-template-from-repo.lit.ts @@ -17,7 +17,7 @@ const sourceStage = new codepipeline.Stage(pipeline, 'Source', { pipeline }); const source = new codecommit.PipelineSourceAction(stack, 'Source', { stage: sourceStage, repository: repo, - artifactName: 'SourceArtifact', + outputArtifactName: 'SourceArtifact', }); // Deployment stage: create and deploy changeset with manual approval @@ -30,7 +30,7 @@ new cfn.PipelineCreateReplaceChangeSetAction(prodStage, 'PrepareChanges', { stackName, changeSetName, fullPermissions: true, - templatePath: source.artifact.atPath('template.yaml'), + templatePath: source.outputArtifact.atPath('template.yaml'), }); new codepipeline.ManualApprovalAction(stack, 'ApproveChanges', { diff --git a/packages/@aws-cdk/aws-codepipeline/test/integ.lambda-pipeline.ts b/packages/@aws-cdk/aws-codepipeline/test/integ.lambda-pipeline.ts index f8f4f5dba7814..b623e59d132ca 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/integ.lambda-pipeline.ts +++ b/packages/@aws-cdk/aws-codepipeline/test/integ.lambda-pipeline.ts @@ -15,7 +15,7 @@ const bucket = new s3.Bucket(stack, 'PipelineBucket', { }); new s3.PipelineSourceAction(stack, 'Source', { stage: sourceStage, - artifactName: 'SourceArtifact', + outputArtifactName: 'SourceArtifact', bucket, bucketKey: 'key', }); diff --git a/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-cfn.ts b/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-cfn.ts index 341b05d3eef90..b0a1bc7f25daf 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-cfn.ts +++ b/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-cfn.ts @@ -1,5 +1,4 @@ import cfn = require('@aws-cdk/aws-cloudformation'); -import { ArtifactPath } from '@aws-cdk/aws-codepipeline-api'; import { Role } from '@aws-cdk/aws-iam'; import { ServicePrincipal } from '@aws-cdk/aws-iam'; import s3 = require('@aws-cdk/aws-s3'); @@ -18,7 +17,7 @@ const bucket = new s3.Bucket(stack, 'PipelineBucket', { }); const source = new s3.PipelineSourceAction(stack, 'Source', { stage: sourceStage, - artifactName: 'SourceArtifact', + outputArtifactName: 'SourceArtifact', bucket, bucketKey: 'key', }); @@ -37,7 +36,7 @@ new cfn.PipelineCreateReplaceChangeSetAction(stack, 'DeployCFN', { changeSetName, stackName, role, - templatePath: new ArtifactPath(source.artifact, 'test.yaml') + templatePath: source.outputArtifact.atPath('test.yaml'), }); app.run(); diff --git a/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-code-commit-build.expected.json b/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-code-commit-build.expected.json index 4088ef1fa556d..f8b7694208759 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-code-commit-build.expected.json +++ b/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-code-commit-build.expected.json @@ -175,7 +175,11 @@ } ], "Name": "build", - "OutputArtifacts": [], + "OutputArtifacts": [ + { + "Name": "Artifact_awscdkcodepipelinecodecommitcodebuildMyBuildProjectbuild61B48DC4" + } + ], "RunOrder": 1 } ], diff --git a/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-code-commit-build.ts b/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-code-commit-build.ts index 0fc1b075f2bf8..41baeac27cab0 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-code-commit-build.ts +++ b/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-code-commit-build.ts @@ -14,9 +14,9 @@ const repository = new codecommit.Repository(stack, 'MyRepo', { const pipeline = new codepipeline.Pipeline(stack, 'Pipeline'); const sourceStage = new codepipeline.Stage(pipeline, 'source', { pipeline }); -const source = new codecommit.PipelineSourceAction(stack, 'source', { +new codecommit.PipelineSourceAction(stack, 'source', { stage: sourceStage, - artifactName: 'SourceArtifact', + outputArtifactName: 'SourceArtifact', repository, }); @@ -25,8 +25,6 @@ const project = new codebuild.Project(stack, 'MyBuildProject', { }); const buildStage = new codepipeline.Stage(pipeline, 'build', { pipeline }); -project.addBuildToPipeline(buildStage, 'build', { - inputArtifact: source.artifact, -}); +project.addBuildToPipeline(buildStage, 'build'); app.run(); diff --git a/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-code-commit.ts b/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-code-commit.ts index 794a3364031cd..dc5d80ea8e0ea 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-code-commit.ts +++ b/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-code-commit.ts @@ -12,7 +12,7 @@ const pipeline = new codepipeline.Pipeline(stack, 'Pipeline'); const sourceStage = pipeline.addStage('source'); repo.addToPipeline(sourceStage, 'source', { - artifactName: 'SourceArtifact', + outputArtifactName: 'SourceArtifact', }); const buildStage = new codepipeline.Stage(stack, 'build', { pipeline }); diff --git a/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-code-deploy.ts b/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-code-deploy.ts index 511901f2ac31b..954d49eb1652c 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-code-deploy.ts +++ b/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-code-deploy.ts @@ -30,15 +30,14 @@ const pipeline = new codepipeline.Pipeline(stack, 'Pipeline', { }); const sourceStage = new codepipeline.Stage(stack, 'Source', { pipeline }); -const sourceAction = bucket.addToPipeline(sourceStage, 'S3Source', { +bucket.addToPipeline(sourceStage, 'S3Source', { bucketKey: 'application.zip', - artifactName: 'SourceOutput', + outputArtifactName: 'SourceOutput', }); const deployStage = new codepipeline.Stage(stack, 'Deploy', { pipeline }); new codedeploy.PipelineDeployAction(stack, 'CodeDeploy', { stage: deployStage, - inputArtifact: sourceAction.artifact, applicationName: 'IntegTestDeployApp', deploymentGroupName: 'IntegTestDeploymentGroup', }); diff --git a/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-events.expected.json b/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-events.expected.json index df70d70cfd542..71f870df83040 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-events.expected.json +++ b/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-events.expected.json @@ -168,7 +168,11 @@ } ], "Name": "CodeBuildAction", - "OutputArtifacts": [], + "OutputArtifacts": [ + { + "Name": "Artifact_awscdkpipelineeventtargetCodeBuildAction37D411C2" + } + ], "RunOrder": 1 } ], diff --git a/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-events.ts b/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-events.ts index 6158c938f704a..c27c392eb2e18 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-events.ts +++ b/packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-events.ts @@ -21,12 +21,12 @@ const project = new codebuild.PipelineProject(stack, 'BuildProject'); const sourceAction = new codecommit.PipelineSourceAction(pipeline, 'CodeCommitSource', { stage: sourceStage, - artifactName: 'Source', + outputArtifactName: 'Source', repository, }); new codebuild.PipelineBuildAction(stack, 'CodeBuildAction', { stage: buildStage, - inputArtifact: sourceAction.artifact, + inputArtifact: sourceAction.outputArtifact, project }); diff --git a/packages/@aws-cdk/aws-codepipeline/test/test.action.ts b/packages/@aws-cdk/aws-codepipeline/test/test.action.ts index fd640a6d59886..0af650baf9d41 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/test.action.ts +++ b/packages/@aws-cdk/aws-codepipeline/test/test.action.ts @@ -1,4 +1,7 @@ // import { validateArtifactBounds, validateSourceAction } from '../lib/validation'; +import { expect, haveResource } from '@aws-cdk/assert'; +import codebuild = require('@aws-cdk/aws-codebuild'); +import codecommit = require('@aws-cdk/aws-codecommit'); import actions = require('@aws-cdk/aws-codepipeline-api'); import cdk = require('@aws-cdk/cdk'); import { Test } from 'nodeunit'; @@ -61,35 +64,59 @@ export = { }, }, - 'standard action with artifacts'(test: Test) { + 'automatically assigns artifact names to the Actions'(test: Test) { const stack = new cdk.Stack(); const pipeline = new codepipeline.Pipeline(stack, 'pipeline'); - const stage = new codepipeline.Stage(stack, 'stage', { pipeline }); - const action = new TestAction(stack, 'TestAction', { - stage, - artifactBounds: actions.defaultBounds(), - category: actions.ActionCategory.Source, - provider: 'test provider', - configuration: { blah: 'bleep' } + + const repo = new codecommit.Repository(stack, 'Repo', { + repositoryName: 'Repo', }); - new actions.Artifact(action, 'TestOutput'); + const sourceStage = pipeline.addStage('Source'); + repo.addToPipeline(sourceStage, 'CodeCommit'); + + const project = new codebuild.PipelineProject(stack, 'Project'); + const buildStage = pipeline.addStage('Build'); + project.addBuildToPipeline(buildStage, 'CodeBuild'); - test.deepEqual((stage.render().actions as any)[0], { - name: 'TestAction', - inputArtifacts: [], - actionTypeId: + expect(stack).to(haveResource('AWS::CodePipeline::Pipeline', { + "Stages": [ { - category: 'Source', - version: '1', - owner: 'AWS', - provider: 'test provider' + "Name": "Source", + "Actions": [ + { + "Name": "CodeCommit", + "InputArtifacts": [], + "OutputArtifacts": [ + { + "Name": "Artifact_RepoCodeCommit7910F5F9", + }, + ], + } + ], }, - configuration: { blah: 'bleep' }, - outputArtifacts: [{ name: 'TestOutput' }], - runOrder: 1 - }); + { + "Name": "Build", + "Actions": [ + { + "Name": "CodeBuild", + "InputArtifacts": [ + { + "Name": "Artifact_RepoCodeCommit7910F5F9", + } + ], + "OutputArtifacts": [ + { + "Name": "Artifact_ProjectCodeBuildE34AD2EC", + }, + ], + } + ], + }, + ], + })); + test.done(); - } + }, }; function boundsValidationResult(numberOfArtifacts: number, min: number, max: number): string[] { diff --git a/packages/@aws-cdk/aws-codepipeline/test/test.cloudformation-pipeline-actions.ts b/packages/@aws-cdk/aws-codepipeline/test/test.cloudformation-pipeline-actions.ts index 920a3fdc57e50..e6b66298cb0b9 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/test.cloudformation-pipeline-actions.ts +++ b/packages/@aws-cdk/aws-codepipeline/test/test.cloudformation-pipeline-actions.ts @@ -28,7 +28,7 @@ export = { const source = new PipelineSourceAction(stack, 'source', { stage: sourceStage, - artifactName: 'SourceArtifact', + outputArtifactName: 'SourceArtifact', repository: repo, }); @@ -44,8 +44,8 @@ export = { const buildAction = new PipelineBuildAction(stack, 'build', { stage: buildStage, project, - inputArtifact: source.artifact, - artifactName: "OutputYo" + inputArtifact: source.outputArtifact, + outputArtifactName: "OutputYo" }); /** Deploy! */ @@ -62,8 +62,8 @@ export = { stackName, changeSetName, role: changeSetExecRole, - templatePath: new ArtifactPath(buildAction.artifact!, 'template.yaml'), - templateConfiguration: new ArtifactPath(buildAction.artifact!, 'templateConfig.json') + templatePath: new ArtifactPath(buildAction.outputArtifact, 'template.yaml'), + templateConfiguration: new ArtifactPath(buildAction.outputArtifact, 'templateConfig.json') }); new PipelineExecuteChangeSetAction(stack, 'ExecuteChangeSetProd', { @@ -203,7 +203,7 @@ export = { new PipelineCreateUpdateStackAction(stack.deployStage, 'CreateUpdate', { stage: stack.deployStage, stackName: 'MyStack', - templatePath: stack.source.artifact.atPath('template.yaml'), + templatePath: stack.source.outputArtifact.atPath('template.yaml'), fullPermissions: true, }); @@ -256,7 +256,7 @@ export = { new PipelineCreateUpdateStackAction(stack, 'CreateUpdate', { stage: stack.deployStage, stackName: 'MyStack', - templatePath: stack.source.artifact.atPath('template.yaml'), + templatePath: stack.source.outputArtifact.atPath('template.yaml'), outputFileName: 'CreateResponse.json', }); @@ -287,7 +287,7 @@ export = { new PipelineCreateUpdateStackAction(stack, 'CreateUpdate', { stage: stack.deployStage, stackName: 'MyStack', - templatePath: stack.source.artifact.atPath('template.yaml'), + templatePath: stack.source.outputArtifact.atPath('template.yaml'), replaceOnFailure: true, }); @@ -320,7 +320,7 @@ export = { new PipelineCreateUpdateStackAction(stack, 'CreateUpdate', { stage: stack.deployStage, stackName: 'MyStack', - templatePath: stack.source.artifact.atPath('template.yaml'), + templatePath: stack.source.outputArtifact.atPath('template.yaml'), parameterOverrides: { RepoName: stack.repo.repositoryName } @@ -371,7 +371,7 @@ class TestFixture extends cdk.Stack { this.repo = new Repository(this, 'MyVeryImportantRepo', { repositoryName: 'my-very-important-repo' }); this.source = new PipelineSourceAction(this, 'Source', { stage: this.sourceStage, - artifactName: 'SourceArtifact', + outputArtifactName: 'SourceArtifact', repository: this.repo, }); } diff --git a/packages/@aws-cdk/aws-codepipeline/test/test.general-validation.ts b/packages/@aws-cdk/aws-codepipeline/test/test.general-validation.ts index 3ca6c9b92438f..f10c842b09e7e 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/test.general-validation.ts +++ b/packages/@aws-cdk/aws-codepipeline/test/test.general-validation.ts @@ -62,13 +62,13 @@ export = { const bucket = new s3.Bucket(stack, 'PipelineBucket'); new s3.PipelineSourceAction(stack, 'FirstAction', { stage: firstStage, - artifactName: 'FirstArtifact', + outputArtifactName: 'FirstArtifact', bucket, bucketKey: 'key', }); new s3.PipelineSourceAction(stack, 'SecondAction', { stage: secondStage, - artifactName: 'SecondAction', + outputArtifactName: 'SecondAction', bucket, bucketKey: 'key', }); diff --git a/packages/@aws-cdk/aws-codepipeline/test/test.pipeline.ts b/packages/@aws-cdk/aws-codepipeline/test/test.pipeline.ts index 81c890292bad9..8b6c20f74f5cd 100644 --- a/packages/@aws-cdk/aws-codepipeline/test/test.pipeline.ts +++ b/packages/@aws-cdk/aws-codepipeline/test/test.pipeline.ts @@ -22,7 +22,7 @@ export = { const sourceStage = new codepipeline.Stage(pipeline, 'source', { pipeline }); const source = new codecommit.PipelineSourceAction(stack, 'source', { stage: sourceStage, - artifactName: 'SourceArtifact', + outputArtifactName: 'SourceArtifact', repository, }); @@ -32,7 +32,7 @@ export = { }); new codebuild.PipelineBuildAction(stack, 'build', { stage: buildStage, - inputArtifact: source.artifact, + inputArtifact: source.outputArtifact, project, }); @@ -52,7 +52,7 @@ export = { new codepipeline.GitHubSourceAction(stack, 'GH', { stage: s1, runOrder: 8, - artifactName: 'A', + outputArtifactName: 'A', branch: 'branch', oauthToken: secret.value, owner: 'foo', @@ -140,7 +140,7 @@ export = { const stage1 = new codepipeline.Stage(stack, 'S1', { pipeline }); new s3.PipelineSourceAction(stack, 'A1', { stage: stage1, - artifactName: 'Artifact', + outputArtifactName: 'Artifact', bucket: new s3.Bucket(stack, 'Bucket'), bucketKey: 'Key' }); @@ -343,7 +343,7 @@ export = { const result = new codecommit.PipelineSourceAction(stack, 'stage', { stage: stageForTesting(stack), - artifactName: 'SomeArtifact', + outputArtifactName: 'SomeArtifact', repository: repositoryForTesting(stack), pollForSourceChanges: false, }); @@ -356,7 +356,7 @@ export = { const result = new codecommit.PipelineSourceAction(stack, 'stage', { stage: stageForTesting(stack), - artifactName: 'SomeArtifact', + outputArtifactName: 'SomeArtifact', repository: repositoryForTesting(stack), pollForSourceChanges: true, }); diff --git a/packages/@aws-cdk/aws-lambda/lib/pipeline-action.ts b/packages/@aws-cdk/aws-lambda/lib/pipeline-action.ts index 4e37842794d85..70890d9a39504 100644 --- a/packages/@aws-cdk/aws-lambda/lib/pipeline-action.ts +++ b/packages/@aws-cdk/aws-lambda/lib/pipeline-action.ts @@ -86,13 +86,4 @@ export class PipelineInvokeAction extends codepipeline.Action { .addAction('codepipeline:PutJobFailureResult')); } } - - /** - * Add an input artifact - * @param artifact - */ - protected addInputArtifact(artifact: codepipeline.Artifact): codepipeline.Action { - super.addInputArtifact(artifact); - return this; - } } diff --git a/packages/@aws-cdk/aws-s3/README.md b/packages/@aws-cdk/aws-s3/README.md index be325f8118192..0b8801a7ec207 100644 --- a/packages/@aws-cdk/aws-s3/README.md +++ b/packages/@aws-cdk/aws-s3/README.md @@ -87,25 +87,20 @@ const sourceBucket = new s3.Bucket(this, 'MyBucket', { }); const pipeline = new codepipeline.Pipeline(this, 'MyPipeline'); -const sourceStage = new codepipeline.Stage(this, 'Source', { - pipeline, -}); +const sourceStage = pipeline.addStage('Source'); const sourceAction = new s3.PipelineSourceAction(this, 'S3Source', { stage: sourceStage, bucket: sourceBucket, bucketKey: 'path/to/file.zip', - artifactName: 'SourceOuptut', //name can be arbitrary }); -// use sourceAction.artifact as the inputArtifact to later Actions... ``` You can also add the Bucket to the Pipeline directly: ```ts // equivalent to the code above: -const sourceAction = sourceBucket.addToPipeline(sourceStage, 'CodeCommit', { +const sourceAction = sourceBucket.addToPipeline(sourceStage, 'S3Source', { bucketKey: 'path/to/file.zip', - artifactName: 'SourceOutput', }); ``` diff --git a/packages/@aws-cdk/aws-s3/lib/bucket.ts b/packages/@aws-cdk/aws-s3/lib/bucket.ts index 2f56be427017f..5f4c28e327b65 100644 --- a/packages/@aws-cdk/aws-s3/lib/bucket.ts +++ b/packages/@aws-cdk/aws-s3/lib/bucket.ts @@ -124,7 +124,7 @@ export abstract class BucketRef extends cdk.Construct { * @returns the newly created {@link PipelineSourceAction} */ public addToPipeline(stage: actions.IStage, name: string, props: CommonPipelineSourceActionProps): PipelineSourceAction { - return new PipelineSourceAction(this.parent!, name, { + return new PipelineSourceAction(this, name, { stage, bucket: this, ...props, diff --git a/packages/@aws-cdk/aws-s3/lib/pipeline-action.ts b/packages/@aws-cdk/aws-s3/lib/pipeline-action.ts index 7f8d8285a61ff..c77e805bcd98a 100644 --- a/packages/@aws-cdk/aws-s3/lib/pipeline-action.ts +++ b/packages/@aws-cdk/aws-s3/lib/pipeline-action.ts @@ -11,8 +11,10 @@ export interface CommonPipelineSourceActionProps extends codepipeline.CommonActi /** * The name of the source's output artifact. Output artifacts are used by CodePipeline as * inputs into other actions. + * + * @default a name will be auto-generated */ - artifactName: string; + outputArtifactName?: string; /** * The key within the S3 bucket that stores the source code. @@ -47,15 +49,13 @@ export interface PipelineSourceActionProps extends CommonPipelineSourceActionPro export class PipelineSourceAction extends codepipeline.SourceAction { constructor(parent: cdk.Construct, name: string, props: PipelineSourceActionProps) { super(parent, name, { - stage: props.stage, - runOrder: props.runOrder, provider: 'S3', configuration: { S3Bucket: props.bucket.bucketName, S3ObjectKey: props.bucketKey, PollForSourceChanges: props.pollForSourceChanges || true }, - artifactName: props.artifactName + ...props, }); // pipeline needs permissions to read from the S3 bucket