@flit/cdk-pipeline 1.0.24 → 1.0.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flit/cdk-pipeline",
3
- "version": "1.0.24",
3
+ "version": "1.0.26",
4
4
  "description": "A highly customizable and extensible CI/CD pipeline intended as alternative to CDK's native CodePipeline",
5
5
  "keywords": [
6
6
  "aws",
@@ -36,21 +36,16 @@
36
36
  "prepack": "jsii"
37
37
  },
38
38
  "devDependencies": {
39
- "@types/node": "^20.10.6",
40
- "aws-cdk": "^2.118.0",
41
- "aws-cdk-lib": "2.118.0",
42
- "cdk-aws-lambda-powertools-layer": "^3.7.0",
43
- "constructs": "10.3.0",
44
- "jest": "^29.7.0",
45
- "jsii": "^5.3.2",
46
- "jsii-pacmak": "^1.93.0",
47
- "ts-jest": "^29.1.1",
48
- "ts-node": "^10.9.2",
49
- "typescript": "^5.3.3"
39
+ "@types/node": "^22.7.7",
40
+ "aws-cdk-lib": "2.162.1",
41
+ "constructs": "10.4.2",
42
+ "jsii": "^5.5.4",
43
+ "jsii-pacmak": "^1.104.0",
44
+ "typescript": "^5.6.3"
50
45
  },
51
46
  "peerDependencies": {
52
- "aws-cdk-lib": "^2.118.0",
53
- "constructs": "^10.3.0"
47
+ "aws-cdk-lib": "2.162.1",
48
+ "constructs": "10.4.2"
54
49
  },
55
50
  "publishConfig": {
56
51
  "access": "public"
@@ -83,9 +78,5 @@
83
78
  }
84
79
  }
85
80
  },
86
- "stability": "stable",
87
- "typedocOptions": {
88
- "entryPoints": "./src/index.ts",
89
- "readme": "./TYPEDOC.md"
90
- }
81
+ "stability": "stable"
91
82
  }
@@ -1,9 +1,24 @@
1
- import { BuildEnvironmentVariable } from "aws-cdk-lib/aws-codebuild";
1
+ import {
2
+ BuildEnvironmentVariable,
3
+ BuildSpec,
4
+ mergeBuildSpecs,
5
+ Project,
6
+ ProjectProps,
7
+ } from "aws-cdk-lib/aws-codebuild";
8
+ import { Stack } from "aws-cdk-lib";
9
+ import { IAction } from "aws-cdk-lib/aws-codepipeline";
10
+ import {
11
+ CloudFormationCreateReplaceChangeSetAction,
12
+ CloudFormationExecuteChangeSetAction,
13
+ CodeBuildAction,
14
+ ManualApprovalAction,
15
+ } from "aws-cdk-lib/aws-codepipeline-actions";
16
+ import * as path from "path";
2
17
 
3
18
  import { Artifact } from "./artifact";
4
19
  import { Segment, SegmentConstructed } from "./segment";
5
- import { StackSegmentConstructed } from "./stack-segment";
6
20
  import { Pipeline } from "./pipeline";
21
+ import { PublishAssetsAction } from "./publish-assets-action";
7
22
 
