Skip to content

Commit

Permalink
feat(aws-codepipeline): Jenkins build and test Actions. (#1216)
Browse files Browse the repository at this point in the history
  • Loading branch information
skinny85 committed Jan 7, 2019
1 parent 607f997 commit 471e8eb
Show file tree
Hide file tree
Showing 11 changed files with 939 additions and 55 deletions.
52 changes: 0 additions & 52 deletions packages/@aws-cdk/aws-codepipeline-api/lib/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,55 +310,3 @@ export abstract class Action extends cdk.Construct {
// });
// }
// }

/*
TODO: A Jenkins build needs a corresponding custom action for each "Jenkins provider".
This should be created automatically.
Example custom action created to execute Jenkins:
{
"id": {
"category": "Test",
"provider": "<provider name>",
"owner": "Custom",
"version": "1"
},
"outputArtifactDetails": {
"minimumCount": 0,
"maximumCount": 5
},
"settings": {
"executionUrlTemplate": "https://www.google.com/job/{Config:ProjectName}/{ExternalExecutionId}",
"entityUrlTemplate": "https://www.google.com/job/{Config:ProjectName}"
},
"actionConfigurationProperties": [
{
"queryable": true,
"key": true,
"name": "ProjectName",
"required": true,
"secret": false
}
],
"inputArtifactDetails": {
"minimumCount": 0,
"maximumCount": 5
}
}
*/

// export class JenkinsBuild extends BuildAction {
// constructor(scope: Stage, id: string, jenkinsProvider: string, project: string) {
// super(scope, id, jenkinsProvider, DefaultBounds(), {
// ProjectName: project
// });
// }
// }

// export class JenkinsTest extends TestAction {
// constructor(scope: Stage, id: string, jenkinsProvider: string, project: string) {
// super(scope, id, jenkinsProvider, DefaultBounds(), {
// ProjectName: project
// });
// }
// }
9 changes: 8 additions & 1 deletion packages/@aws-cdk/aws-codepipeline-api/lib/build-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,19 @@ export interface BuildActionProps extends CommonActionProps, CommonActionConstru
artifactBounds: ActionArtifactBounds;

/**
* The source action owner (could be 'AWS', 'ThirdParty' or 'Custom').
* The build Action owner (could be 'AWS', 'ThirdParty' or 'Custom').
*
* @default 'AWS'
*/
owner?: string;

/**
* The build Action version.
*
* @default '1'
*/
version?: string;

/**
* The name of the build's output artifact.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface SourceActionProps extends CommonActionProps, CommonActionConstr
owner?: string;

/**
* The source action verison.
* The source Action version.
*
* @default "1"
*/
Expand Down
9 changes: 8 additions & 1 deletion packages/@aws-cdk/aws-codepipeline-api/lib/test-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,19 @@ export interface TestActionProps extends CommonActionProps, CommonActionConstruc
artifactBounds: ActionArtifactBounds;

/**
* The source action owner (could be 'AWS', 'ThirdParty' or 'Custom').
* The test Action owner (could be 'AWS', 'ThirdParty' or 'Custom').
*
* @default 'AWS'
*/
owner?: string;

/**
* The test Action version.
*
* @default '1'
*/
version?: string;

/**
* The action's configuration. These are key-value pairs that specify input values for an action.
* For more information, see the AWS CodePipeline User Guide.
Expand Down
55 changes: 55 additions & 0 deletions packages/@aws-cdk/aws-codepipeline/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,61 @@ but `notifyEmails` were,
a new SNS Topic will be created
(and accessible through the `notificationTopic` property of the Action).

#### Jenkins Actions

In order to use Jenkins Actions in the Pipeline,
you first need to create a `JenkinsProvider`:

```ts
const jenkinsProvider = new codepipeline.JenkinsProvider(this, 'JenkinsProvider', {
providerName: 'MyJenkinsProvider',
serverUrl: 'http://my-jenkins.com:8080',
version: '2', // optional, default: '1'
});
```

If you've registered a Jenkins provider in a different CDK app,
or outside the CDK (in the CodePipeline AWS Console, for example),
you can import it:

```ts
const jenkinsProvider = codepipeline.JenkinsProvider.import(this, 'JenkinsProvider', {
providerName: 'MyJenkinsProvider',
serverUrl: 'http://my-jenkins.com:8080',
version: '2', // optional, default: '1'
});
```

Note that a Jenkins provider
(identified by the provider name-category(build/test)-version tuple)
must always be registered in the given account, in the given AWS region,
before it can be used in CodePipeline.

With a `JenkinsProvider`,
we can create a Jenkins Action:

```ts
const buildAction = new codepipeline.JenkinsBuildAction(this, 'JenkinsBuild', {
stage: buildStage,
jenkinsProvider: jenkinsProvider,
projectName: 'MyProject',
});
// there's also a JenkinsTestAction that works identically
```

You can also add the Action to the Pipeline directly:

```ts
// equivalent to the code above:
const buildAction = jenkinsProvider.addToPipeline(buildStage, 'JenkinsBuild', {
projectName: 'MyProject',
});

const testAction = jenkinsProvider.addToPipelineAsTest(buildStage, 'JenkinsTest', {
projectName: 'MyProject',
});
```

### Cross-region CodePipelines

You can also use the cross-region feature to deploy resources
Expand Down
145 changes: 145 additions & 0 deletions packages/@aws-cdk/aws-codepipeline/lib/custom-action-registration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import cpapi = require('@aws-cdk/aws-codepipeline-api');
import cdk = require('@aws-cdk/cdk');
import { cloudformation } from './codepipeline.generated';

/**
* The creation attributes used for defining a configuration property
* of a custom Action.
*/
export interface CustomActionProperty {
/**
* The name of the property.
* You use this name in the `configuration` attribute when defining your custom Action class.
*/
name: string;

/**
* The description of the property.
*
* @default the description will be empty
*/
description?: string;

// because of @see URLs
// tslint:disable:max-line-length

/**
* Whether this property is a key.
*
* @default false
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codepipeline-customactiontype-configurationproperties.html#cfn-codepipeline-customactiontype-configurationproperties-key
*/
key?: boolean;

/**
* Whether this property is queryable.
* Note that only a single property of a custom Action can be queryable.
*
* @default false
* @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codepipeline-customactiontype-configurationproperties.html#cfn-codepipeline-customactiontype-configurationproperties-queryable
*/
queryable?: boolean;

// tslint:enable:max-line-length

/**
* Whether this property is required.
*/
required: boolean;

/**
* Whether this property is secret,
* like a password, or access key.
*
* @default false
*/
secret?: boolean;

/**
* The type of the property,
* like 'String', 'Number', or 'Boolean'.
*
* @default 'String'
*/
type?: string;
}

/**
* Properties of registering a custom Action.
*/
export interface CustomActionRegistrationProps {
/**
* The category of the Action.
*/
category: cpapi.ActionCategory;

/**
* The artifact bounds of the Action.
*/
artifactBounds: cpapi.ActionArtifactBounds;

/**
* The provider of the Action.
*/
provider: string;

/**
* The version of your Action.
*
* @default '1'
*/
version?: string;

/**
* The URL shown for the entire Action in the Pipeline UI.
*/
entityUrl?: string;

/**
* The URL shown for a particular execution of an Action in the Pipeline UI.
*/
executionUrl?: string;

/**
* The properties used for customizing the instance of your Action.
*
* @default []
*/
actionProperties?: CustomActionProperty[];
}

/**
* The resource representing registering a custom Action with CodePipeline.
* For the Action to be usable, it has to be registered for every region and every account it's used in.
* In addition to this class, you should most likely also provide your clients a class
* representing your custom Action, extending the Action class,
* and taking the `actionProperties` as properly typed, construction properties.
*/
export class CustomActionRegistration extends cdk.Construct {
constructor(parent: cdk.Construct, id: string, props: CustomActionRegistrationProps) {
super(parent, id);

new cloudformation.CustomActionTypeResource(this, 'Resource', {
category: props.category,
inputArtifactDetails: {
minimumCount: props.artifactBounds.minInputs,
maximumCount: props.artifactBounds.maxInputs,
},
outputArtifactDetails: {
minimumCount: props.artifactBounds.minOutputs,
maximumCount: props.artifactBounds.maxOutputs,
},
provider: props.provider,
version: props.version,
settings: {
entityUrlTemplate: props.entityUrl,
executionUrlTemplate: props.executionUrl,
},
configurationProperties: props.actionProperties === undefined ? undefined : props.actionProperties.map((ap) => { return {
key: ap.key || false,
secret: ap.secret || false,
...ap,
}; }),
});
}
}
2 changes: 2 additions & 0 deletions packages/@aws-cdk/aws-codepipeline/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export * from './cross-region-scaffold-stack';
export * from './github-source-action';
export * from './jenkins-actions';
export * from './jenkins-provider';
export * from './manual-approval-action';
export * from './pipeline';
export * from './stage';
Expand Down
Loading

0 comments on commit 471e8eb

Please sign in to comment.