Skip to content

Commit

Permalink
Merge branch 'main' of github.com:ttskp/cdk-pipelines into main
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/BuildSpecPipeline.ts
  • Loading branch information
wolfadr committed Jun 7, 2021
1 parent 6ffc2b1 commit 246fc85
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 57 deletions.
14 changes: 5 additions & 9 deletions buildspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ env:
code-artifact:
domain: tts
repos:
pip: tts-pypi
tts-npm: [npm, jsii-npm]
# tts-pypi: [pip, jsii-twine]
phases:
install:
runtime-versions:
Expand All @@ -14,16 +15,11 @@ phases:
pre_build:
commands:
- yarn install
- projen
- projen bump
build:
commands:
- projen build
post_build:
commands:
- ls -al
- export CODEARTIFACT_AUTH_TOKEN=`aws codeartifact get-authorization-token --domain tts --domain-owner 672648692041 --query authorizationToken --output text`
- export TWINE_REPOSITORY_URL=`aws codeartifact get-repository-endpoint --domain tts --repository tts-pypi --format pypi --query repositoryEndpoint --output text`
- export TWINE_USERNAME=aws
- export TWINE_PASSWORD=$CODEARTIFACT_AUTH_TOKEN
- jsii-release-pypi
- projen bump
- echo $NPM_REGISTRY
- jsii-release-npm
61 changes: 14 additions & 47 deletions src/BuildSpecPipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { CodeBuildAction, CodeCommitSourceAction, CodeCommitTrigger } from '@aws
import { Effect, PolicyStatement } from '@aws-cdk/aws-iam';
import { Construct, Duration, RemovalPolicy, Stack } from '@aws-cdk/core';
import * as YAML from 'yaml';
import { CodeArtifactFeature } from './features/codeArtifact';
import { BuildProjectFeature } from './features/core';

// type dict = { [key: string]: any };
type dict = Record<string, any>;
Expand All @@ -29,60 +31,13 @@ export interface BuildSpecPipelineProps {

readonly buildSpec?: dict;
readonly buildSpecFile?: string;

// readonly codeArtifactDomain?: string;
}

const buildSpecPipelinePropsDefaults: BuildSpecPipelineProps = {
retainRepository: true,
branch: 'master',
};

export class BuildProjectFeature {
readonly policyStatements: Array<PolicyStatement> = [];
readonly preBuildCommands: Array<string> = [];
}

interface CodeArtifactFeatureProps {
readonly domain: string;
readonly repos: Record<string, string>;
}

class CodeArtifactFeature extends BuildProjectFeature {

constructor(pipeline: BuildSpecPipeline) {

super();

const params: CodeArtifactFeatureProps = pipeline.buildSpec.env?.['code-artifact'];

if (params?.domain && params?.repos) {
const region = Stack.of(pipeline).region;
const account = Stack.of(pipeline).account;

this.policyStatements.push(new PolicyStatement({
actions: ['codeartifact:*'],
resources: [
`arn:aws:codeartifact:${region}:${account}:package/${params.domain}/*`,
`arn:aws:codeartifact:${region}:${account}:repository/${params.domain}/*`,
`arn:aws:codeartifact:${region}:${account}:domain/${params.domain}`,
],
effect: Effect.ALLOW,
}));

this.policyStatements.push(new PolicyStatement({
actions: ['sts:GetServiceBearerToken'],
resources: ['*'],
effect: Effect.ALLOW,
}));

Object.keys(params.repos).forEach(key => {
this.preBuildCommands.push(`aws codeartifact login --tool ${key} --repository ${params.repos[key]} --domain ${params.domain} --domain-owner ${account}`);
});
}
}
}

