projen-pipelines 0.2.11 → 0.2.13

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.
@@ -0,0 +1,106 @@
1
+ import { IVersionInfo, GitInfoInput, DeploymentInfoInput } from './types';
2
+ /**
3
+ * Represents complete version information for a deployment
4
+ */
5
+ export declare class VersionInfo implements IVersionInfo {
6
+ /**
7
+ * Create a VersionInfo instance from raw data
8
+ */
9
+ static create(props: IVersionInfo): VersionInfo;
10
+ /**
11
+ * Create a VersionInfo instance from environment variables
12
+ */
13
+ static fromEnvironment(env: {
14
+ [key: string]: string;
15
+ }): VersionInfo;
16
+ /**
17
+ * Create a VersionInfo instance from a JSON string
18
+ */
19
+ static fromJson(json: string): VersionInfo;
20
+ readonly version: string;
21
+ readonly commitHash: string;
22
+ readonly commitHashShort: string;
23
+ readonly branch: string;
24
+ readonly tag?: string;
25
+ readonly commitsSinceTag?: number;
26
+ readonly commitCount: number;
27
+ readonly packageVersion?: string;
28
+ readonly deployedAt: string;
29
+ readonly deployedBy: string;
30
+ readonly buildNumber?: string;
31
+ readonly environment: string;
32
+ readonly repository?: string;
33
+ readonly pipelineVersion?: string;
34
+ private constructor();
35
+ /**
36
+ * Convert to plain version string
37
+ */
38
+ toString(): string;
39
+ /**
40
+ * Convert to JSON string
41
+ */
42
+ toJson(pretty?: boolean): string;
43
+ /**
44
+ * Convert to object
45
+ */
46
+ toObject(): IVersionInfo;
47
+ /**
48
+ * Get formatted version for display
49
+ */
50
+ displayVersion(): string;
51
+ /**
52
+ * Check if this version is from a tagged release
53
+ */
54
+ taggedRelease(): boolean;
55
+ /**
56
+ * Check if this version is from the main branch
57
+ */
58
+ mainBranch(): boolean;
59
+ /**
60
+ * Compare with another version
61
+ * Returns: -1 if this < other, 0 if equal, 1 if this > other
62
+ */
63
+ compare(other: VersionInfo): number;
64
+ /**
65
+ * Create a parameter name for SSM Parameter Store
66
+ */
67
+ parameterName(template: string): string;
68
+ /**
69
+ * Create CloudFormation export name
70
+ */
71
+ exportName(template: string): string;
72
+ }
73
+ /**
74
+ * Builder class for creating VersionInfo instances
75
+ */
76
+ export declare class VersionInfoBuilder {
77
+ private props;
78
+ /**
79
+ * Set the version string
80
+ */
81
+ version(version: string): this;
82
+ /**
83
+ * Set git information
84
+ */
85
+ gitInfo(info: GitInfoInput): this;
86
+ /**
87
+ * Set package version
88
+ */
89
+ packageVersion(version: string): this;
90
+ /**
91
+ * Set deployment metadata
92
+ */
93
+ deploymentInfo(info: DeploymentInfoInput): this;
94
+ /**
95
+ * Set repository information
96
+ */
97
+ repository(repo: string): this;
98
+ /**
99
+ * Set pipeline version
100
+ */
101
+ pipelineVersion(version: string): this;
102
+ /**
103
+ * Build the VersionInfo instance
104
+ */
105
+ create(): VersionInfo;
106
+ }
@@ -0,0 +1,269 @@
1
+ "use strict";
2
+ var _a, _b;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.VersionInfoBuilder = exports.VersionInfo = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ /**
7
+ * Represents complete version information for a deployment
8
+ */
9
+ class VersionInfo {
10
+ /**
11
+ * Create a VersionInfo instance from raw data
12
+ */
13
+ static create(props) {
14
+ return new VersionInfo(props);
15
+ }
16
+ /**
17
+ * Create a VersionInfo instance from environment variables
18
+ */
19
+ static fromEnvironment(env) {
20
+ const commitHash = env.GITHUB_SHA || env.GIT_COMMIT_HASH || '';
21
+ const commitHashShort = commitHash.substring(0, 8);
22
+ const props = {
23
+ version: env.VERSION || '0.0.0',
24
+ commitHash,
25
+ commitHashShort,
26
+ branch: env.GIT_BRANCH || env.GITHUB_REF_NAME || 'unknown',
27
+ commitCount: parseInt(env.GIT_COMMIT_COUNT || '0', 10),
28
+ deployedAt: new Date().toISOString(),
29
+ deployedBy: env.GITHUB_ACTOR || env.GITLAB_USER_LOGIN || env.USER || 'unknown',
30
+ environment: env.STAGE || env.ENVIRONMENT || 'unknown',
31
+ };
32
+ // Add optional fields only if they exist
33
+ if (env.GIT_TAG)
34
+ props.tag = env.GIT_TAG;
35
+ if (env.COMMITS_SINCE_TAG)
36
+ props.commitsSinceTag = parseInt(env.COMMITS_SINCE_TAG, 10);
37
+ if (env.PACKAGE_VERSION)
38
+ props.packageVersion = env.PACKAGE_VERSION;
39
+ if (env.GITHUB_RUN_NUMBER)
40
+ props.buildNumber = env.GITHUB_RUN_NUMBER;
41
+ else if (env.CI_PIPELINE_ID)
42
+ props.buildNumber = env.CI_PIPELINE_ID;
43
+ if (env.GITHUB_REPOSITORY)
44
+ props.repository = env.GITHUB_REPOSITORY;
45
+ else if (env.CI_PROJECT_PATH)
46
+ props.repository = env.CI_PROJECT_PATH;
47
+ if (env.PIPELINE_VERSION)
48
+ props.pipelineVersion = env.PIPELINE_VERSION;
49
+ return new VersionInfo(props);
50
+ }
51
+ /**
52
+ * Create a VersionInfo instance from a JSON string
53
+ */
54
+ static fromJson(json) {
55
+ const data = JSON.parse(json);
56
+ return new VersionInfo(data);
57
+ }
58
+ constructor(props) {
59
+ this.version = props.version;
60
+ this.commitHash = props.commitHash;
61
+ this.commitHashShort = props.commitHashShort;
62
+ this.branch = props.branch;
63
+ this.tag = props.tag;
64
+ this.commitsSinceTag = props.commitsSinceTag;
65
+ this.commitCount = props.commitCount;
66
+ this.packageVersion = props.packageVersion;
67
+ this.deployedAt = props.deployedAt;
68
+ this.deployedBy = props.deployedBy;
69
+ this.buildNumber = props.buildNumber;
70
+ this.environment = props.environment;
71
+ this.repository = props.repository;
72
+ this.pipelineVersion = props.pipelineVersion;
73
+ }
74
+ /**
75
+ * Convert to plain version string
76
+ */
77
+ toString() {
78
+ return this.version;
79
+ }
80
+ /**
81
+ * Convert to JSON string
82
+ */
83
+ toJson(pretty = false) {
84
+ const data = {
85
+ version: this.version,
86
+ commitHash: this.commitHash,
87
+ commitHashShort: this.commitHashShort,
88
+ branch: this.branch,
89
+ commitCount: this.commitCount,
90
+ deployedAt: this.deployedAt,
91
+ deployedBy: this.deployedBy,
92
+ environment: this.environment,
93
+ };
94
+ if (this.tag !== undefined)
95
+ data.tag = this.tag;
96
+ if (this.commitsSinceTag !== undefined)
97
+ data.commitsSinceTag = this.commitsSinceTag;
98
+ if (this.packageVersion !== undefined)
99
+ data.packageVersion = this.packageVersion;
100
+ if (this.buildNumber !== undefined)
101
+ data.buildNumber = this.buildNumber;
102
+ if (this.repository !== undefined)
103
+ data.repository = this.repository;
104
+ if (this.pipelineVersion !== undefined)
105
+ data.pipelineVersion = this.pipelineVersion;
106
+ return pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
107
+ }
108
+ /**
109
+ * Convert to object
110
+ */
111
+ toObject() {
112
+ return JSON.parse(this.toJson());
113
+ }
114
+ /**
115
+ * Get formatted version for display
116
+ */
117
+ displayVersion() {
118
+ if (this.tag && this.commitsSinceTag === 0) {
119
+ return this.tag;
120
+ }
121
+ return this.version;
122
+ }
123
+ /**
124
+ * Check if this version is from a tagged release
125
+ */
126
+ taggedRelease() {
127
+ return this.tag !== undefined && this.commitsSinceTag === 0;
128
+ }
129
+ /**
130
+ * Check if this version is from the main branch
131
+ */
132
+ mainBranch() {
133
+ return this.branch === 'main' || this.branch === 'master';
134
+ }
135
+ /**
136
+ * Compare with another version
137
+ * Returns: -1 if this < other, 0 if equal, 1 if this > other
138
+ */
139
+ compare(other) {
140
+ // First compare by commit count
141
+ if (this.commitCount < other.commitCount)
142
+ return -1;
143
+ if (this.commitCount > other.commitCount)
144
+ return 1;
145
+ // Then by version string
146
+ return this.version.localeCompare(other.version);
147
+ }
148
+ /**
149
+ * Create a parameter name for SSM Parameter Store
150
+ */
151
+ parameterName(template) {
152
+ return template
153
+ .replace('{stage}', this.environment)
154
+ .replace('{environment}', this.environment)
155
+ .replace('{branch}', this.branch)
156
+ .replace('{version}', this.version);
157
+ }
158
+ /**
159
+ * Create CloudFormation export name
160
+ */
161
+ exportName(template) {
162
+ return template
163
+ .replace('{stage}', this.environment)
164
+ .replace('{environment}', this.environment)
165
+ .replace('{branch}', this.branch)
166
+ .replace('{version}', this.version);
167
+ }
168
+ }
169
+ exports.VersionInfo = VersionInfo;
170
+ _a = JSII_RTTI_SYMBOL_1;
171
+ VersionInfo[_a] = { fqn: "projen-pipelines.VersionInfo", version: "0.2.13" };
172
+ /**
173
+ * Builder class for creating VersionInfo instances
174
+ */
175
+ class VersionInfoBuilder {
176
+ constructor() {
177
+ this.props = {};
178
+ }
179
+ /**
180
+ * Set the version string
181
+ */
182
+ version(version) {
183
+ this.props.version = version;
184
+ return this;
185
+ }
186
+ /**
187
+ * Set git information
188
+ */
189
+ gitInfo(info) {
190
+ this.props.commitHash = info.commitHash;
191
+ this.props.commitHashShort = info.commitHash.substring(0, 8);
192
+ this.props.branch = info.branch;
193
+ this.props.tag = info.tag;
194
+ this.props.commitsSinceTag = info.commitsSinceTag;
195
+ this.props.commitCount = info.commitCount;
196
+ return this;
197
+ }
198
+ /**
199
+ * Set package version
200
+ */
201
+ packageVersion(version) {
202
+ this.props.packageVersion = version;
203
+ return this;
204
+ }
205
+ /**
206
+ * Set deployment metadata
207
+ */
208
+ deploymentInfo(info) {
209
+ this.props.environment = info.environment;
210
+ this.props.deployedBy = info.deployedBy ?? 'unknown';
211
+ this.props.buildNumber = info.buildNumber;
212
+ this.props.deployedAt = new Date().toISOString();
213
+ return this;
214
+ }
215
+ /**
216
+ * Set repository information
217
+ */
218
+ repository(repo) {
219
+ this.props.repository = repo;
220
+ return this;
221
+ }
222
+ /**
223
+ * Set pipeline version
224
+ */
225
+ pipelineVersion(version) {
226
+ this.props.pipelineVersion = version;
227
+ return this;
228
+ }
229
+ /**
230
+ * Build the VersionInfo instance
231
+ */
232
+ create() {
233
+ if (!this.props.version) {
234
+ throw new Error('Version is required');
235
+ }
236
+ if (!this.props.commitHash) {
237
+ throw new Error('Commit hash is required');
238
+ }
239
+ if (!this.props.branch) {
240
+ throw new Error('Branch is required');
241
+ }
242
+ if (this.props.commitCount === undefined) {
243
+ throw new Error('Commit count is required');
244
+ }
245
+ if (!this.props.environment) {
246
+ throw new Error('Environment is required');
247
+ }
248
+ return VersionInfo.create({
249
+ version: this.props.version,
250
+ commitHash: this.props.commitHash,
251
+ commitHashShort: this.props.commitHashShort,
252
+ branch: this.props.branch,
253
+ tag: this.props.tag,
254
+ commitsSinceTag: this.props.commitsSinceTag,
255
+ commitCount: this.props.commitCount,
256
+ packageVersion: this.props.packageVersion,
257
+ deployedAt: this.props.deployedAt ?? new Date().toISOString(),
258
+ deployedBy: this.props.deployedBy ?? 'unknown',
259
+ buildNumber: this.props.buildNumber,
260
+ environment: this.props.environment,
261
+ repository: this.props.repository,
262
+ pipelineVersion: this.props.pipelineVersion,
263
+ });
264
+ }
265
+ }
266
+ exports.VersionInfoBuilder = VersionInfoBuilder;
267
+ _b = JSII_RTTI_SYMBOL_1;
268
+ VersionInfoBuilder[_b] = { fqn: "projen-pipelines.VersionInfoBuilder", version: "0.2.13" };
269
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi1pbmZvLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3ZlcnNpb25pbmcvdmVyc2lvbi1pbmZvLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBbUJBOztHQUVHO0FBQ0gsTUFBYSxXQUFXO0lBRXRCOztPQUVHO0lBQ0ksTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFtQjtRQUN0QyxPQUFPLElBQUksV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7T0FFRztJQUNJLE1BQU0sQ0FBQyxlQUFlLENBQUMsR0FBOEI7UUFDMUQsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDLFVBQVUsSUFBSSxHQUFHLENBQUMsZUFBZSxJQUFJLEVBQUUsQ0FBQztRQUMvRCxNQUFNLGVBQWUsR0FBRyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUVuRCxNQUFNLEtBQUssR0FBdUI7WUFDaEMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxPQUFPLElBQUksT0FBTztZQUMvQixVQUFVO1lBQ1YsZUFBZTtZQUNmLE1BQU0sRUFBRSxHQUFHLENBQUMsVUFBVSxJQUFJLEdBQUcsQ0FBQyxlQUFlLElBQUksU0FBUztZQUMxRCxXQUFXLEVBQUUsUUFBUSxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsSUFBSSxHQUFHLEVBQUUsRUFBRSxDQUFDO1lBQ3RELFVBQVUsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRTtZQUNwQyxVQUFVLEVBQUUsR0FBRyxDQUFDLFlBQVksSUFBSSxHQUFHLENBQUMsaUJBQWlCLElBQUksR0FBRyxDQUFDLElBQUksSUFBSSxTQUFTO1lBQzlFLFdBQVcsRUFBRSxHQUFHLENBQUMsS0FBSyxJQUFJLEdBQUcsQ0FBQyxXQUFXLElBQUksU0FBUztTQUN2RCxDQUFDO1FBRUYseUNBQXlDO1FBQ3pDLElBQUksR0FBRyxDQUFDLE9BQU87WUFBRSxLQUFLLENBQUMs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SSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDNUIsTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1FBQzdDLENBQUM7UUFFRCxPQUFPLFdBQVcsQ0FBQyxNQUFNLENBQUM7WUFDeEIsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTztZQUMzQixVQUFVLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVO1lBQ2pDLGVBQWUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWdCO1lBQzVDLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU07WUFDekIsR0FBRyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRztZQUNuQixlQUFlLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlO1lBQzNDLFdBQVcsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVc7WUFDbkMsY0FBYyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYztZQUN6QyxVQUFVLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLElBQUksSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUU7WUFDN0QsVUFBVSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxJQUFJLFNBQVM7WUFDOUMsV0FBVyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVztZQUNuQyxXQUFXLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXO1lBQ25DLFVBQVUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVU7WUFDakMsZUFBZSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZTtTQUM1QyxDQUFDLENBQUM7SUFDTCxDQUFDOztBQS9GSCxnREFnR0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJVmVyc2lvbkluZm8sIEdpdEluZm9JbnB1dCwgRGVwbG95bWVudEluZm9JbnB1dCB9IGZyb20gJy4vdHlwZXMnO1xuXG5cbmludGVyZmFjZSBNdXRhYmxlVmVyc2lvbkluZm8ge1xuICB2ZXJzaW9uPzogc3RyaW5nO1xuICBjb21taXRIYXNoPzogc3RyaW5nO1xuICBjb21taXRIYXNoU2hvcnQ/OiBzdHJpbmc7XG4gIGJyYW5jaD86IHN0cmluZztcbiAgdGFnPzogc3RyaW5nO1xuICBjb21taXRzU2luY2VUYWc/OiBudW1iZXI7XG4gIGNvbW1pdENvdW50PzogbnVtYmVyO1xuICBwYWNrYWdlVmVyc2lvbj86IHN0cmluZztcbiAgZGVwbG95ZWRBdD86IHN0cmluZztcbiAgZGVwbG95ZWRCeT86IHN0cmluZztcbiAgYnVpbGROdW1iZXI/OiBzdHJpbmc7XG4gIGVudmlyb25tZW50Pzogc3RyaW5nO1xuICByZXBvc2l0b3J5Pzogc3RyaW5nO1xuICBwaXBlbGluZVZlcnNpb24/OiBzdHJpbmc7XG59XG4vKipcbiAqIFJlcHJlc2VudHMgY29tcGxldGUgdmVyc2lvbiBpbmZvcm1hdGlvbiBmb3IgYSBkZXBsb3ltZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBWZXJzaW9uSW5mbyBpbXBsZW1lbnRzIElWZXJzaW9uSW5mbyB7XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIFZlcnNpb25JbmZvIGluc3RhbmNlIGZyb20gcmF3IGRhdGFcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY3JlYXRlKHByb3BzOiBJVmVyc2lvbkluZm8pOiBWZXJzaW9uSW5mbyB7XG4gICAgcmV0dXJuIG5ldyBWZXJzaW9uSW5mbyhwcm9wcyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgVmVyc2lvbkluZm8gaW5zdGFuY2UgZnJvbSBlbnZpcm9ubWVudCB2YXJpYWJsZXNcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbUVudmlyb25tZW50KGVudjogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSk6IFZlcnNpb25JbmZvIHtcbiAgICBjb25zdCBjb21taXRIYXNoID0gZW52LkdJVEhVQl9TSEEgfHwgZW52LkdJVF9DT01NSVRfSEFTSCB8fCAnJztcbiAgICBjb25zdCBjb21taXRIYXNoU2hvcnQgPSBjb21taXRIYXNoLnN1YnN0cmluZygwLCA4KTtcblxuICAgIGNvbnN0IHByb3BzOiBNdXRhYmxlVmVyc2lvbkluZm8gPSB7XG4gICAgICB2ZXJzaW9uOiBlbnYuVkVSU0lPTiB8fCAnMC4wLjAnLFxuICAgICAgY29tbWl0SGFzaCxcbiAgICAgIGNvbW1pdEhhc2hTaG9ydCxcbiAgICAgIGJyYW5jaDogZW52LkdJVF9CUkFOQ0ggfHwgZW52LkdJVEhVQl9SRUZfTkFNRSB8fCAndW5rbm93bicsXG4gICAgICBjb21taXRDb3VudDogcGFyc2VJbnQoZW52LkdJVF9DT01NSVRfQ09VTlQgfHwgJzAnLCAxMCksXG4gICAgICBkZXBsb3llZEF0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICBkZXBsb3llZEJ5OiBlbnYuR0lUSFVCX0FDVE9SIHx8IGVudi5HSVRMQUJfVVNFUl9MT0dJTiB8fCBlbnYuVVNFUiB8fCAndW5rbm93bicsXG4gICAgICBlbnZpcm9ubWVudDogZW52LlNUQUdFIHx8IGVudi5FTlZJUk9OTUVOVCB8fCAndW5rbm93bicsXG4gICAgfTtcblxuICAgIC8vIEFkZCBvcHRpb25hbCBmaWVsZHMgb25seSBpZiB0aGV5IGV4aXN0XG4gICAgaWYgKGVudi5HSVRfVEFHKSBwcm9wcy50YWcgPSBlbnYuR0lUX1RBRztcbiAgICBpZiAoZW52LkNPTU1JVFNfU0lOQ0VfVEFHKSBwcm9wcy5jb21taXRzU2luY2VUYWcgPSBwYXJzZUludChlbnYuQ09NTUlUU19TSU5DRV9UQUcsIDEwKTtcbiAgICBpZiAoZW52LlBBQ0tBR0VfVkVSU0lPTikgcHJvcHMucGFja2FnZVZlcnNpb24gPSBlbnYuUEFDS0FHRV9WRVJTSU9OO1xuICAgIGlmIChlbnYuR0lUSFVCX1JVTl9OVU1CRVIpIHByb3BzLmJ1aWxkTnVtYmVyID0gZW52LkdJVEhVQl9SVU5fTlVNQkVSO1xuICAgIGVsc2UgaWYgKGVudi5DSV9QSVBFTElORV9JRCkgcHJvcHMuYnVpbGROdW1iZXIgPSBlbnYuQ0lfUElQRUxJTkVfSUQ7XG4gICAgaWYgKGVudi5HSVRIVUJfUkVQT1NJVE9SWSkgcHJvcHMucmVwb3NpdG9yeSA9IGVudi5HSVRIVUJfUkVQT1NJVE9SWTtcbiAgICBlbHNlIGlmIChlbnYuQ0lfUFJPSkVDVF9QQVRIKSBwcm9wcy5yZXBvc2l0b3J5ID0gZW52LkNJX1BST0pFQ1RfUEFUSDtcbiAgICBpZiAoZW52LlBJUEVMSU5FX1ZFUlNJT04pIHByb3BzLnBpcGVsaW5lVmVyc2lvbiA9IGVudi5QSVBFTElORV9WRVJTSU9OO1xuXG4gICAgcmV0dXJuIG5ldyBWZXJzaW9uSW5mbyhwcm9wcyBhcyBJVmVyc2lvbkluZm8pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIFZlcnNpb25JbmZvIGluc3RhbmNlIGZyb20gYSBKU09OIHN0cmluZ1xuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmcm9tSnNvbihqc29uOiBzdHJpbmcpOiBWZXJzaW9uSW5mbyB7XG4gICAgY29uc3QgZGF0YSA9IEpTT04ucGFyc2UoanNvbik7XG4gICAgcmV0dXJuIG5ldyBWZXJzaW9uSW5mbyhkYXRhKTtcbiAgfVxuXG4gIHB1YmxpYyByZWFkb25seSB2ZXJzaW9uOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBjb21taXRIYXNoOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBjb21taXRIYXNoU2hvcnQ6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGJyYW5jaDogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgdGFnPzogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgY29tbWl0c1NpbmNlVGFnPzogbnVtYmVyO1xuICBwdWJsaWMgcmVhZG9ubHkgY29tbWl0Q291bnQ6IG51bWJlcjtcbiAgcHVibGljIHJlYWRvbmx5IHBhY2thZ2VWZXJzaW9uPzogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgZGVwbG95ZWRBdDogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgZGVwbG95ZWRCeTogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgYnVpbGROdW1iZXI/OiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBlbnZpcm9ubWVudDogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgcmVwb3NpdG9yeT86IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IHBpcGVsaW5lVmVyc2lvbj86IHN0cmluZztcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKHByb3BzOiBJVmVyc2lvbkluZm8pIHtcbiAgICB0aGlzLnZlcnNpb24gPSBwcm9wcy52ZXJzaW9uO1xuICAgIHRoaXMuY29tbWl0SGFzaCA9IHByb3BzLmNvbW1pdEhhc2g7XG4gICAgdGhpcy5jb21taXRIYXNoU2hvcnQgPSBwcm9wcy5jb21taXRIYXNoU2hvcnQ7XG4gICAgdGhpcy5icmFuY2ggPSBwcm9wcy5icmFuY2g7XG4gICAgdGhpcy50YWcgPSBwcm9wcy50YWc7XG4gICAgdGhpcy5jb21taXRzU2luY2VUYWcgPSBwcm9wcy5jb21taXRzU2luY2VUYWc7XG4gICAgdGhpcy5jb21taXRDb3VudCA9IHByb3BzLmNvbW1pdENvdW50O1xuICAgIHRoaXMucGFja2FnZVZlcnNpb24gPSBwcm9wcy5wYWNrYWdlVmVyc2lvbjtcbiAgICB0aGlzLmRlcGxveWVkQXQgPSBwcm9wcy5kZXBsb3llZEF0O1xuICAgIHRoaXMuZGVwbG95ZWRCeSA9IHByb3BzLmRlcGxveWVkQnk7XG4gICAgdGhpcy5idWlsZE51bWJlciA9IHByb3BzLmJ1aWxkTnVtYmVyO1xuICAgIHRoaXMuZW52aXJvbm1lbnQgPSBwcm9wcy5lbnZpcm9ubWVudDtcbiAgICB0aGlzLnJlcG9zaXRvcnkgPSBwcm9wcy5yZXBvc2l0b3J5O1xuICAgIHRoaXMucGlwZWxpbmVWZXJzaW9uID0gcHJvcHMucGlwZWxpbmVWZXJzaW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgdG8gcGxhaW4gdmVyc2lvbiBzdHJpbmdcbiAgICovXG4gIHB1YmxpYyB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnZlcnNpb247XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydCB0byBKU09OIHN0cmluZ1xuICAgKi9cbiAgcHVibGljIHRvSnNvbihwcmV0dHkgPSBmYWxzZSk6IHN0cmluZyB7XG4gICAgY29uc3QgZGF0YTogTXV0YWJsZVZlcnNpb25JbmZvID0ge1xuICAgICAgdmVyc2lvbjogdGhpcy52ZXJzaW9uLFxuICAgICAgY29tbWl0SGFzaDogdGhpcy5jb21taXRIYXNoLFxuICAgICAgY29tbWl0SGFzaFNob3J0OiB0aGlzLmNvbW1pdEhhc2hTaG9ydCxcbiAgICAgIGJyYW5jaDogdGhpcy5icmFuY2gsXG4gICAgICBjb21taXRDb3VudDogdGhpcy5jb21taXRDb3VudCxcbiAgICAgIGRlcGxveWVkQXQ6IHRoaXMuZGVwbG95ZWRBdCxcbiAgICAgIGRlcGxveWVkQnk6IHRoaXMuZGVwbG95ZWRCeSxcbiAgICAgIGVudmlyb25tZW50OiB0aGlzLmVudmlyb25tZW50LFxuICAgIH07XG5cbiAgICBpZiAodGhpcy50YWcgIT09IHVuZGVmaW5lZCkgZGF0YS50YWcgPSB0aGlzLnRhZztcbiAgICBpZiAodGhpcy5jb21taXRzU2luY2VUYWcgIT09IHVuZGVmaW5lZCkgZGF0YS5jb21taXRzU2luY2VUYWcgPSB0aGlzLmNvbW1pdHNTaW5jZVRhZztcbiAgICBpZiAodGhpcy5wYWNrYWdlVmVyc2lvbiAhPT0gdW5kZWZpbmVkKSBkYXRhLnBhY2thZ2VWZXJzaW9uID0gdGhpcy5wYWNrYWdlVmVyc2lvbjtcbiAgICBpZiAodGhpcy5idWlsZE51bWJlciAhPT0gdW5kZWZpbmVkKSBkYXRhLmJ1aWxkTnVtYmVyID0gdGhpcy5idWlsZE51bWJlcjtcbiAgICBpZiAodGhpcy5yZXBvc2l0b3J5ICE9PSB1bmRlZmluZWQpIGRhdGEucmVwb3NpdG9yeSA9IHRoaXMucmVwb3NpdG9yeTtcbiAgICBpZiAodGhpcy5waXBlbGluZVZlcnNpb24gIT09IHVuZGVmaW5lZCkgZGF0YS5waXBlbGluZVZlcnNpb24gPSB0aGlzLnBpcGVsaW5lVmVyc2lvbjtcblxuICAgIHJldHVybiBwcmV0dHkgPyBKU09OLnN0cmluZ2lmeShkYXRhLCBudWxsLCAyKSA6IEpTT04uc3RyaW5naWZ5KGRhdGEpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnQgdG8gb2JqZWN0XG4gICAqL1xuICBwdWJsaWMgdG9PYmplY3QoKTogSVZlcnNpb25JbmZvIHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZSh0aGlzLnRvSnNvbigpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZm9ybWF0dGVkIHZlcnNpb24gZm9yIGRpc3BsYXlcbiAgICovXG4gIHB1YmxpYyBkaXNwbGF5VmVyc2lvbigpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLnRhZyAmJiB0aGlzLmNvbW1pdHNTaW5jZVRhZyA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRoaXMudGFnO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy52ZXJzaW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIHRoaXMgdmVyc2lvbiBpcyBmcm9tIGEgdGFnZ2VkIHJlbGVhc2VcbiAgICovXG4gIHB1YmxpYyB0YWdnZWRSZWxlYXNlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnRhZyAhPT0gdW5kZWZpbmVkICYmIHRoaXMuY29tbWl0c1NpbmNlVGFnID09PSAwO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIHRoaXMgdmVyc2lvbiBpcyBmcm9tIHRoZSBtYWluIGJyYW5jaFxuICAgKi9cbiAgcHVibGljIG1haW5CcmFuY2goKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuYnJhbmNoID09PSAnbWFpbicgfHwgdGhpcy5icmFuY2ggPT09ICdtYXN0ZXInO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXBhcmUgd2l0aCBhbm90aGVyIHZlcnNpb25cbiAgICogUmV0dXJuczogLTEgaWYgdGhpcyA8IG90aGVyLCAwIGlmIGVxdWFsLCAxIGlmIHRoaXMgPiBvdGhlclxuICAgKi9cbiAgcHVibGljIGNvbXBhcmUob3RoZXI6IFZlcnNpb25JbmZvKTogbnVtYmVyIHtcbiAgICAvLyBGaXJzdCBjb21wYXJlIGJ5IGNvbW1pdCBjb3VudFxuICAgIGlmICh0aGlzLmNvbW1pdENvdW50IDwgb3RoZXIuY29tbWl0Q291bnQpIHJldHVybiAtMTtcbiAgICBpZiAodGhpcy5jb21taXRDb3VudCA+IG90aGVyLmNvbW1pdENvdW50KSByZXR1cm4gMTtcblxuICAgIC8vIFRoZW4gYnkgdmVyc2lvbiBzdHJpbmdcbiAgICByZXR1cm4gdGhpcy52ZXJzaW9uLmxvY2FsZUNvbXBhcmUob3RoZXIudmVyc2lvbik7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgcGFyYW1ldGVyIG5hbWUgZm9yIFNTTSBQYXJhbWV0ZXIgU3RvcmVcbiAgICovXG4gIHB1YmxpYyBwYXJhbWV0ZXJOYW1lKHRlbXBsYXRlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB0ZW1wbGF0ZVxuICAgICAgLnJlcGxhY2UoJ3tzdGFnZX0nLCB0aGlzLmVudmlyb25tZW50KVxuICAgICAgLnJlcGxhY2UoJ3tlbnZpcm9ubWVudH0nLCB0aGlzLmVudmlyb25tZW50KVxuICAgICAgLnJlcGxhY2UoJ3ticmFuY2h9JywgdGhpcy5icmFuY2gpXG4gICAgICAucmVwbGFjZSgne3ZlcnNpb259JywgdGhpcy52ZXJzaW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgQ2xvdWRGb3JtYXRpb24gZXhwb3J0IG5hbWVcbiAgICovXG4gIHB1YmxpYyBleHBvcnROYW1lKHRlbXBsYXRlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB0ZW1wbGF0ZVxuICAgICAgLnJlcGxhY2UoJ3tzdGFnZX0nLCB0aGlzLmVudmlyb25tZW50KVxuICAgICAgLnJlcGxhY2UoJ3tlbnZpcm9ubWVudH0nLCB0aGlzLmVudmlyb25tZW50KVxuICAgICAgLnJlcGxhY2UoJ3ticmFuY2h9JywgdGhpcy5icmFuY2gpXG4gICAgICAucmVwbGFjZSgne3ZlcnNpb259JywgdGhpcy52ZXJzaW9uKTtcbiAgfVxufVxuXG4vKipcbiAqIEJ1aWxkZXIgY2xhc3MgZm9yIGNyZWF0aW5nIFZlcnNpb25JbmZvIGluc3RhbmNlc1xuICovXG5leHBvcnQgY2xhc3MgVmVyc2lvbkluZm9CdWlsZGVyIHtcbiAgcHJpdmF0ZSBwcm9wczogTXV0YWJsZVZlcnNpb25JbmZvID0ge307XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgdmVyc2lvbiBzdHJpbmdcbiAgICovXG4gIHB1YmxpYyB2ZXJzaW9uKHZlcnNpb246IHN0cmluZyk6IHRoaXMge1xuICAgIHRoaXMucHJvcHMudmVyc2lvbiA9IHZlcnNpb247XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogU2V0IGdpdCBpbmZvcm1hdGlvblxuICAgKi9cbiAgcHVibGljIGdpdEluZm8oaW5mbzogR2l0SW5mb0lucHV0KTogdGhpcyB7XG4gICAgdGhpcy5wcm9wcy5jb21taXRIYXNoID0gaW5mby5jb21taXRIYXNoO1xuICAgIHRoaXMucHJvcHMuY29tbWl0SGFzaFNob3J0ID0gaW5mby5jb21taXRIYXNoLnN1YnN0cmluZygwLCA4KTtcbiAgICB0aGlzLnByb3BzLmJyYW5jaCA9IGluZm8uYnJhbmNoO1xuICAgIHRoaXMucHJvcHMudGFnID0gaW5mby50YWc7XG4gICAgdGhpcy5wcm9wcy5jb21taXRzU2luY2VUYWcgPSBpbmZvLmNvbW1pdHNTaW5jZVRhZztcbiAgICB0aGlzLnByb3BzLmNvbW1pdENvdW50ID0gaW5mby5jb21taXRDb3VudDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgcGFja2FnZSB2ZXJzaW9uXG4gICAqL1xuICBwdWJsaWMgcGFja2FnZVZlcnNpb24odmVyc2lvbjogc3RyaW5nKTogdGhpcyB7XG4gICAgdGhpcy5wcm9wcy5wYWNrYWdlVmVyc2lvbiA9IHZlcnNpb247XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogU2V0IGRlcGxveW1lbnQgbWV0YWRhdGFcbiAgICovXG4gIHB1YmxpYyBkZXBsb3ltZW50SW5mbyhpbmZvOiBEZXBsb3ltZW50SW5mb0lucHV0KTogdGhpcyB7XG4gICAgdGhpcy5wcm9wcy5lbnZpcm9ubWVudCA9IGluZm8uZW52aXJvbm1lbnQ7XG4gICAgdGhpcy5wcm9wcy5kZXBsb3llZEJ5ID0gaW5mby5kZXBsb3llZEJ5ID8/ICd1bmtub3duJztcbiAgICB0aGlzLnByb3BzLmJ1aWxkTnVtYmVyID0gaW5mby5idWlsZE51bWJlcjtcbiAgICB0aGlzLnByb3BzLmRlcGxveWVkQXQgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHJlcG9zaXRvcnkgaW5mb3JtYXRpb25cbiAgICovXG4gIHB1YmxpYyByZXBvc2l0b3J5KHJlcG86IHN0cmluZyk6IHRoaXMge1xuICAgIHRoaXMucHJvcHMucmVwb3NpdG9yeSA9IHJlcG87XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHBpcGVsaW5lIHZlcnNpb25cbiAgICovXG4gIHB1YmxpYyBwaXBlbGluZVZlcnNpb24odmVyc2lvbjogc3RyaW5nKTogdGhpcyB7XG4gICAgdGhpcy5wcm9wcy5waXBlbGluZVZlcnNpb24gPSB2ZXJzaW9uO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIHRoZSBWZXJzaW9uSW5mbyBpbnN0YW5jZVxuICAgKi9cbiAgcHVibGljIGNyZWF0ZSgpOiBWZXJzaW9uSW5mbyB7XG4gICAgaWYgKCF0aGlzLnByb3BzLnZlcnNpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVmVyc2lvbiBpcyByZXF1aXJlZCcpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMucHJvcHMuY29tbWl0SGFzaCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb21taXQgaGFzaCBpcyByZXF1aXJlZCcpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMucHJvcHMuYnJhbmNoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0JyYW5jaCBpcyByZXF1aXJlZCcpO1xuICAgIH1cbiAgICBpZiAodGhpcy5wcm9wcy5jb21taXRDb3VudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbW1pdCBjb3VudCBpcyByZXF1aXJlZCcpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMucHJvcHMuZW52aXJvbm1lbnQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRW52aXJvbm1lbnQgaXMgcmVxdWlyZWQnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gVmVyc2lvbkluZm8uY3JlYXRlKHtcbiAgICAgIHZlcnNpb246IHRoaXMucHJvcHMudmVyc2lvbixcbiAgICAgIGNvbW1pdEhhc2g6IHRoaXMucHJvcHMuY29tbWl0SGFzaCxcbiAgICAgIGNvbW1pdEhhc2hTaG9ydDogdGhpcy5wcm9wcy5jb21taXRIYXNoU2hvcnQhLFxuICAgICAgYnJhbmNoOiB0aGlzLnByb3BzLmJyYW5jaCxcbiAgICAgIHRhZzogdGhpcy5wcm9wcy50YWcsXG4gICAgICBjb21taXRzU2luY2VUYWc6IHRoaXMucHJvcHMuY29tbWl0c1NpbmNlVGFnLFxuICAgICAgY29tbWl0Q291bnQ6IHRoaXMucHJvcHMuY29tbWl0Q291bnQsXG4gICAgICBwYWNrYWdlVmVyc2lvbjogdGhpcy5wcm9wcy5wYWNrYWdlVmVyc2lvbixcbiAgICAgIGRlcGxveWVkQXQ6IHRoaXMucHJvcHMuZGVwbG95ZWRBdCA/PyBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICBkZXBsb3llZEJ5OiB0aGlzLnByb3BzLmRlcGxveWVkQnkgPz8gJ3Vua25vd24nLFxuICAgICAgYnVpbGROdW1iZXI6IHRoaXMucHJvcHMuYnVpbGROdW1iZXIsXG4gICAgICBlbnZpcm9ubWVudDogdGhpcy5wcm9wcy5lbnZpcm9ubWVudCxcbiAgICAgIHJlcG9zaXRvcnk6IHRoaXMucHJvcHMucmVwb3NpdG9yeSxcbiAgICAgIHBpcGVsaW5lVmVyc2lvbjogdGhpcy5wcm9wcy5waXBlbGluZVZlcnNpb24sXG4gICAgfSk7XG4gIH1cbn0iXX0=
package/llm.md CHANGED
@@ -44,9 +44,10 @@ For AWS CDK applications, the library provides:
44
44
 
