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.
- package/.jsii +5051 -1445
- package/API.md +3366 -457
- package/README.md +270 -0
- package/lib/assign-approver/base.js +1 -1
- package/lib/assign-approver/github.js +1 -1
- package/lib/awscdk/base.d.ts +21 -0
- package/lib/awscdk/base.js +247 -3
- package/lib/awscdk/bash.js +1 -1
- package/lib/awscdk/github.d.ts +12 -0
- package/lib/awscdk/github.js +117 -2
- package/lib/awscdk/gitlab.d.ts +1 -0
- package/lib/awscdk/gitlab.js +8 -2
- package/lib/index.d.ts +1 -0
- package/lib/index.js +2 -1
- package/lib/steps/artifact-steps.js +2 -2
- package/lib/steps/aws-assume-role.step.js +1 -1
- package/lib/steps/registries.js +2 -2
- package/lib/steps/step.js +4 -4
- package/lib/versioning/computation.d.ts +63 -0
- package/lib/versioning/computation.js +121 -0
- package/lib/versioning/config.d.ts +41 -0
- package/lib/versioning/config.js +91 -0
- package/lib/versioning/index.d.ts +7 -0
- package/lib/versioning/index.js +46 -0
- package/lib/versioning/outputs.d.ts +87 -0
- package/lib/versioning/outputs.js +166 -0
- package/lib/versioning/setup.d.ts +30 -0
- package/lib/versioning/setup.js +165 -0
- package/lib/versioning/strategy.d.ts +21 -0
- package/lib/versioning/strategy.js +51 -0
- package/lib/versioning/types.d.ts +183 -0
- package/lib/versioning/types.js +3 -0
- package/lib/versioning/version-info.d.ts +106 -0
- package/lib/versioning/version-info.js +269 -0
- package/llm.md +23 -1
- package/package.json +1 -1
|
@@ -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
|