8
23
  export interface PipelineSegmentProps {
9
24
  /**
@@ -14,7 +29,7 @@ export interface PipelineSegmentProps {
14
29
  * The command(s) to build the stack.
15
30
  * @example "cdk synth StackName --strict --exclusively"
16
31
  */
17
- readonly command: string | string[];
32
+ readonly project: ProjectProps;
18
33
  /**
19
34
  * The environmental variables for the build stage.
20
35
  */
@@ -62,7 +77,7 @@ export class PipelineSegment extends Segment {
62
77
  }
63
78
 
64
79
  construct(scope: Pipeline): SegmentConstructed {
65
- return new StackSegmentConstructed(scope, `Deploy${scope.stackName}`, {
80
+ return new PipelineSegmentConstructed(scope, `Deploy${scope.stackName}`, {
66
81
  ...this.props,
67
82
  stack: scope,
68
83
  input: this.inputs[0],
@@ -70,3 +85,96 @@ export class PipelineSegment extends Segment {
70
85
  });
71
86
  }
72
87
  }
88
+
89
+ export interface PipelineSegmentConstructedProps {
90
+ readonly stack: Stack;
91
+ readonly project: ProjectProps;
92
+ readonly environmentVariables?: { [key: string]: BuildEnvironmentVariable };
93
+ readonly stackName?: string;
94
+ readonly account?: string;
95
+ readonly region?: string;
96
+ readonly input: Artifact;
97
+ readonly extraInputs?: Artifact[];
98
+ readonly output?: Artifact;
99
+ readonly outputFileName?: string;
100
+ readonly manualApproval?: Boolean;
101
+ }
102
+
103
+ export class PipelineSegmentConstructed extends SegmentConstructed {
104
+ readonly name: string;
105
+ readonly actions: IAction[];
106
+
107
+ constructor(
108
+ scope: Pipeline,
109
+ id: string,
110
+ props: PipelineSegmentConstructedProps,
111
+ ) {
112
+ super(scope, id);
113
+
114
+ this.name = props.stack.stackName;
115
+
116
+ const buildArtifact = props.output || new Artifact();
117
+
118
+ this.actions = [
119
+ new CodeBuildAction({
120
+ actionName: "Build",
121
+ runOrder: 1,
122
+ input: props.input,
123
+ extraInputs: props.extraInputs,
124
+ outputs: [buildArtifact],
125
+ environmentVariables: props.environmentVariables,
126
+ project: new Project(this, "UpdateCodeBuild", {
127
+ ...props.project,
128
+ buildSpec: props.project.buildSpec
129
+ ? mergeBuildSpecs(
130
+ props.project.buildSpec,
131
+ BuildSpec.fromObject({
132
+ artifacts: {
133
+ files: [path.join(scope.buildDir, "**/*")],
134
+ },
135
+ }),
136
+ )
137
+ : BuildSpec.fromObject({
138
+ artifacts: {
139
+ files: [path.join(scope.buildDir, "**/*")],
140
+ },
141
+ }),
142
+ }),
143
+ }),
144
+ new PublishAssetsAction(this, "PublishAssets", {
145
+ actionName: "PublishAssets",
146
+ runOrder: 2,
147
+ input: buildArtifact,
148
+ manifestPath: scope.buildDir,
149
+ }),
150
+ new CloudFormationCreateReplaceChangeSetAction({
151
+ actionName: "PrepareChanges",
152
+ runOrder: 3,
153
+ stackName: props.stackName ? props.stackName : props.stack.stackName,
154
+ account: props.account,
155
+ region: props.region,
156
+ changeSetName: `${props.stack.stackName}Changes`,
157
+ adminPermissions: true,
158
+ templatePath: buildArtifact.atPath(
159
+ path.join(scope.buildDir, props.stack.templateFile),
160
+ ),
161
+ }),
162
+ ...(props.manualApproval
163
+ ? [
164
+ new ManualApprovalAction({
165
+ actionName: "ApproveChanges",
166
+ runOrder: 4,
167
+ }),
168
+ ]
169
+ : []),
170
+ new CloudFormationExecuteChangeSetAction({
171
+ actionName: "ExecuteChanges",
172
+ runOrder: props.manualApproval ? 5 : 4,
173
+ stackName: props.stackName ? props.stackName : props.stack.stackName,
174
+ account: props.account,
175
+ region: props.region,
176
+ changeSetName: `${props.stack.stackName}Changes`,
177
+ }),
178
+ ];
179
+ }
180
+ }
package/src/pipeline.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  import { App, Stack, StackProps } from "aws-cdk-lib";
2
2
  import { Construct } from "constructs";
3
- import { Pipeline as AwsPipeline, IAction } from "aws-cdk-lib/aws-codepipeline";
3
+ import {
4
+ Pipeline as AwsPipeline,
5
+ IAction,
6
+ PipelineType,
7
+ } from "aws-cdk-lib/aws-codepipeline";
4
8
  import * as path from "path";
5
9
 
6
10
  import { Artifact } from "./artifact";
@@ -68,6 +72,7 @@ export class Pipeline extends Stack {
68
72
  new AwsPipeline(this, "Pipeline", {
69
73
  pipelineName: props.pipelineName,
70
74
  restartExecutionOnUpdate: true,
75
+ pipelineType: PipelineType.V2,
71
76
  stages: [
72
77
  {
73
78
  stageName: "Source",
@@ -96,10 +96,7 @@ export class PublishAssetsAction extends Construct implements IAction {
96
96
  "runtime-versions": {
97
97
  nodejs: "latest",
98
98
  },
99
- commands: [
100
- "n lts",
101
- "npm i -g npm@latest @flit/publish-cdk-assets@latest",
102
- ],
99
+ commands: ["npm i -g npm@latest @flit/publish-cdk-assets@latest"],
103
100
  },
104
101
  build: {
105
102
  commands: `pca ${
@@ -2,9 +2,9 @@ import { Stack } from "aws-cdk-lib";
2
2
  import {
3
3
  BuildEnvironmentVariable,
4
4
  BuildSpec,
5
- ComputeType,
6
- LinuxBuildImage,
5
+ mergeBuildSpecs,
7
6
  Project,
7
+ ProjectProps,
8
8
  } from "aws-cdk-lib/aws-codebuild";
9
9
  import { IAction } from "aws-cdk-lib/aws-codepipeline";
10
10
  import {
@@ -16,10 +16,10 @@ import {
16
16
  import { IRole } from "aws-cdk-lib/aws-iam";
17
17
  import * as path from "path";
18
18
 
19
- import { PublishAssetsAction } from "./publish-assets-action";
20
19
  import { Artifact } from "./artifact";
21
20
  import { Segment, SegmentConstructed } from "./segment";
22
21
  import { Pipeline } from "./pipeline";
22
+ import { PublishAssetsAction } from "./publish-assets-action";
23
23
 
24
24
  export interface StackSegmentProps {
25
25
  /**
@@ -34,7 +34,7 @@ export interface StackSegmentProps {
34
34
  * The command(s) to build the stack.
35
35
  * @example "cdk synth StackName --strict --exclusively"
36
36
  */
37
- readonly command: string | string[];
37
+ readonly project?: ProjectProps;
38
38
  /**
39
39
  * The role for the build stage.
40
40
  */
@@ -99,7 +99,7 @@ export class StackSegment extends Segment {
99
99
 
100
100
  export interface StackSegmentConstructedProps {
101
101
  readonly stack: Stack;
102
- readonly command: string | string[];
102
+ readonly project?: ProjectProps;
103
103
  readonly environmentVariables?: { [key: string]: BuildEnvironmentVariable };
104
104
  readonly stackName?: string;
105
105
  readonly account?: string;
@@ -124,59 +124,53 @@ export class StackSegmentConstructed extends SegmentConstructed {
124
124
 
125
125
  this.name = props.stack.stackName;
126
126
 
127
- const buildArtifact = new Artifact();
127
+ const buildArtifact = props.project ? new Artifact() : undefined;
128
128
 
129
129
  this.actions = [
130
- new CodeBuildAction({
131
- actionName: "Build",
132
- runOrder: 1,
133
- input: props.input,
134
- extraInputs: props.extraInputs,
135
- outputs: [buildArtifact],
136
- environmentVariables: props.environmentVariables,
137
- project: new Project(this, "UpdateCodeBuild", {
138
- environment: {
139
- computeType: ComputeType.MEDIUM,
140
- buildImage: LinuxBuildImage.AMAZON_LINUX_2_5,
141
- privileged: true,
142
- },
143
- buildSpec: BuildSpec.fromObject({
144
- version: "0.2",
145
- phases: {
146
- install: {
147
- "runtime-versions": {
148
- nodejs: "latest",
149
- },
150
- commands: ["n 18.18.2", "npm i -g npm@latest", "npm ci"],
151
- },
152
- build: {
153
- commands: props.command,
154
- },
155
- },
156
- artifacts: {
157
- files: [path.join(scope.buildDir, "**/*")],
158
- },
159
- cache: {
160
- paths: ["/root/.npm/**/*"],
161
- },
162
- }),
163
- }),
164
- }),
165
- new PublishAssetsAction(this, "PublishAssets", {
166
- actionName: "PublishAssets",
167
- runOrder: 2,
168
- input: buildArtifact,
169
- manifestPath: scope.buildDir,
170
- }),
130
+ ...(buildArtifact
131
+ ? [
132
+ new CodeBuildAction({
133
+ actionName: "Build",
134
+ runOrder: 1,
135
+ input: props.input,
136
+ extraInputs: props.extraInputs,
137
+ outputs: [buildArtifact],
138
+ environmentVariables: props.environmentVariables,
139
+ project: new Project(this, "UpdateCodeBuild", {
140
+ ...props.project,
141
+ buildSpec: props.project?.buildSpec
142
+ ? mergeBuildSpecs(
143
+ props.project.buildSpec,
144
+ BuildSpec.fromObject({
145
+ artifacts: {
146
+ files: [path.join(scope.buildDir, "**/*")],
147
+ },
148
+ }),
149
+ )
150
+ : BuildSpec.fromObject({
151
+ artifacts: {
152
+ files: [path.join(scope.buildDir, "**/*")],
153
+ },
154
+ }),
155
+ }),
156
+ }),
157
+ new PublishAssetsAction(this, "PublishAssets", {
158
+ actionName: "PublishAssets",
159
+ runOrder: 2,
160
+ input: buildArtifact,
161
+ manifestPath: scope.buildDir,
162
+ }),
163
+ ]
164
+ : []),
171
165
  new CloudFormationCreateReplaceChangeSetAction({
172
166
  actionName: "PrepareChanges",
173
- runOrder: 3,
167
+ runOrder: buildArtifact ? 3 : 1,
174
168
  stackName: props.stackName ? props.stackName : props.stack.stackName,
175
169
  account: props.account,
176
170
  region: props.region,
177
171
  changeSetName: `${props.stack.stackName}Changes`,
178
172
  adminPermissions: true,
179
- templatePath: buildArtifact.atPath(
173
+ templatePath: (buildArtifact ? buildArtifact : props.input).atPath(
180
174
  path.join(scope.buildDir, props.stack.templateFile),
181
175
  ),
182
176
  }),
@@ -184,13 +178,19 @@ export class StackSegmentConstructed extends SegmentConstructed {
184
178
  ? [
185
179
  new ManualApprovalAction({
186
180
  actionName: "ApproveChanges",
187
- runOrder: 4,
181
+ runOrder: buildArtifact ? 4 : 2,
188
182
  }),
189
183
  ]
190
184
  : []),
191
185
  new CloudFormationExecuteChangeSetAction({
192
186
  actionName: "ExecuteChanges",
193
- runOrder: props.manualApproval ? 5 : 4,
187
+ runOrder: props.manualApproval
188
+ ? buildArtifact
189
+ ? 5
190
+ : 3
191
+ : buildArtifact
192
+ ? 4
193
+ : 2,
194
194
  stackName: props.stackName ? props.stackName : props.stack.stackName,
195
195
  account: props.account,
196
196
  region: props.region,