45
45
  - `CDKPipeline` (abstract base class)
46
46
  - Platform-specific implementations (e.g., `GithubCDKPipeline`)
47
- - Support for multi-stage deployments (dev, prod, personal)
47
+ - Support for multi-stage deployments (dev, prod, personal, feature)
48
48
  - Asset publishing and versioning
49
49
  - Automated CloudFormation deployment
50
+ - Feature branch deployments with automatic lifecycle management
50
51
 
51
52
  ## Usage Example
52
53
 
@@ -128,6 +129,7 @@ When creating a CDK pipeline, these are key configuration options:
128
129
  | `pkgNamespace` | Namespace for published packages |
129
130
  | `stages` | Array of deployment stages with environment settings |
130
131
  | `useGithubPackagesForAssembly` | Use GitHub Packages for assembly storage |
132
+ | `featureStages` | Configuration for feature branch deployments |
131
133
 
132
134
  ## Deployment Stages
133
135
 
@@ -186,6 +188,26 @@ The CDK pipeline adds these tasks to your projen project:
186
188
  | `bump` | Bump version based on git tags |
187
189
  | `release:push-assembly` | Publish cloud assembly to registry |
188
190
 
191
+ ## Feature Branch Deployments
192
+
193
+ When `featureStages` is configured, the library creates automated workflows for feature branch lifecycle management:
194
+
195
+ ### GitHub Actions Implementation
196
+
197
+ - **deploy-feature workflow**: Triggered when a PR is labeled with 'feature-deployment'
198
+ - **destroy-feature workflow**: Triggered when PR is closed or 'feature-deployment' label is removed
199
+ - Uses branch name in stack naming for isolation
200
+
201
+ ### Configuration Example
202
+
203
+ ```typescript
204
+ {
205
+ featureStages: {
206
+ env: { account: '123456789013', region: 'eu-central-1' }
207
+ }
208
+ }
209
+ ```
210
+
189
211
  ## Best Practices
190
212
 
191
213
  1. **IAM Role Setup**: Create minimal permission IAM roles for deployment
package/package.json CHANGED
@@ -83,7 +83,7 @@
83
83
  "publishConfig": {
84
84
  "access": "public"
85
85
  },
86
- "version": "0.2.11",
86
+ "version": "0.2.13",
87
87
  "jest": {
88
88
  "coverageProvider": "v8",
89
89
  "testMatch": [