class SSMParametersFeature extends BuildProjectFeature {

constructor(pipeline: BuildSpecPipeline) {
Expand Down Expand Up @@ -229,11 +184,23 @@ export class BuildSpecPipeline extends Construct {
Object.defineProperty(this.buildSpec.phases.pre_build, 'commands', { value: [] });
}

if (!this.buildSpec.phases.post_build) {
Object.defineProperty(this.buildSpec.phases, 'post_build', { value: {} });
}

if (!this.buildSpec.phases.post_build.commands) {
Object.defineProperty(this.buildSpec.phases.post_build, 'commands', { value: [] });
}

this.features.forEach(feature => {
this.buildSpec.phases.pre_build.commands = [
...feature.preBuildCommands,
...this.buildSpec.phases.pre_build.commands,
];
this.buildSpec.phases.post_build.commands = [
...feature.postBuildCommands,
...this.buildSpec.phases.post_build.commands,
];
});

const buildProject = new PipelineProject(this, 'PipelineProject', {
Expand Down
89 changes: 89 additions & 0 deletions src/features/codeArtifact.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { Effect, PolicyStatement } from '@aws-cdk/aws-iam';
import { Stack } from '@aws-cdk/core';
import { BuildSpecPipeline } from '../BuildSpecPipeline';
import { BuildProjectFeature } from './core';

function stamp(template: string, params: Record<string, string>) {
// @ts-ignore
const { domain, repo, account } = params;
return eval('`'+template+'`');
}

const toolTemplate: Record<string, Record<string, Array<any>>> = {
'npm': {
preBuild: [
'aws codeartifact login --tool npm --domain ${domain} --repository ${repo} --domain-owner ${account}',
],
},
'jsii-npm': {
postBuild: [
'export NPM_REGISTRY=\\`aws codeartifact get-repository-endpoint --domain ${domain} --repository ${repo} --format npm --query repositoryEndpoint --output text\\`',
'export NPM_TOKEN=$CODEARTIFACT_AUTH_TOKEN',
],
},
'pip': {
preBuild: ['aws codeartifact login --tool pip --domain ${domain} --repository ${repo} --domain-owner ${account}'],
},
'jsii-twine': {
postBuild: [
'export TWINE_REPOSITORY_URL=\\`aws codeartifact get-repository-endpoint --domain ${domain} --repository ${repo} --format pypi --query repositoryEndpoint --output text\\`',
'export TWINE_USERNAME=aws',
'export TWINE_PASSWORD=$CODEARTIFACT_AUTH_TOKEN',
],
},
};

export interface CodeArtifactFeatureProps {
readonly domain: string;
readonly repos: Record<string, string>;
}

export class CodeArtifactFeature extends BuildProjectFeature {

constructor(pipeline: BuildSpecPipeline) {

super();

const params: CodeArtifactFeatureProps = pipeline.buildSpec.env?.['code-artifact'];

if (params?.domain && params?.repos) {

const region = Stack.of(pipeline).region;
const account = Stack.of(pipeline).account;
const domain = params.domain;

this.policyStatements.push(new PolicyStatement({
actions: ['codeartifact:*'],
resources: [
`arn:aws:codeartifact:${region}:${account}:domain/${params.domain}`,
`arn:aws:codeartifact:${region}:${account}:package/${params.domain}/*`,
`arn:aws:codeartifact:${region}:${account}:repository/${params.domain}/*`,
],
effect: Effect.ALLOW,
}));

this.policyStatements.push(new PolicyStatement({
actions: ['sts:GetServiceBearerToken'],
resources: ['*'],
effect: Effect.ALLOW,
conditions: {
StringEquals: {
'sts:AWSServiceName': 'codeartifact.amazonaws.com',
},
},
}));

this.preBuildCommands.push(
`export CODEARTIFACT_AUTH_TOKEN=\`aws codeartifact get-authorization-token --domain ${domain} --query authorizationToken --output text\``,
);

Object.keys(params.repos).forEach(repo => {
Object.values(params.repos[repo]).forEach(tool => {
toolTemplate[tool]?.preBuild?.forEach(t => this.preBuildCommands.push(stamp(t, { domain, repo, account })));
toolTemplate[tool]?.postBuild?.forEach(t => this.postBuildCommands.push(stamp(t, { domain, repo, account })));
});
});
}
}
}

7 changes: 7 additions & 0 deletions src/features/core.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { PolicyStatement } from '@aws-cdk/aws-iam';

export class BuildProjectFeature {
readonly policyStatements: Array<PolicyStatement> = [];
readonly preBuildCommands: Array<string> = [];
readonly postBuildCommands: Array<string> = [];
}
3 changes: 3 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
export * from './BuildSpecPipeline';
export * from './CustomExtensionPipeline';
export { CodeArtifactFeature } from './features/codeArtifact';
export { CodeArtifactFeatureProps } from './features/codeArtifact';
export { BuildProjectFeature } from './features/core';
1 change: 0 additions & 1 deletion src/integ.default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ const stack = new Stack(app, 'tts-cdk-pipelines-integration-test');

new BuildSpecPipeline(stack, 'BuildPipelineWithProjectName', {
projectName: 'tts-cdk-pipelines',
// codeArtifactDomain: 'tts',
});

0 comments on commit 246fc85

Please sign in to comment.