projen-pipelines 0.0.17 → 0.0.18

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.
@@ -1,5 +1,4 @@
1
1
  import { Component, awscdk } from 'projen';
2
- import { BaseEngine, GithubEngineConfig } from './engine';
3
2
  /**
4
3
  * The Environment interface is designed to hold AWS related information
5
4
  * for a specific deployment environment within your infrastructure.
@@ -78,14 +77,6 @@ export interface CDKPipelineOptions {
78
77
  * @default CONTINUOUS_DELIVERY
79
78
  */
80
79
  readonly deploymentType?: DeploymentType;
81
- /**
82
- * This field determines the CI/CD tooling that will be used to run the pipeline. The component
83
- * will render workflows for the given system. Options include GitHub and GitLab.
84
- *
85
- * @default - tries to derive it from the projects configuration
86
- */
87
- readonly engine?: PipelineEngine;
88
- readonly githubConfig?: GithubEngineConfig;
89
80
  readonly preInstallCommands?: string[];
90
81
  readonly preSynthCommands?: string[];
91
82
  readonly postSynthCommands?: string[];
@@ -94,13 +85,17 @@ export interface CDKPipelineOptions {
94
85
  * The CDKPipeline class extends the Component class and sets up the necessary configuration for deploying AWS CDK (Cloud Development Kit) applications across multiple stages.
95
86
  * It also manages tasks such as publishing CDK assets, bumping version based on git tags, and cleaning up conflicting tasks.
96
87
  */
97
- export declare class CDKPipeline extends Component {
98
- private app;
99
- private props;
88
+ export declare abstract class CDKPipeline extends Component {
89
+ protected app: awscdk.AwsCdkTypeScriptApp;
90
+ private baseOptions;
100
91
  readonly stackPrefix: string;
101
- readonly engine: BaseEngine;
102
- constructor(app: awscdk.AwsCdkTypeScriptApp, props: CDKPipelineOptions);
103
- private createSynthStage;
92
+ constructor(app: awscdk.AwsCdkTypeScriptApp, baseOptions: CDKPipelineOptions);
93
+ protected getInstallCommands(): string[];
94
+ protected getInstallPackageCommands(packageName: string, runPreInstallCommands?: boolean): string[];
95
+ protected getSynthCommands(): string[];
96
+ protected getAssetUploadCommands(needsVersionedArtifacts: boolean): string[];
97
+ protected getDeployCommands(stageName: string): string[];
98
+ protected getDiffCommands(stageName: string): string[];
104
99
  /**
105
100
  * This method generates the entry point for the application, including interfaces and classes
106
101
  * necessary to set up the pipeline and define the AWS CDK stacks for different environments.
@@ -0,0 +1,284 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CDKPipeline = exports.DeploymentType = exports.PipelineEngine = void 0;
4
+ const projen_1 = require("projen");
5
+ const common_1 = require("projen/lib/common");
6
+ const javascript_1 = require("projen/lib/javascript");
7
+ /**
8
+ * The CI/CD tooling used to run your pipeline.
9
+ * The component will render workflows for the given system
10
+ */
11
+ var PipelineEngine;
12
+ (function (PipelineEngine) {
13
+ /** Create GitHub actions */
14
+ PipelineEngine[PipelineEngine["GITHUB"] = 0] = "GITHUB";
15
+ /** Create a .gitlab-ci.yaml file */
16
+ PipelineEngine[PipelineEngine["GITLAB"] = 1] = "GITLAB";
17
+ // /** Create AWS CodeCatalyst workflows */
18
+ // CODE_CATALYST,
19
+ })(PipelineEngine || (exports.PipelineEngine = PipelineEngine = {}));
20
+ /**
21
+ * Describes the type of pipeline that will be created
22
+ */
23
+ var DeploymentType;
24
+ (function (DeploymentType) {
25
+ /** Deploy every commit as far as possible; hopefully into production */
26
+ DeploymentType[DeploymentType["CONTINUOUS_DEPLOYMENT"] = 0] = "CONTINUOUS_DEPLOYMENT";
27
+ /** Build every commit and prepare all assets for a later deployment */
28
+ DeploymentType[DeploymentType["CONTINUOUS_DELIVERY"] = 1] = "CONTINUOUS_DELIVERY";
29
+ })(DeploymentType || (exports.DeploymentType = DeploymentType = {}));
30
+ /**
31
+ * The CDKPipeline class extends the Component class and sets up the necessary configuration for deploying AWS CDK (Cloud Development Kit) applications across multiple stages.
32
+ * It also manages tasks such as publishing CDK assets, bumping version based on git tags, and cleaning up conflicting tasks.
33
+ */
34
+ class CDKPipeline extends projen_1.Component {
35
+ constructor(app, baseOptions) {
36
+ var _a, _b, _c;
37
+ super(app);
38
+ this.app = app;
39
+ this.baseOptions = baseOptions;
40
+ // Add development dependencies
41
+ this.app.addDevDeps('@types/standard-version', 'standard-version', 'cdk-assets');
42
+ // this.app.addDeps(
43
+ // );
44
+ this.stackPrefix = (_a = baseOptions.stackPrefix) !== null && _a !== void 0 ? _a : app.name;
45
+ // Removes the compiled cloud assembly before each synth
46
+ (_b = this.project.tasks.tryFind('synth')) === null || _b === void 0 ? void 0 : _b.prependExec(`rm -rf ${this.app.cdkConfig.cdkout}`);
47
+ (_c = this.project.tasks.tryFind('synth:silent')) === null || _c === void 0 ? void 0 : _c.prependExec(`rm -rf ${this.app.cdkConfig.cdkout}`);
48
+ // Remove tasks that might conflict with the pipeline process
49
+ this.project.removeTask('deploy');
50
+ this.project.removeTask('diff');
51
+ this.project.removeTask('destroy');
52
+ this.project.removeTask('watch');
53
+ // Creates different deployment stages
54
+ if (baseOptions.personalStage) {
55
+ this.createPersonalStage();
56
+ }
57
+ if (baseOptions.featureStages) {
58
+ this.createFeatureStage();
59
+ }
60
+ for (const stage of baseOptions.stages) {
61
+ this.createPipelineStage(stage);
62
+ }
63
+ // Creates tasks to handle the release process
64
+ this.createReleaseTasks();
65
+ // Creates a specialized CDK App class
66
+ this.createApplicationEntrypoint();
67
+ }
68
+ getInstallCommands() {
69
+ var _a;
70
+ return [
71
+ ...((_a = this.baseOptions.preInstallCommands) !== null && _a !== void 0 ? _a : []),
72
+ `npx projen ${this.app.package.installCiTask.name}`,
73
+ ];
74
+ }
75
+ getInstallPackageCommands(packageName, runPreInstallCommands = false) {
76
+ var _a;
77
+ const commands = runPreInstallCommands ? (_a = this.baseOptions.preInstallCommands) !== null && _a !== void 0 ? _a : [] : [];
78
+ switch (this.app.package.packageManager) {
79
+ case javascript_1.NodePackageManager.YARN:
80
+ case javascript_1.NodePackageManager.YARN2:
81
+ commands.push(`yarn add ${packageName}`);
82
+ break;
83
+ case javascript_1.NodePackageManager.NPM:
84
+ commands.push(`npm install ${packageName}`);
85
+ break;
86
+ default:
87
+ throw new Error('No install scripts for packageManager: ' + this.app.package.packageManager);
88
+ }
89
+ return commands;
90
+ }
91
+ getSynthCommands() {
92
+ var _a, _b;
93
+ return [
94
+ ...this.getInstallCommands(),
95
+ ...((_a = this.baseOptions.preSynthCommands) !== null && _a !== void 0 ? _a : []),
96
+ 'npx projen build',
97
+ ...((_b = this.baseOptions.postSynthCommands) !== null && _b !== void 0 ? _b : []),
98
+ ];
99
+ }
100
+ getAssetUploadCommands(needsVersionedArtifacts) {
101
+ return [
102
+ ...this.getInstallCommands(),
103
+ 'npx projen publish:assets',
104
+ ...(needsVersionedArtifacts ? [
105
+ 'npx projen bump',
106
+ 'npx projen release:push-assembly',
107
+ ] : []),
108
+ ];
109
+ }
110
+ getDeployCommands(stageName) {
111
+ return [
112
+ `npx projen deploy:${stageName}`,
113
+ ];
114
+ }
115
+ getDiffCommands(stageName) {
116
+ return [
117
+ `npx projen diff:${stageName}`,
118
+ ];
119
+ }
120
+ /**
121
+ * This method generates the entry point for the application, including interfaces and classes
122
+ * necessary to set up the pipeline and define the AWS CDK stacks for different environments.
123
+ */
124
+ createApplicationEntrypoint() {
125
+ let propsCode = '';
126
+ let appCode = '';
127
+ if (this.baseOptions.personalStage) {
128
+ propsCode += ` /** This function will be used to generate a personal stack. */
129
+ providePersonalStack: (app: App, stackId: string, props: PipelineAppStackProps) => Stack;
130
+ `;
131
+ appCode += ` // If the environment variable USER is set and a function is provided for creating a personal stack, it is called with necessary arguments.
132
+ if (props.providePersonalStack && process.env.USER) {
133
+ const stageName = 'personal-' + process.env.USER.toLowerCase().replace(/\\\//g, '-');
134
+ props.providePersonalStack(this, '${this.stackPrefix}-personal', { env: ${JSON.stringify(this.baseOptions.personalStage.env)}, stackName: \`${this.stackPrefix}-\${stageName}\`, stageName });
135
+ }
136
+ `;
137
+ }
138
+ if (this.baseOptions.featureStages) {
139
+ propsCode += ` /** This function will be used to generate a feature stack. */
140
+ provideFeatureStack: (app: App, stackId: string, props: PipelineAppStackProps) => Stack;
141
+ `;
142
+ appCode += ` // If the environment variable BRANCH is set and a function is provided for creating a feature stack, it is called with necessary arguments.
143
+ if (props.provideFeatureStack && process.env.BRANCH) {
144
+ const stageName = 'feature-' + process.env.BRANCH.toLowerCase().replace(/\\\//g, '-');
145
+ props.provideFeatureStack(this, '${this.stackPrefix}-feature', { env: ${JSON.stringify(this.baseOptions.featureStages.env)}, stackName: \`${this.stackPrefix}-\${stageName}\`, stageName });
146
+ }
147
+ `;
148
+ }
149
+ for (const stage of this.baseOptions.stages) {
150
+ const nameUpperFirst = `${stage.name.charAt(0).toUpperCase()}${stage.name.substring(1)}`;
151
+ propsCode += ` /** This function will be used to generate a ${stage.name} stack. */
152
+ provide${nameUpperFirst}Stack: (app: App, stackId: string, props: PipelineAppStackProps) => Stack;
153
+ `;
154
+ appCode += ` // If a function is provided for creating a ${stage.name} stack, it is called with necessary arguments.
155
+ if (props.provide${nameUpperFirst}Stack) {
156
+ props.provide${nameUpperFirst}Stack(this, '${this.stackPrefix}-${stage.name}', { env: ${JSON.stringify(stage.env)}, stackName: '${this.stackPrefix}-${stage.name}', stageName: '${stage.name}' });
157
+ }
158
+ `;
159
+ }
160
+ const appFile = new projen_1.TextFile(this.project, `${this.app.srcdir}/app.ts`);
161
+ appFile.addLine(`// ${common_1.PROJEN_MARKER}
162
+ /* eslint-disable */
163
+ import { App, AppProps, Stack, StackProps } from 'aws-cdk-lib';
164
+
165
+ /**
166
+ * PipelineAppProps is an extension of AppProps, which is part of the AWS CDK core.
167
+ * It includes optional functions to provide AWS Stacks for different stages.
168
+ *
169
+ * Use these functions to instantiate your application stacks with the parameters for
170
+ * each stage
171
+ */
172
+ export interface PipelineAppProps extends AppProps {
173
+ ${propsCode}
174
+ }
175
+
176
+ /**
177
+ * PipelineAppStackProps is an extension of StackProps, which is part of the AWS CDK core.
178
+ * It includes an additional property to specify the stage name.
179
+ */
180
+ export interface PipelineAppStackProps extends StackProps {
181
+ stageName: string;
182
+ }
183
+
184
+ /**
185
+ * The PipelineApp class extends the App class from AWS CDK and overrides the constructor to support
186
+ * different stages of the application (development, production, personal, feature) by invoking the provided
187
+ * stack-providing functions from the props.
188
+ */
189
+ export class PipelineApp extends App {
190
+ constructor(props: PipelineAppProps) {
191
+ super(props);
192
+
193
+ ${appCode}
194
+
195
+ }
196
+ }
197
+ `);
198
+ }
199
+ /**
200
+ * This method sets up tasks to publish CDK assets to all accounts and handle versioning, including bumping the version
201
+ * based on the latest git tag and pushing the CDK assembly to the package repository.
202
+ */
203
+ createReleaseTasks() {
204
+ // Task to publish the CDK assets to all accounts
205
+ this.project.addTask('publish:assets', {
206
+ steps: this.baseOptions.stages.map(stage => ({
207
+ exec: `npx cdk-assets -p ${this.app.cdkConfig.cdkout}/${this.stackPrefix}-${stage.name}.assets.json publish`,
208
+ })),
209
+ });
210
+ this.project.addTask('bump', {
211
+ description: 'Bumps version based on latest git tag',
212
+ steps: [
213
+ {
214
+ exec: 'pipelines-release bump',
215
+ },
216
+ {
217
+ exec: 'git push --tags',
218
+ },
219
+ ],
220
+ });
221
+ this.project.addTask('release:push-assembly', {
222
+ steps: [
223
+ {
224
+ exec: `pipelines-release create-manifest "${this.app.cdkConfig.cdkout}" "${this.baseOptions.pkgNamespace}"`,
225
+ },
226
+ {
227
+ cwd: this.app.cdkConfig.cdkout,
228
+ exec: 'npm version --no-git-tag-version from-git',
229
+ },
230
+ {
231
+ cwd: this.app.cdkConfig.cdkout,
232
+ exec: 'npm publish',
233
+ },
234
+ ],
235
+ });
236
+ }
237
+ /**
238
+ * This method sets up tasks for the personal deployment stage, including deployment, watching for changes,
239
+ * comparing changes (diff), and destroying the stack when no longer needed.
240
+ */
241
+ createPersonalStage() {
242
+ this.project.addTask('deploy:personal', {
243
+ exec: `cdk deploy ${this.stackPrefix}-personal`,
244
+ });
245
+ this.project.addTask('watch:personal', {
246
+ exec: `cdk deploy --watch --hotswap ${this.stackPrefix}-personal`,
247
+ });
248
+ this.project.addTask('diff:personal', {
249
+ exec: `cdk diff ${this.stackPrefix}-personal`,
250
+ });
251
+ this.project.addTask('destroy:personal', {
252
+ exec: `cdk destroy ${this.stackPrefix}-personal`,
253
+ });
254
+ }
255
+ /**
256
+ * This method sets up tasks for the feature deployment stage, including deployment, comparing changes (diff),
257
+ * and destroying the stack when no longer needed.
258
+ */
259
+ createFeatureStage() {
260
+ this.project.addTask('deploy:feature', {
261
+ exec: `cdk --progress events --require-approval never deploy ${this.stackPrefix}-feature`,
262
+ });
263
+ this.project.addTask('diff:feature', {
264
+ exec: `cdk diff ${this.stackPrefix}-feature`,
265
+ });
266
+ this.project.addTask('destroy:feature', {
267
+ exec: `cdk destroy ${this.stackPrefix}-feature`,
268
+ });
269
+ }
270
+ /**
271
+ * This method sets up tasks for the general pipeline stages (dev, prod), including deployment and comparing changes (diff).
272
+ * @param {DeployStageOptions} stage - The stage to create
273
+ */
274
+ createPipelineStage(stage) {
275
+ this.project.addTask(`deploy:${stage.name}`, {
276
+ exec: `cdk --app ${this.app.cdkConfig.cdkout} --progress events --require-approval never deploy ${this.stackPrefix}-${stage.name}`,
277
+ });
278
+ this.project.addTask(`diff:${stage.name}`, {
279
+ exec: `cdk --app ${this.app.cdkConfig.cdkout} diff ${this.stackPrefix}-${stage.name}`,
280
+ });
281
+ }
282
+ }
283
+ exports.CDKPipeline = CDKPipeline;
284
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hd3NjZGsvYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtQ0FBcUQ7QUFDckQsOENBQWtEO0FBQ2xELHNEQUEyRDtBQXVCM0Q7OztHQUdHO0FBQ0gsSUFBWSxjQU9YO0FBUEQsV0FBWSxjQUFjO0lBQ3hCLDRCQUE0QjtJQUM1Qix1REFBTSxDQUFBO0lBQ04sb0NBQW9DO0lBQ3BDLHVEQUFNLENBQUE7SUFDTiwyQ0FBMkM7SUFDM0MsaUJBQWlCO0FBQ25CLENBQUMsRUFQVyxjQUFjLDhCQUFkLGNBQWMsUUFPekI7QUFFRDs7R0FFRztBQUNILElBQVksY0FLWDtBQUxELFdBQVksY0FBYztJQUN4Qix3RUFBd0U7SUFDeEUscUZBQXFCLENBQUE7SUFDckIsdUVBQXVFO0lBQ3ZFLGlGQUFtQixDQUFBO0FBQ3JCLENBQUMsRUFMVyxjQUFjLDhCQUFkLGNBQWMsUUFLekI7QUF3REQ7OztHQUdHO0FBQ0gsTUFBc0IsV0FBWSxTQUFRLGtCQUFTO0lBSWpELFlBQXNCLEdBQStCLEVBQVUsV0FBK0I7O1FBQzVGLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQURTLFFBQUcsR0FBSCxHQUFHLENBQTRCO1FBQVUsZ0JBQVcsR0FBWCxXQUFXLENBQW9CO1FBRzVGLCtCQUErQjtRQUMvQixJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FDakIseUJBQXlCLEVBQ3pCLGtCQUFrQixFQUNsQixZQUFZLENBQ2IsQ0FBQztRQUNGLG9CQUFvQjtRQUNwQixLQUFLO1FBRUwsSUFBSSxDQUFDLFdBQVcsR0FBRyxNQUFBLFdBQVcsQ0FBQyxXQUFXLG1DQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUM7UUFFdkQsd0RBQXdEO1FBQ3hELE1BQUEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQywwQ0FBRSxXQUFXLENBQUMsVUFBVSxJQUFJLENBQUMs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V0FBVztTQUNqRCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssa0JBQWtCO1FBQ3hCLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLGdCQUFnQixFQUFFO1lBQ3JDLElBQUksRUFBRSx5REFBeUQsSUFBSSxDQUFDLFdBQVcsVUFBVTtTQUMxRixDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUU7WUFDbkMsSUFBSSxFQUFFLFlBQVksSUFBSSxDQUFDLFdBQVcsVUFBVTtTQUM3QyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsRUFBRTtZQUN0QyxJQUFJLEVBQUUsZUFBZSxJQUFJLENBQUMsV0FBVyxVQUFVO1NBQ2hELENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7O09BR0c7SUFDSyxtQkFBbUIsQ0FBQyxLQUFzQjtRQUNoRCxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxVQUFVLEtBQUssQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUMzQyxJQUFJLEVBQUUsYUFBYSxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxNQUFNLHNEQUFzRCxJQUFJLENBQUMsV0FBVyxJQUFJLEtBQUssQ0FBQyxJQUFJLEVBQUU7U0FDbkksQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsUUFBUSxLQUFLLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFDekMsSUFBSSxFQUFFLGFBQWEsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsTUFBTSxTQUFTLElBQUksQ0FBQyxXQUFXLElBQUksS0FBSyxDQUFDLElBQUksRUFBRTtTQUN0RixDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0Y7QUFuUkQsa0NBbVJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBUZXh0RmlsZSwgYXdzY2RrIH0gZnJvbSAncHJvamVuJztcbmltcG9ydCB7IFBST0pFTl9NQVJLRVIgfSBmcm9tICdwcm9qZW4vbGliL2NvbW1vbic7XG5pbXBvcnQgeyBOb2RlUGFja2FnZU1hbmFnZXIgfSBmcm9tICdwcm9qZW4vbGliL2phdmFzY3JpcHQnO1xuXG4vKipcbiAqIFRoZSBFbnZpcm9ubWVudCBpbnRlcmZhY2UgaXMgZGVzaWduZWQgdG8gaG9sZCBBV1MgcmVsYXRlZCBpbmZvcm1hdGlvblxuICogZm9yIGEgc3BlY2lmaWMgZGVwbG95bWVudCBlbnZpcm9ubWVudCB3aXRoaW4geW91ciBpbmZyYXN0cnVjdHVyZS5cbiAqIEVhY2ggZW52aXJvbm1lbnQgcmVxdWlyZXMgYSBzcGVjaWZpYyBhY2NvdW50IGFuZCByZWdpb24gZm9yIGl0cyByZXNvdXJjZXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRW52aXJvbm1lbnQge1xuICAvKipcbiAgICogVGhlIEFXUyBBY2NvdW50IElEIGFzc29jaWF0ZWQgd2l0aCB0aGUgZW52aXJvbm1lbnQuIEl0J3MgaW1wb3J0YW50IGJlY2F1c2VcbiAgICogZGlmZmVyZW50IHNlcnZpY2VzIG9yIGZlYXR1cmVzIGNvdWxkIGhhdmUgZGlzdGluY3QgcGVybWlzc2lvbnMgYW5kIHNldHRpbmdzXG4gICAqIGluIGRpZmZlcmVudCBhY2NvdW50cy5cbiAgICovXG4gIHJlYWRvbmx5IGFjY291bnQ6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIEFXUyBSZWdpb24gZm9yIHRoZSBlbnZpcm9ubWVudC4gVGhpcyBkZXRlcm1pbmVzIHdoZXJlIHlvdXIgcmVzb3VyY2VzXG4gICAqIGFyZSBjcmVhdGVkIGFuZCB3aGVyZSB5b3VyIGFwcGxpY2F0aW9uIHdpbGwgcnVuLiBJdCBjYW4gYWZmZWN0IGxhdGVuY3ksXG4gICAqIGF2YWlsYWJpbGl0eSwgYW5kIHByaWNpbmcuXG4gICAqL1xuICByZWFkb25seSByZWdpb246IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGUgQ0kvQ0QgdG9vbGluZyB1c2VkIHRvIHJ1biB5b3VyIHBpcGVsaW5lLlxuICogVGhlIGNvbXBvbmVudCB3aWxsIHJlbmRlciB3b3JrZmxvd3MgZm9yIHRoZSBnaXZlbiBzeXN0ZW1cbiAqL1xuZXhwb3J0IGVudW0gUGlwZWxpbmVFbmdpbmUge1xuICAvKiogQ3JlYXRlIEdpdEh1YiBhY3Rpb25zICovXG4gIEdJVEhVQixcbiAgLyoqIENyZWF0ZSBhIC5naXRsYWItY2kueWFtbCBmaWxlICovXG4gIEdJVExBQixcbiAgLy8gLyoqIENyZWF0ZSBBV1MgQ29kZUNhdGFseXN0IHdvcmtmbG93cyAqL1xuICAvLyBDT0RFX0NBVEFMWVNULFxufVxuXG4vKipcbiAqIERlc2NyaWJlcyB0aGUgdHlwZSBvZiBwaXBlbGluZSB0aGF0IHdpbGwgYmUgY3JlYXRlZFxuICovXG5leHBvcnQgZW51bSBEZXBsb3ltZW50VHlwZSB7XG4gIC8qKiBEZXBsb3kgZXZlcnkgY29tbWl0IGFzIGZhciBhcyBwb3NzaWJsZTsgaG9wZWZ1bGx5IGludG8gcHJvZHVjdGlvbiAqL1xuICBDT05USU5VT1VTX0RFUExPWU1FTlQsXG4gIC8qKiBCdWlsZCBldmVyeSBjb21taXQgYW5kIHByZXBhcmUgYWxsIGFzc2V0cyBmb3IgYSBsYXRlciBkZXBsb3ltZW50ICovXG4gIENPTlRJTlVPVVNfREVMSVZFUlksXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVwbG95bWVudFN0YWdlIHtcbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICByZWFkb25seSBlbnY6IEVudmlyb25tZW50O1xuICByZWFkb25seSBtYW51YWxBcHByb3ZhbD86IGJvb2xlYW47XG59XG5cbi8qKlxuICogVGhlIENES1BpcGVsaW5lT3B0aW9ucyBpbnRlcmZhY2UgaXMgZGVzaWduZWQgdG8gcHJvdmlkZSBjb25maWd1cmF0aW9uXG4gKiBvcHRpb25zIGZvciBhIENESyAoQ2xvdWQgRGV2ZWxvcG1lbnQgS2l0KSBwaXBlbGluZS4gSXQgYWxsb3dzIHRoZSBkZWZpbml0aW9uXG4gKiBvZiBzZXR0aW5ncyBzdWNoIGFzIHRoZSBzdGFjayBwcmVmaXggYW5kIHBhY2thZ2UgbmFtZXNwYWNlIHRvIGJlIHVzZWQgaW4gdGhlXG4gKiBBV1Mgc3RhY2ssIGFsb25nIHdpdGggdGhlIGVudmlyb25tZW50cyBjb25maWd1cmF0aW9uIHRvIGJlIHVzZWQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ0RLUGlwZWxpbmVPcHRpb25zIHtcblxuICAvKipcbiAgICogVGhpcyBmaWVsZCBpcyB1c2VkIHRvIGRlZmluZSBhIHByZWZpeCBmb3IgdGhlIEFXUyBTdGFjayByZXNvdXJjZXMgY3JlYXRlZFxuICAgKiBkdXJpbmcgdGhlIHBpcGVsaW5lJ3Mgb3BlcmF0aW9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCBwcm9qZWN0IG5hbWVcbiAgICovXG4gIHJlYWRvbmx5IHN0YWNrUHJlZml4Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGlzIGZpZWxkIGRldGVybWluZXMgdGhlIE5QTSBuYW1lc3BhY2UgdG8gYmUgdXNlZCB3aGVuIHBhY2thZ2luZyBDREsgY2xvdWRcbiAgICogYXNzZW1ibGllcy4gQSBuYW1lc3BhY2UgaGVscHMgZ3JvdXAgcmVsYXRlZCByZXNvdXJjZXMgdG9nZXRoZXIsIHByb3ZpZGluZ1xuICAgKiBiZXR0ZXIgb3JnYW5pemF0aW9uIGFuZCBlYXNlIG9mIG1hbmFnZW1lbnQuXG4gICAqL1xuICByZWFkb25seSBwa2dOYW1lc3BhY2U6IHN0cmluZztcblxuICByZWFkb25seSBzdGFnZXM6IERlcGxveW1lbnRTdGFnZVtdO1xuXG4gIHJlYWRvbmx5IHBlcnNvbmFsU3RhZ2U/OiB7XG4gICAgcmVhZG9ubHkgZW52OiBFbnZpcm9ubWVudDtcbiAgfTtcblxuICByZWFkb25seSBmZWF0dXJlU3RhZ2VzPzoge1xuICAgIHJlYWRvbmx5IGVudjogRW52aXJvbm1lbnQ7XG4gIH07XG5cbiAgLyoqXG4gICAqIFRoaXMgZmllbGQgc3BlY2lmaWVzIHRoZSB0eXBlIG9mIHBpcGVsaW5lIHRvIGNyZWF0ZS4gSWYgc2V0IHRvIENPTlRJTlVPVVNfREVQTE9ZTUVOVCxcbiAgICogZXZlcnkgY29tbWl0IGlzIGRlcGxveWVkIGFzIGZhciBhcyBwb3NzaWJsZSwgaG9wZWZ1bGx5IGludG8gcHJvZHVjdGlvbi4gSWYgc2V0IHRvXG4gICAqIENPTlRJTlVPVVNfREVMSVZFUlksIGV2ZXJ5IGNvbW1pdCBpcyBidWlsdCBhbmQgYWxsIGFzc2V0cyBhcmUgcHJlcGFyZWQgZm9yIGEgbGF0ZXIgZGVwbG95bWVudC5cbiAgICpcbiAgICogQGRlZmF1bHQgQ09OVElOVU9VU19ERUxJVkVSWVxuICAgKi9cbiAgcmVhZG9ubHkgZGVwbG95bWVudFR5cGU/OiBEZXBsb3ltZW50VHlwZTtcblxuICByZWFkb25seSBwcmVJbnN0YWxsQ29tbWFuZHM/OiBzdHJpbmdbXTtcbiAgcmVhZG9ubHkgcHJlU3ludGhDb21tYW5kcz86IHN0cmluZ1tdO1xuICByZWFkb25seSBwb3N0U3ludGhDb21tYW5kcz86IHN0cmluZ1tdO1xuXG59XG5cbi8qKlxuICogVGhlIENES1BpcGVsaW5lIGNsYXNzIGV4dGVuZHMgdGhlIENvbXBvbmVudCBjbGFzcyBhbmQgc2V0cyB1cCB0aGUgbmVjZXNzYXJ5IGNvbmZpZ3VyYXRpb24gZm9yIGRlcGxveWluZyBBV1MgQ0RLIChDbG91ZCBEZXZlbG9wbWVudCBLaXQpIGFwcGxpY2F0aW9ucyBhY3Jvc3MgbXVsdGlwbGUgc3RhZ2VzLlxuICogSXQgYWxzbyBtYW5hZ2VzIHRhc2tzIHN1Y2ggYXMgcHVibGlzaGluZyBDREsgYXNzZXRzLCBidW1waW5nIHZlcnNpb24gYmFzZWQgb24gZ2l0IHRhZ3MsIGFuZCBjbGVhbmluZyB1cCBjb25mbGljdGluZyB0YXNrcy5cbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIENES1BpcGVsaW5lIGV4dGVuZHMgQ29tcG9uZW50IHtcblxuICBwdWJsaWMgcmVhZG9ubHkgc3RhY2tQcmVmaXg6IHN0cmluZztcblxuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgYXBwOiBhd3NjZGsuQXdzQ2RrVHlwZVNjcmlwdEFwcCwgcHJpdmF0ZSBiYXNlT3B0aW9uczogQ0RLUGlwZWxpbmVPcHRpb25zKSB7XG4gICAgc3VwZXIoYXBwKTtcblxuICAgIC8vIEFkZCBkZXZlbG9wbWVudCBkZXBlbmRlbmNpZXNcbiAgICB0aGlzLmFwcC5hZGREZXZEZXBzKFxuICAgICAgJ0B0eXBlcy9zdGFuZGFyZC12ZXJzaW9uJyxcbiAgICAgICdzdGFuZGFyZC12ZXJzaW9uJyxcbiAgICAgICdjZGstYXNzZXRzJyxcbiAgICApO1xuICAgIC8vIHRoaXMuYXBwLmFkZERlcHMoXG4gICAgLy8gKTtcblxuICAgIHRoaXMuc3RhY2tQcmVmaXggPSBiYXNlT3B0aW9ucy5zdGFja1ByZWZpeCA/PyBhcHAubmFtZTtcblxuICAgIC8vIFJlbW92ZXMgdGhlIGNvbXBpbGVkIGNsb3VkIGFzc2VtYmx5IGJlZm9yZSBlYWNoIHN5bnRoXG4gICAgdGhpcy5wcm9qZWN0LnRhc2tzLnRyeUZpbmQoJ3N5bnRoJyk/LnByZXBlbmRFeGVjKGBybSAtcmYgJHt0aGlzLmFwcC5jZGtDb25maWcuY2Rrb3V0fWApO1xuICAgIHRoaXMucHJvamVjdC50YXNrcy50cnlGaW5kKCdzeW50aDpzaWxlbnQnKT8ucHJlcGVuZEV4ZWMoYHJtIC1yZiAke3RoaXMuYXBwLmNka0NvbmZpZy5jZGtvdXR9YCk7XG5cbiAgICAvLyBSZW1vdmUgdGFza3MgdGhhdCBtaWdodCBjb25mbGljdCB3aXRoIHRoZSBwaXBlbGluZSBwcm9jZXNzXG4gICAgdGhpcy5wcm9qZWN0LnJlbW92ZVRhc2soJ2RlcGxveScpO1xuICAgIHRoaXMucHJvamVjdC5yZW1vdmVUYXNrKCdkaWZmJyk7XG4gICAgdGhpcy5wcm9qZWN0LnJlbW92ZVRhc2soJ2Rlc3Ryb3knKTtcbiAgICB0aGlzLnByb2plY3QucmVtb3ZlVGFzaygnd2F0Y2gnKTtcblxuICAgIC8vIENyZWF0ZXMgZGlmZmVyZW50IGRlcGxveW1lbnQgc3RhZ2VzXG4gICAgaWYgKGJhc2VPcHRpb25zLnBlcnNvbmFsU3RhZ2UpIHtcbiAgICAgIHRoaXMuY3JlYXRlUGVyc29uYWxTdGFnZSgpO1xuICAgIH1cbiAgICBpZiAoYmFzZU9wdGlvbnMuZmVhdHVyZVN0YWdlcykge1xuICAgICAgdGhpcy5jcmVhdGVGZWF0dXJlU3RhZ2UoKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBzdGFnZSBvZiBiYXNlT3B0aW9ucy5zdGFnZXMpIHtcbiAgICAgIHRoaXMuY3JlYXRlUGlwZWxpbmVTdGFnZShzdGFnZSk7XG4gICAgfVxuXG4gICAgLy8gQ3JlYXRlcyB0YXNrcyB0byBoYW5kbGUgdGhlIHJlbGVhc2UgcHJvY2Vzc1xuICAgIHRoaXMuY3JlYXRlUmVsZWFzZVRhc2tzKCk7XG5cbiAgICAvLyBDcmVhdGVzIGEgc3BlY2lhbGl6ZWQgQ0RLIEFwcCBjbGFzc1xuICAgIHRoaXMuY3JlYXRlQXBwbGljYXRpb25FbnRyeXBvaW50KCk7XG5cbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRJbnN0YWxsQ29tbWFuZHMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBbXG4gICAgICAuLi4odGhpcy5iYXNlT3B0aW9ucy5wcmVJbnN0YWxsQ29tbWFuZHMgPz8gW10pLFxuICAgICAgYG5weCBwcm9qZW4gJHt0aGlzLmFwcC5wYWNrYWdlLmluc3RhbGxDaVRhc2submFtZX1gLFxuICAgIF07XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0SW5zdGFsbFBhY2thZ2VDb21tYW5kcyhwYWNrYWdlTmFtZTogc3RyaW5nLCBydW5QcmVJbnN0YWxsQ29tbWFuZHM6IGJvb2xlYW4gPSBmYWxzZSk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBjb21tYW5kcyA9IHJ1blByZUluc3RhbGxDb21tYW5kcyA/IHRoaXMuYmFzZU9wdGlvbnMucHJlSW5zdGFsbENvbW1hbmRzID8/IFtdIDogW107XG5cbiAgICBzd2l0Y2ggKHRoaXMuYXBwLnBhY2thZ2UucGFja2FnZU1hbmFnZXIpIHtcbiAgICAgIGNhc2UgTm9kZVBhY2thZ2VNYW5hZ2VyLllBUk46XG4gICAgICBjYXNlIE5vZGVQYWNrYWdlTWFuYWdlci5ZQVJOMjpcbiAgICAgICAgY29tbWFuZHMucHVzaChgeWFybiBhZGQgJHtwYWNrYWdlTmFtZX1gKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIE5vZGVQYWNrYWdlTWFuYWdlci5OUE06XG4gICAgICAgIGNvbW1hbmRzLnB1c2goYG5wbSBpbnN0YWxsICR7cGFja2FnZU5hbWV9YCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBpbnN0YWxsIHNjcmlwdHMgZm9yIHBhY2thZ2VNYW5hZ2VyOiAnICsgdGhpcy5hcHAucGFja2FnZS5wYWNrYWdlTWFuYWdlcik7XG4gICAgfVxuICAgIHJldHVybiBjb21tYW5kcztcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRTeW50aENvbW1hbmRzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gW1xuICAgICAgLi4udGhpcy5nZXRJbnN0YWxsQ29tbWFuZHMoKSxcbiAgICAgIC4uLih0aGlzLmJhc2VPcHRpb25zLnByZVN5bnRoQ29tbWFuZHMgPz8gW10pLFxuICAgICAgJ25weCBwcm9qZW4gYnVpbGQnLFxuICAgICAgLi4uKHRoaXMuYmFzZU9wdGlvbnMucG9zdFN5bnRoQ29tbWFuZHMgPz8gW10pLFxuICAgIF07XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0QXNzZXRVcGxvYWRDb21tYW5kcyhuZWVkc1ZlcnNpb25lZEFydGlmYWN0czogYm9vbGVhbik6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gW1xuICAgICAgLi4udGhpcy5nZXRJbnN0YWxsQ29tbWFuZHMoKSxcbiAgICAgICducHggcHJvamVuIHB1Ymxpc2g6YXNzZXRzJyxcbiAgICAgIC4uLihuZWVkc1ZlcnNpb25lZEFydGlmYWN0cyA/IFtcbiAgICAgICAgJ25weCBwcm9qZW4gYnVtcCcsXG4gICAgICAgICducHggcHJvamVuIHJlbGVhc2U6cHVzaC1hc3NlbWJseScsXG4gICAgICBdIDogW10pLFxuICAgIF07XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0RGVwbG95Q29tbWFuZHMoc3RhZ2VOYW1lOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIGBucHggcHJvamVuIGRlcGxveToke3N0YWdlTmFtZX1gLFxuICAgIF07XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0RGlmZkNvbW1hbmRzKHN0YWdlTmFtZTogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBbXG4gICAgICBgbnB4IHByb2plbiBkaWZmOiR7c3RhZ2VOYW1lfWAsXG4gICAgXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBnZW5lcmF0ZXMgdGhlIGVudHJ5IHBvaW50IGZvciB0aGUgYXBwbGljYXRpb24sIGluY2x1ZGluZyBpbnRlcmZhY2VzIGFuZCBjbGFzc2VzXG4gICAqIG5lY2Vzc2FyeSB0byBzZXQgdXAgdGhlIHBpcGVsaW5lIGFuZCBkZWZpbmUgdGhlIEFXUyBDREsgc3RhY2tzIGZvciBkaWZmZXJlbnQgZW52aXJvbm1lbnRzLlxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVBcHBsaWNhdGlvbkVudHJ5cG9pbnQoKSB7XG4gICAgbGV0IHByb3BzQ29kZSA9ICcnO1xuICAgIGxldCBhcHBDb2RlID0gJyc7XG5cbiAgICBpZiAodGhpcy5iYXNlT3B0aW9ucy5wZXJzb25hbFN0YWdlKSB7XG4gICAgICBwcm9wc0NvZGUgKz0gYCAgLyoqIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSB1c2VkIHRvIGdlbmVyYXRlIGEgcGVyc29uYWwgc3RhY2suICovXG4gIHByb3ZpZGVQZXJzb25hbFN0YWNrOiAoYXBwOiBBcHAsIHN0YWNrSWQ6IHN0cmluZywgcHJvcHM6IFBpcGVsaW5lQXBwU3RhY2tQcm9wcykgPT4gU3RhY2s7XG5gO1xuICAgICAgYXBwQ29kZSArPSBgICAgIC8vIElmIHRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZSBVU0VSIGlzIHNldCBhbmQgYSBmdW5jdGlvbiBpcyBwcm92aWRlZCBmb3IgY3JlYXRpbmcgYSBwZXJzb25hbCBzdGFjaywgaXQgaXMgY2FsbGVkIHdpdGggbmVjZXNzYXJ5IGFyZ3VtZW50cy5cbiAgICBpZiAocHJvcHMucHJvdmlkZVBlcnNvbmFsU3RhY2sgJiYgcHJvY2Vzcy5lbnYuVVNFUikge1xuICAgICAgY29uc3Qgc3RhZ2VOYW1lID0gJ3BlcnNvbmFsLScgKyBwcm9jZXNzLmVudi5VU0VSLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvXFxcXFxcLy9nLCAnLScpO1xuICAgICAgcHJvcHMucHJvdmlkZVBlcnNvbmFsU3RhY2sodGhpcywgJyR7dGhpcy5zdGFja1ByZWZpeH0tcGVyc29uYWwnLCB7IGVudjogJHtKU09OLnN0cmluZ2lmeSh0aGlzLmJhc2VPcHRpb25zLnBlcnNvbmFsU3RhZ2UuZW52KX0sIHN0YWNrTmFtZTogXFxgJHt0aGlzLnN0YWNrUHJlZml4fS1cXCR7c3RhZ2VOYW1lfVxcYCwgc3RhZ2VOYW1lIH0pO1xuICAgIH1cbmA7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYmFzZU9wdGlvbnMuZmVhdHVyZVN0YWdlcykge1xuICAgICAgcHJvcHNDb2RlICs9IGAgIC8qKiBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgdXNlZCB0byBnZW5lcmF0ZSBhIGZlYXR1cmUgc3RhY2suICovXG4gIHByb3ZpZGVGZWF0dXJlU3RhY2s6IChhcHA6IEFwcCwgc3RhY2tJZDogc3RyaW5nLCBwcm9wczogUGlwZWxpbmVBcHBTdGFja1Byb3BzKSA9PiBTdGFjaztcbmA7XG4gICAgICBhcHBDb2RlICs9IGAgICAgLy8gSWYgdGhlIGVudmlyb25tZW50IHZhcmlhYmxlIEJSQU5DSCBpcyBzZXQgYW5kIGEgZnVuY3Rpb24gaXMgcHJvdmlkZWQgZm9yIGNyZWF0aW5nIGEgZmVhdHVyZSBzdGFjaywgaXQgaXMgY2FsbGVkIHdpdGggbmVjZXNzYXJ5IGFyZ3VtZW50cy5cbiAgICBpZiAocHJvcHMucHJvdmlkZUZlYXR1cmVTdGFjayAmJiBwcm9jZXNzLmVudi5CUkFOQ0gpIHtcbiAgICAgIGNvbnN0IHN0YWdlTmFtZSA9ICdmZWF0dXJlLScgKyBwcm9jZXNzLmVudi5CUkFOQ0gudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9cXFxcXFwvL2csICctJyk7XG4gICAgICBwcm9wcy5wcm92aWRlRmVhdHVyZVN0YWNrKHRoaXMsICcke3RoaXMuc3RhY2tQcmVmaXh9LWZlYXR1cmUnLCB7IGVudjogJHtKU09OLnN0cmluZ2lmeSh0aGlzLmJhc2VPcHRpb25zLmZlYXR1cmVTdGFnZXMuZW52KX0sIHN0YWNrTmFtZTogXFxgJHt0aGlzLnN0YWNrUHJlZml4fS1cXCR7c3RhZ2VOYW1lfVxcYCwgc3RhZ2VOYW1lIH0pO1xuICAgIH1cbmA7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBzdGFnZSBvZiB0aGlzLmJhc2VPcHRpb25zLnN0YWdlcykge1xuICAgICAgY29uc3QgbmFtZVVwcGVyRmlyc3QgPSBgJHtzdGFnZS5uYW1lLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpfSR7c3RhZ2UubmFtZS5zdWJzdHJpbmcoMSl9YDtcblxuICAgICAgcHJvcHNDb2RlICs9IGAgIC8qKiBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgdXNlZCB0byBnZW5lcmF0ZSBhICR7c3RhZ2UubmFtZX0gc3RhY2suICovXG4gIHByb3ZpZGUke25hbWVVcHBlckZpcnN0fVN0YWNrOiAoYXBwOiBBcHAsIHN0YWNrSWQ6IHN0cmluZywgcHJvcHM6IFBpcGVsaW5lQXBwU3RhY2tQcm9wcykgPT4gU3RhY2s7XG5gO1xuICAgICAgYXBwQ29kZSArPSBgICAgIC8vIElmIGEgZnVuY3Rpb24gaXMgcHJvdmlkZWQgZm9yIGNyZWF0aW5nIGEgJHtzdGFnZS5uYW1lfSBzdGFjaywgaXQgaXMgY2FsbGVkIHdpdGggbmVjZXNzYXJ5IGFyZ3VtZW50cy5cbiAgICBpZiAocHJvcHMucHJvdmlkZSR7bmFtZVVwcGVyRmlyc3R9U3RhY2spIHtcbiAgICAgIHByb3BzLnByb3ZpZGUke25hbWVVcHBlckZpcnN0fVN0YWNrKHRoaXMsICcke3RoaXMuc3RhY2tQcmVmaXh9LSR7c3RhZ2UubmFtZX0nLCB7IGVudjogJHtKU09OLnN0cmluZ2lmeShzdGFnZS5lbnYpfSwgc3RhY2tOYW1lOiAnJHt0aGlzLnN0YWNrUHJlZml4fS0ke3N0YWdlLm5hbWV9Jywgc3RhZ2VOYW1lOiAnJHtzdGFnZS5uYW1lfScgfSk7XG4gICAgfVxuYDtcbiAgICB9XG5cbiAgICBjb25zdCBhcHBGaWxlID0gbmV3IFRleHRGaWxlKHRoaXMucHJvamVjdCwgYCR7dGhpcy5hcHAuc3JjZGlyfS9hcHAudHNgKTtcbiAgICBhcHBGaWxlLmFkZExpbmUoYC8vICR7UFJPSkVOX01BUktFUn1cbi8qIGVzbGludC1kaXNhYmxlICovXG5pbXBvcnQgeyBBcHAsIEFwcFByb3BzLCBTdGFjaywgU3RhY2tQcm9wcyB9IGZyb20gJ2F3cy1jZGstbGliJztcblxuLyoqXG4gKiBQaXBlbGluZUFwcFByb3BzIGlzIGFuIGV4dGVuc2lvbiBvZiBBcHBQcm9wcywgd2hpY2ggaXMgcGFydCBvZiB0aGUgQVdTIENESyBjb3JlLlxuICogSXQgaW5jbHVkZXMgb3B0aW9uYWwgZnVuY3Rpb25zIHRvIHByb3ZpZGUgQVdTIFN0YWNrcyBmb3IgZGlmZmVyZW50IHN0YWdlcy5cbiAqXG4gKiBVc2UgdGhlc2UgZnVuY3Rpb25zIHRvIGluc3RhbnRpYXRlIHlvdXIgYXBwbGljYXRpb24gc3RhY2tzIHdpdGggdGhlIHBhcmFtZXRlcnMgZm9yXG4gKiBlYWNoIHN0YWdlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGlwZWxpbmVBcHBQcm9wcyBleHRlbmRzIEFwcFByb3BzIHtcbiR7cHJvcHNDb2RlfVxufVxuXG4vKipcbiAqIFBpcGVsaW5lQXBwU3RhY2tQcm9wcyBpcyBhbiBleHRlbnNpb24gb2YgU3RhY2tQcm9wcywgd2hpY2ggaXMgcGFydCBvZiB0aGUgQVdTIENESyBjb3JlLlxuICogSXQgaW5jbHVkZXMgYW4gYWRkaXRpb25hbCBwcm9wZXJ0eSB0byBzcGVjaWZ5IHRoZSBzdGFnZSBuYW1lLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBpcGVsaW5lQXBwU3RhY2tQcm9wcyBleHRlbmRzIFN0YWNrUHJvcHMge1xuICBzdGFnZU5hbWU6IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGUgUGlwZWxpbmVBcHAgY2xhc3MgZXh0ZW5kcyB0aGUgQXBwIGNsYXNzIGZyb20gQVdTIENESyBhbmQgb3ZlcnJpZGVzIHRoZSBjb25zdHJ1Y3RvciB0byBzdXBwb3J0XG4gKiBkaWZmZXJlbnQgc3RhZ2VzIG9mIHRoZSBhcHBsaWNhdGlvbiAoZGV2ZWxvcG1lbnQsIHByb2R1Y3Rpb24sIHBlcnNvbmFsLCBmZWF0dXJlKSBieSBpbnZva2luZyB0aGUgcHJvdmlkZWRcbiAqIHN0YWNrLXByb3ZpZGluZyBmdW5jdGlvbnMgZnJvbSB0aGUgcHJvcHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBQaXBlbGluZUFwcCBleHRlbmRzIEFwcCB7XG4gIGNvbnN0cnVjdG9yKHByb3BzOiBQaXBlbGluZUFwcFByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuXG4ke2FwcENvZGV9XG5cbiAgfVxufVxuYCk7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBtZXRob2Qgc2V0cyB1cCB0YXNrcyB0byBwdWJsaXNoIENESyBhc3NldHMgdG8gYWxsIGFjY291bnRzIGFuZCBoYW5kbGUgdmVyc2lvbmluZywgaW5jbHVkaW5nIGJ1bXBpbmcgdGhlIHZlcnNpb25cbiAgICogYmFzZWQgb24gdGhlIGxhdGVzdCBnaXQgdGFnIGFuZCBwdXNoaW5nIHRoZSBDREsgYXNzZW1ibHkgdG8gdGhlIHBhY2thZ2UgcmVwb3NpdG9yeS5cbiAgICovXG4gIHByaXZhdGUgY3JlYXRlUmVsZWFzZVRhc2tzKCkge1xuICAgIC8vIFRhc2sgdG8gcHVibGlzaCB0aGUgQ0RLIGFzc2V0cyB0byBhbGwgYWNjb3VudHNcbiAgICB0aGlzLnByb2plY3QuYWRkVGFzaygncHVibGlzaDphc3NldHMnLCB7XG4gICAgICBzdGVwczogdGhpcy5iYXNlT3B0aW9ucy5zdGFnZXMubWFwKHN0YWdlID0+ICh7XG4gICAgICAgIGV4ZWM6IGBucHggY2RrLWFzc2V0cyAtcCAke3RoaXMuYXBwLmNka0NvbmZpZy5jZGtvdXR9LyR7dGhpcy5zdGFja1ByZWZpeH0tJHtzdGFnZS5uYW1lfS5hc3NldHMuanNvbiBwdWJsaXNoYCxcbiAgICAgIH0pKSxcbiAgICB9KTtcblxuICAgIHRoaXMucHJvamVjdC5hZGRUYXNrKCdidW1wJywge1xuICAgICAgZGVzY3JpcHRpb246ICdCdW1wcyB2ZXJzaW9uIGJhc2VkIG9uIGxhdGVzdCBnaXQgdGFnJyxcbiAgICAgIHN0ZXBzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBleGVjOiAncGlwZWxpbmVzLXJlbGVhc2UgYnVtcCcsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBleGVjOiAnZ2l0IHB1c2ggLS10YWdzJyxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG4gICAgdGhpcy5wcm9qZWN0LmFkZFRhc2soJ3JlbGVhc2U6cHVzaC1hc3NlbWJseScsIHtcbiAgICAgIHN0ZXBzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBleGVjOiBgcGlwZWxpbmVzLXJlbGVhc2UgY3JlYXRlLW1hbmlmZXN0IFwiJHt0aGlzLmFwcC5jZGtDb25maWcuY2Rrb3V0fVwiICBcIiR7dGhpcy5iYXNlT3B0aW9ucy5wa2dOYW1lc3BhY2V9XCJgLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgY3dkOiB0aGlzLmFwcC5jZGtDb25maWcuY2Rrb3V0LFxuICAgICAgICAgIGV4ZWM6ICducG0gdmVyc2lvbiAtLW5vLWdpdC10YWctdmVyc2lvbiBmcm9tLWdpdCcsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBjd2Q6IHRoaXMuYXBwLmNka0NvbmZpZy5jZGtvdXQsXG4gICAgICAgICAgZXhlYzogJ25wbSBwdWJsaXNoJyxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBtZXRob2Qgc2V0cyB1cCB0YXNrcyBmb3IgdGhlIHBlcnNvbmFsIGRlcGxveW1lbnQgc3RhZ2UsIGluY2x1ZGluZyBkZXBsb3ltZW50LCB3YXRjaGluZyBmb3IgY2hhbmdlcyxcbiAgICogY29tcGFyaW5nIGNoYW5nZXMgKGRpZmYpLCBhbmQgZGVzdHJveWluZyB0aGUgc3RhY2sgd2hlbiBubyBsb25nZXIgbmVlZGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVQZXJzb25hbFN0YWdlKCkge1xuICAgIHRoaXMucHJvamVjdC5hZGRUYXNrKCdkZXBsb3k6cGVyc29uYWwnLCB7XG4gICAgICBleGVjOiBgY2RrIGRlcGxveSAke3RoaXMuc3RhY2tQcmVmaXh9LXBlcnNvbmFsYCxcbiAgICB9KTtcbiAgICB0aGlzLnByb2plY3QuYWRkVGFzaygnd2F0Y2g6cGVyc29uYWwnLCB7XG4gICAgICBleGVjOiBgY2RrIGRlcGxveSAtLXdhdGNoIC0taG90c3dhcCAke3RoaXMuc3RhY2tQcmVmaXh9LXBlcnNvbmFsYCxcbiAgICB9KTtcbiAgICB0aGlzLnByb2plY3QuYWRkVGFzaygnZGlmZjpwZXJzb25hbCcsIHtcbiAgICAgIGV4ZWM6IGBjZGsgZGlmZiAke3RoaXMuc3RhY2tQcmVmaXh9LXBlcnNvbmFsYCxcbiAgICB9KTtcbiAgICB0aGlzLnByb2plY3QuYWRkVGFzaygnZGVzdHJveTpwZXJzb25hbCcsIHtcbiAgICAgIGV4ZWM6IGBjZGsgZGVzdHJveSAke3RoaXMuc3RhY2tQcmVmaXh9LXBlcnNvbmFsYCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBzZXRzIHVwIHRhc2tzIGZvciB0aGUgZmVhdHVyZSBkZXBsb3ltZW50IHN0YWdlLCBpbmNsdWRpbmcgZGVwbG95bWVudCwgY29tcGFyaW5nIGNoYW5nZXMgKGRpZmYpLFxuICAgKiBhbmQgZGVzdHJveWluZyB0aGUgc3RhY2sgd2hlbiBubyBsb25nZXIgbmVlZGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVGZWF0dXJlU3RhZ2UoKSB7XG4gICAgdGhpcy5wcm9qZWN0LmFkZFRhc2soJ2RlcGxveTpmZWF0dXJlJywge1xuICAgICAgZXhlYzogYGNkayAtLXByb2dyZXNzIGV2ZW50cyAtLXJlcXVpcmUtYXBwcm92YWwgbmV2ZXIgZGVwbG95ICR7dGhpcy5zdGFja1ByZWZpeH0tZmVhdHVyZWAsXG4gICAgfSk7XG4gICAgdGhpcy5wcm9qZWN0LmFkZFRhc2soJ2RpZmY6ZmVhdHVyZScsIHtcbiAgICAgIGV4ZWM6IGBjZGsgZGlmZiAke3RoaXMuc3RhY2tQcmVmaXh9LWZlYXR1cmVgLFxuICAgIH0pO1xuICAgIHRoaXMucHJvamVjdC5hZGRUYXNrKCdkZXN0cm95OmZlYXR1cmUnLCB7XG4gICAgICBleGVjOiBgY2RrIGRlc3Ryb3kgJHt0aGlzLnN0YWNrUHJlZml4fS1mZWF0dXJlYCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBzZXRzIHVwIHRhc2tzIGZvciB0aGUgZ2VuZXJhbCBwaXBlbGluZSBzdGFnZXMgKGRldiwgcHJvZCksIGluY2x1ZGluZyBkZXBsb3ltZW50IGFuZCBjb21wYXJpbmcgY2hhbmdlcyAoZGlmZikuXG4gICAqIEBwYXJhbSB7RGVwbG95U3RhZ2VPcHRpb25zfSBzdGFnZSAtIFRoZSBzdGFnZSB0byBjcmVhdGVcbiAgICovXG4gIHByaXZhdGUgY3JlYXRlUGlwZWxpbmVTdGFnZShzdGFnZTogRGVwbG95bWVudFN0YWdlKSB7XG4gICAgdGhpcy5wcm9qZWN0LmFkZFRhc2soYGRlcGxveToke3N0YWdlLm5hbWV9YCwge1xuICAgICAgZXhlYzogYGNkayAtLWFwcCAke3RoaXMuYXBwLmNka0NvbmZpZy5jZGtvdXR9IC0tcHJvZ3Jlc3MgZXZlbnRzIC0tcmVxdWlyZS1hcHByb3ZhbCBuZXZlciBkZXBsb3kgJHt0aGlzLnN0YWNrUHJlZml4fS0ke3N0YWdlLm5hbWV9YCxcbiAgICB9KTtcbiAgICB0aGlzLnByb2plY3QuYWRkVGFzayhgZGlmZjoke3N0YWdlLm5hbWV9YCwge1xuICAgICAgZXhlYzogYGNkayAtLWFwcCAke3RoaXMuYXBwLmNka0NvbmZpZy5jZGtvdXR9IGRpZmYgJHt0aGlzLnN0YWNrUHJlZml4fS0ke3N0YWdlLm5hbWV9YCxcbiAgICB9KTtcbiAgfVxufSJdfQ==
@@ -0,0 +1,22 @@
1
+ import { awscdk } from 'projen';
2
+ import { CDKPipeline, CDKPipelineOptions, DeploymentStage } from './base';
3
+ export interface GithubCDKPipelineOptions extends CDKPipelineOptions {
4
+ readonly iamRoleArns: {
5
+ readonly default?: string;
6
+ readonly synth?: string;
7
+ readonly assetPublishing?: string;
8
+ readonly deployment?: {
9
+ [stage: string]: string;
10
+ };
11
+ };
12
+ }
13
+ export declare class GithubCDKPipeline extends CDKPipeline {
14
+ private options;
15
+ readonly needsVersionedArtifacts: boolean;
16
+ private deploymentWorkflow;
17
+ private deploymentStages;
18
+ constructor(app: awscdk.AwsCdkTypeScriptApp, options: GithubCDKPipelineOptions);
19
+ private createSynth;
20
+ createAssetUpload(): void;
21
+ createDeployment(stage: DeploymentStage): void;
22
+ }
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GithubCDKPipeline = void 0;
4
+ const workflows_model_1 = require("projen/lib/github/workflows-model");
5
+ const base_1 = require("./base");
6
+ class GithubCDKPipeline extends base_1.CDKPipeline {
7
+ constructor(app, options) {
8
+ super(app, options);
9
+ this.options = options;
10
+ this.deploymentStages = [];
11
+ this.deploymentWorkflow = this.app.github.addWorkflow('deploy');
12
+ this.deploymentWorkflow.on({
13
+ push: {
14
+ branches: ['main'], // TODO use defaultReleaseBranch
15
+ },
16
+ workflowDispatch: {},
17
+ });
18
+ this.needsVersionedArtifacts = this.options.stages.find(s => s.manualApproval === true) !== undefined;
19
+ this.createSynth();
20
+ this.createAssetUpload();
21
+ for (const stage of options.stages) {
22
+ this.createDeployment(stage);
23
+ }
24
+ }
25
+ createSynth() {
26
+ var _a;
27
+ const steps = [{
28
+ name: 'Checkout',
29
+ uses: 'actions/checkout@v3',
30
+ }];
31
+ if ((_a = this.options.iamRoleArns) === null || _a === void 0 ? void 0 : _a.synth) {
32
+ steps.push({
33
+ name: 'AWS Credentials',
34
+ uses: 'aws-actions/configure-aws-credentials@master',
35
+ with: {
36
+ 'role-to-assume': this.options.iamRoleArns.synth,
37
+ 'role-session-name': 'GitHubAction',
38
+ 'aws-region': 'us-east-1',
39
+ },
40
+ });
41
+ }
42
+ steps.push(...this.getSynthCommands().map(cmd => ({
43
+ run: cmd,
44
+ })));
45
+ steps.push({
46
+ uses: 'actions/upload-artifact@v3',
47
+ with: {
48
+ name: 'cloud-assembly',
49
+ path: `${this.app.cdkConfig.cdkout}/`,
50
+ },
51
+ });
52
+ this.deploymentWorkflow.addJob('synth', {
53
+ name: 'Synth CDK application',
54
+ runsOn: ['ubuntu-latest'],
55
+ env: {
56
+ CI: 'true',
57
+ },
58
+ permissions: { idToken: workflows_model_1.JobPermission.WRITE, contents: workflows_model_1.JobPermission.READ },
59
+ steps,
60
+ });
61
+ }
62
+ createAssetUpload() {
63
+ var _a, _b, _c;
64
+ this.deploymentWorkflow.addJob('assetUpload', {
65
+ name: 'Publish assets to AWS',
66
+ needs: ['synth'],
67
+ runsOn: ['ubuntu-latest'],
68
+ env: {
69
+ CI: 'true',
70
+ },
71
+ permissions: { idToken: workflows_model_1.JobPermission.WRITE, contents: this.needsVersionedArtifacts ? workflows_model_1.JobPermission.WRITE : workflows_model_1.JobPermission.READ },
72
+ steps: [{
73
+ name: 'Checkout',
74
+ uses: 'actions/checkout@v3',
75
+ with: {
76
+ 'fetch-depth': 0,
77
+ },
78
+ }, {
79
+ name: 'Setup GIT identity',
80
+ run: 'git config --global user.name "github-actions" && git config --global user.email "github-actions@github.com"',
81
+ }, {
82
+ name: 'AWS Credentials',
83
+ uses: 'aws-actions/configure-aws-credentials@master',
84
+ with: {
85
+ 'role-to-assume': (_b = (_a = this.options.iamRoleArns) === null || _a === void 0 ? void 0 : _a.assetPublishing) !== null && _b !== void 0 ? _b : (_c = this.options.iamRoleArns) === null || _c === void 0 ? void 0 : _c.default,
86
+ 'role-session-name': 'GitHubAction',
87
+ 'aws-region': 'us-east-1',
88
+ },
89
+ }, {
90
+ uses: 'actions/download-artifact@v3',
91
+ with: {
92
+ name: 'cloud-assembly',
93
+ path: `${this.app.cdkConfig.cdkout}/`,
94
+ },
95
+ },
96
+ ...this.getAssetUploadCommands(this.needsVersionedArtifacts).map(cmd => ({
97
+ run: cmd,
98
+ }))],
99
+ });
100
+ }
101
+ createDeployment(stage) {
102
+ var _a, _b, _c, _d, _e, _f, _g, _h;
103
+ if (stage.manualApproval === true) {
104
+ // Create new workflow for deployment
105
+ const stageWorkflow = this.app.github.addWorkflow(`release-${stage.name}`);
106
+ stageWorkflow.on({
107
+ workflowDispatch: {
108
+ inputs: {
109
+ version: {
110
+ description: 'Package version',
111
+ required: true,
112
+ },
113
+ },
114
+ },
115
+ });
116
+ stageWorkflow.addJob('deploy', {
117
+ name: `Release stage ${stage.name} to AWS`,
118
+ runsOn: ['ubuntu-latest'],
119
+ env: {
120
+ CI: 'true',
121
+ },
122
+ permissions: { idToken: workflows_model_1.JobPermission.WRITE, contents: workflows_model_1.JobPermission.READ },
123
+ steps: [{
124
+ name: 'Checkout',
125
+ uses: 'actions/checkout@v3',
126
+ }, {
127
+ name: 'AWS Credentials',
128
+ uses: 'aws-actions/configure-aws-credentials@master',
129
+ with: {
130
+ 'role-to-assume': (_c = (_b = (_a = this.options.iamRoleArns) === null || _a === void 0 ? void 0 : _a.deployment) === null || _b === void 0 ? void 0 : _b[stage.name]) !== null && _c !== void 0 ? _c : (_d = this.options.iamRoleArns) === null || _d === void 0 ? void 0 : _d.default,
131
+ 'role-session-name': 'GitHubAction',
132
+ 'aws-region': stage.env.region,
133
+ },
134
+ },
135
+ ...this.getInstallCommands().map(cmd => ({
136
+ run: cmd,
137
+ })),
138
+ ...this.getInstallPackageCommands(`${this.options.pkgNamespace}/${this.app.name}@\${{github.event.inputs.version}}`).map(cmd => ({
139
+ run: cmd,
140
+ })),
141
+ {
142
+ run: `mv ./node_modules/${this.options.pkgNamespace}/${this.app.name} ${this.app.cdkConfig.cdkout}`,
143
+ },
144
+ ...this.getDeployCommands(stage.name).map(cmd => ({
145
+ run: cmd,
146
+ }))],
147
+ });
148
+ }
149
+ else {
150
+ // Add deployment to CI/CD workflow
151
+ this.deploymentWorkflow.addJob(`deploy-${stage.name}`, {
152
+ name: `Deploy stage ${stage.name} to AWS`,
153
+ needs: this.deploymentStages.length > 0 ? ['assetUpload', `deploy-${this.deploymentStages.at(-1)}`] : ['assetUpload'],
154
+ runsOn: ['ubuntu-latest'],
155
+ env: {
156
+ CI: 'true',
157
+ },
158
+ permissions: { idToken: workflows_model_1.JobPermission.WRITE, contents: workflows_model_1.JobPermission.READ },
159
+ steps: [{
160
+ name: 'Checkout',
161
+ uses: 'actions/checkout@v3',
162
+ }, {
163
+ name: 'AWS Credentials',
164
+ uses: 'aws-actions/configure-aws-credentials@master',
165
+ with: {
166
+ 'role-to-assume': (_g = (_f = (_e = this.options.iamRoleArns) === null || _e === void 0 ? void 0 : _e.deployment) === null || _f === void 0 ? void 0 : _f[stage.name]) !== null && _g !== void 0 ? _g : (_h = this.options.iamRoleArns) === null || _h === void 0 ? void 0 : _h.default,
167
+ 'role-session-name': 'GitHubAction',
168
+ 'aws-region': stage.env.region,
169
+ },
170
+ }, {
171
+ uses: 'actions/download-artifact@v3',
172
+ with: {
173
+ name: 'cloud-assembly',
174
+ path: `${this.app.cdkConfig.cdkout}/`,
175
+ },
176
+ },
177
+ ...this.getInstallCommands().map(cmd => ({
178
+ run: cmd,
179
+ })),
180
+ ...this.getDeployCommands(stage.name).map(cmd => ({
181
+ run: cmd,
182
+ }))],
183
+ });
184
+ this.deploymentStages.push(stage.name);
185
+ }
186
+ }
187
+ }
188
+ exports.GithubCDKPipeline = GithubCDKPipeline;
189
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2l0aHViLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2F3c2Nkay9naXRodWIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEsdUVBQTJFO0FBQzNFLGlDQUEwRTtBQVkxRSxNQUFhLGlCQUFrQixTQUFRLGtCQUFXO0lBT2hELFlBQVksR0FBK0IsRUFBVSxPQUFpQztRQUNwRixLQUFLLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRCtCLFlBQU8sR0FBUCxPQUFPLENBQTBCO1FBRjlFLHFCQUFnQixHQUFhLEVBQUUsQ0FBQztRQUt0QyxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFPLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2pFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLENBQUM7WUFDekIsSUFBSSxFQUFFO2dCQUNKLFFBQVEsRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLGdDQUFnQzthQUNyRDtZQUNELGdCQUFnQixFQUFFLEVBQUU7U0FDckIsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLHVCQUF1QixHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxjQUFjLEtBQUssSUFBSSxDQUFDLEtBQUssU0FBUyxDQUFDO1FBRXRHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUVuQixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUV6QixLQUFLLE1BQU0sS0FBSyxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUU7WUFDbEMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQzlCO0lBQ0gsQ0FBQztJQUVPLFdBQVc7O1FBQ2pCLE1BQU0sS0FBSyxHQUFjLENBQUM7Z0JBQ3hCLElBQUksRUFBRSxVQUFVO2dCQUNoQixJQUFJLEVBQUUscUJBQXFC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Q0FBQyxDQUFDO29CQUNILEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO3dCQUNoRCxHQUFHLEVBQUUsR0FBRztxQkFDVCxDQUFDLENBQUMsQ0FBQzthQUNMLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQ3hDO0lBQ0gsQ0FBQztDQUNGO0FBbE1ELDhDQWtNQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGF3c2NkayB9IGZyb20gJ3Byb2plbic7XG5pbXBvcnQgeyBHaXRodWJXb3JrZmxvdyB9IGZyb20gJ3Byb2plbi9saWIvZ2l0aHViJztcbmltcG9ydCB7IEpvYlBlcm1pc3Npb24sIEpvYlN0ZXAgfSBmcm9tICdwcm9qZW4vbGliL2dpdGh1Yi93b3JrZmxvd3MtbW9kZWwnO1xuaW1wb3J0IHsgQ0RLUGlwZWxpbmUsIENES1BpcGVsaW5lT3B0aW9ucywgRGVwbG95bWVudFN0YWdlIH0gZnJvbSAnLi9iYXNlJztcblxuXG5leHBvcnQgaW50ZXJmYWNlIEdpdGh1YkNES1BpcGVsaW5lT3B0aW9ucyBleHRlbmRzIENES1BpcGVsaW5lT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGlhbVJvbGVBcm5zOiB7XG4gICAgcmVhZG9ubHkgZGVmYXVsdD86IHN0cmluZztcbiAgICByZWFkb25seSBzeW50aD86IHN0cmluZztcbiAgICByZWFkb25seSBhc3NldFB1Ymxpc2hpbmc/OiBzdHJpbmc7XG4gICAgcmVhZG9ubHkgZGVwbG95bWVudD86IHsgW3N0YWdlOiBzdHJpbmddOiBzdHJpbmcgfTtcbiAgfTtcbn1cblxuZXhwb3J0IGNsYXNzIEdpdGh1YkNES1BpcGVsaW5lIGV4dGVuZHMgQ0RLUGlwZWxpbmUge1xuXG4gIHB1YmxpYyByZWFkb25seSBuZWVkc1ZlcnNpb25lZEFydGlmYWN0czogYm9vbGVhbjtcblxuICBwcml2YXRlIGRlcGxveW1lbnRXb3JrZmxvdzogR2l0aHViV29ya2Zsb3c7XG4gIHByaXZhdGUgZGVwbG95bWVudFN0YWdlczogc3RyaW5nW10gPSBbXTtcblxuICBjb25zdHJ1Y3RvcihhcHA6IGF3c2Nkay5Bd3NDZGtUeXBlU2NyaXB0QXBwLCBwcml2YXRlIG9wdGlvbnM6IEdpdGh1YkNES1BpcGVsaW5lT3B0aW9ucykge1xuICAgIHN1cGVyKGFwcCwgb3B0aW9ucyk7XG5cbiAgICB0aGlzLmRlcGxveW1lbnRXb3JrZmxvdyA9IHRoaXMuYXBwLmdpdGh1YiEuYWRkV29ya2Zsb3coJ2RlcGxveScpO1xuICAgIHRoaXMuZGVwbG95bWVudFdvcmtmbG93Lm9uKHtcbiAgICAgIHB1c2g6IHtcbiAgICAgICAgYnJhbmNoZXM6IFsnbWFpbiddLCAvLyBUT0RPIHVzZSBkZWZhdWx0UmVsZWFzZUJyYW5jaFxuICAgICAgfSxcbiAgICAgIHdvcmtmbG93RGlzcGF0Y2g6IHt9LFxuICAgIH0pO1xuXG4gICAgdGhpcy5uZWVkc1ZlcnNpb25lZEFydGlmYWN0cyA9IHRoaXMub3B0aW9ucy5zdGFnZXMuZmluZChzID0+IHMubWFudWFsQXBwcm92YWwgPT09IHRydWUpICE9PSB1bmRlZmluZWQ7XG5cbiAgICB0aGlzLmNyZWF0ZVN5bnRoKCk7XG5cbiAgICB0aGlzLmNyZWF0ZUFzc2V0VXBsb2FkKCk7XG5cbiAgICBmb3IgKGNvbnN0IHN0YWdlIG9mIG9wdGlvbnMuc3RhZ2VzKSB7XG4gICAgICB0aGlzLmNyZWF0ZURlcGxveW1lbnQoc3RhZ2UpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlU3ludGgoKTogdm9pZCB7XG4gICAgY29uc3Qgc3RlcHM6IEpvYlN0ZXBbXSA9IFt7XG4gICAgICBuYW1lOiAnQ2hlY2tvdXQnLFxuICAgICAgdXNlczogJ2FjdGlvbnMvY2hlY2tvdXRAdjMnLFxuICAgIH1dO1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5pYW1Sb2xlQXJucz8uc3ludGgpIHtcbiAgICAgIHN0ZXBzLnB1c2goe1xuICAgICAgICBuYW1lOiAnQVdTIENyZWRlbnRpYWxzJyxcbiAgICAgICAgdXNlczogJ2F3cy1hY3Rpb25zL2NvbmZpZ3VyZS1hd3MtY3JlZGVudGlhbHNAbWFzdGVyJyxcbiAgICAgICAgd2l0aDoge1xuICAgICAgICAgICdyb2xlLXRvLWFzc3VtZSc6IHRoaXMub3B0aW9ucy5pYW1Sb2xlQXJucy5zeW50aCxcbiAgICAgICAgICAncm9sZS1zZXNzaW9uLW5hbWUnOiAnR2l0SHViQWN0aW9uJyxcbiAgICAgICAgICAnYXdzLXJlZ2lvbic6ICd1cy1lYXN0LTEnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgc3RlcHMucHVzaCguLi50aGlzLmdldFN5bnRoQ29tbWFuZHMoKS5tYXAoY21kID0+ICh7XG4gICAgICBydW46IGNtZCxcbiAgICB9KSkpO1xuXG4gICAgc3RlcHMucHVzaCh7XG4gICAgICB1c2VzOiAnYWN0aW9ucy91cGxvYWQtYXJ0aWZhY3RAdjMnLFxuICAgICAgd2l0aDoge1xuICAgICAgICBuYW1lOiAnY2xvdWQtYXNzZW1ibHknLFxuICAgICAgICBwYXRoOiBgJHt0aGlzLmFwcC5jZGtDb25maWcuY2Rrb3V0fS9gLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHRoaXMuZGVwbG95bWVudFdvcmtmbG93LmFkZEpvYignc3ludGgnLCB7XG4gICAgICBuYW1lOiAnU3ludGggQ0RLIGFwcGxpY2F0aW9uJyxcbiAgICAgIHJ1bnNPbjogWyd1YnVudHUtbGF0ZXN0J10sXG4gICAgICBlbnY6IHtcbiAgICAgICAgQ0k6ICd0cnVlJyxcbiAgICAgIH0sXG4gICAgICBwZXJtaXNzaW9uczogeyBpZFRva2VuOiBKb2JQZXJtaXNzaW9uLldSSVRFLCBjb250ZW50czogSm9iUGVybWlzc2lvbi5SRUFEIH0sXG4gICAgICBzdGVwcyxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBjcmVhdGVBc3NldFVwbG9hZCgpOiB2b2lkIHtcbiAgICB0aGlzLmRlcGxveW1lbnRXb3JrZmxvdy5hZGRKb2IoJ2Fzc2V0VXBsb2FkJywge1xuICAgICAgbmFtZTogJ1B1Ymxpc2ggYXNzZXRzIHRvIEFXUycsXG4gICAgICBuZWVkczogWydzeW50aCddLFxuICAgICAgcnVuc09uOiBbJ3VidW50dS1sYXRlc3QnXSxcbiAgICAgIGVudjoge1xuICAgICAgICBDSTogJ3RydWUnLFxuICAgICAgfSxcbiAgICAgIHBlcm1pc3Npb25zOiB7IGlkVG9rZW46IEpvYlBlcm1pc3Npb24uV1JJVEUsIGNvbnRlbnRzOiB0aGlzLm5lZWRzVmVyc2lvbmVkQXJ0aWZhY3RzID8gSm9iUGVybWlzc2lvbi5XUklURSA6IEpvYlBlcm1pc3Npb24uUkVBRCB9LFxuICAgICAgc3RlcHM6IFt7XG4gICAgICAgIG5hbWU6ICdDaGVja291dCcsXG4gICAgICAgIHVzZXM6ICdhY3Rpb25zL2NoZWNrb3V0QHYzJyxcbiAgICAgICAgd2l0aDoge1xuICAgICAgICAgICdmZXRjaC1kZXB0aCc6IDAsXG4gICAgICAgIH0sXG4gICAgICB9LCB7XG4gICAgICAgIG5hbWU6ICdTZXR1cCBHSVQgaWRlbnRpdHknLFxuICAgICAgICBydW46ICdnaXQgY29uZmlnIC0tZ2xvYmFsIHVzZXIubmFtZSBcImdpdGh1Yi1hY3Rpb25zXCIgJiYgZ2l0IGNvbmZpZyAtLWdsb2JhbCB1c2VyLmVtYWlsIFwiZ2l0aHViLWFjdGlvbnNAZ2l0aHViLmNvbVwiJyxcbiAgICAgIH0sIHtcbiAgICAgICAgbmFtZTogJ0FXUyBDcmVkZW50aWFscycsXG4gICAgICAgIHVzZXM6ICdhd3MtYWN0aW9ucy9jb25maWd1cmUtYXdzLWNyZWRlbnRpYWxzQG1hc3RlcicsXG4gICAgICAgIHdpdGg6IHtcbiAgICAgICAgICAncm9sZS10by1hc3N1bWUnOiB0aGlzLm9wdGlvbnMuaWFtUm9sZUFybnM/LmFzc2V0UHVibGlzaGluZyA/PyB0aGlzLm9wdGlvbnMuaWFtUm9sZUFybnM/LmRlZmF1bHQsXG4gICAgICAgICAgJ3JvbGUtc2Vzc2lvbi1uYW1lJzogJ0dpdEh1YkFjdGlvbicsXG4gICAgICAgICAgJ2F3cy1yZWdpb24nOiAndXMtZWFzdC0xJyxcbiAgICAgICAgfSxcbiAgICAgIH0sIHtcbiAgICAgICAgdXNlczogJ2FjdGlvbnMvZG93bmxvYWQtYXJ0aWZhY3RAdjMnLFxuICAgICAgICB3aXRoOiB7XG4gICAgICAgICAgbmFtZTogJ2Nsb3VkLWFzc2VtYmx5JyxcbiAgICAgICAgICBwYXRoOiBgJHt0aGlzLmFwcC5jZGtDb25maWcuY2Rrb3V0fS9gLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIC4uLnRoaXMuZ2V0QXNzZXRVcGxvYWRDb21tYW5kcyh0aGlzLm5lZWRzVmVyc2lvbmVkQXJ0aWZhY3RzKS5tYXAoY21kID0+ICh7XG4gICAgICAgIHJ1bjogY21kLFxuICAgICAgfSkpXSxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBjcmVhdGVEZXBsb3ltZW50KHN0YWdlOiBEZXBsb3ltZW50U3RhZ2UpOiB2b2lkIHtcbiAgICBpZiAoc3RhZ2UubWFudWFsQXBwcm92YWwgPT09IHRydWUpIHtcbiAgICAgIC8vIENyZWF0ZSBuZXcgd29ya2Zsb3cgZm9yIGRlcGxveW1lbnRcbiAgICAgIGNvbnN0IHN0YWdlV29ya2Zsb3cgPSB0aGlzLmFwcC5naXRodWIhLmFkZFdvcmtmbG93KGByZWxlYXNlLSR7c3RhZ2UubmFtZX1gKTtcbiAgICAgIHN0YWdlV29ya2Zsb3cub24oe1xuICAgICAgICB3b3JrZmxvd0Rpc3BhdGNoOiB7XG4gICAgICAgICAgaW5wdXRzOiB7XG4gICAgICAgICAgICB2ZXJzaW9uOiB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnUGFja2FnZSB2ZXJzaW9uJyxcbiAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIHN0YWdlV29ya2Zsb3cuYWRkSm9iKCdkZXBsb3knLCB7XG4gICAgICAgIG5hbWU6IGBSZWxlYXNlIHN0YWdlICR7c3RhZ2UubmFtZX0gdG8gQVdTYCxcbiAgICAgICAgcnVuc09uOiBbJ3VidW50dS1sYXRlc3QnXSxcbiAgICAgICAgZW52OiB7XG4gICAgICAgICAgQ0k6ICd0cnVlJyxcbiAgICAgICAgfSxcbiAgICAgICAgcGVybWlzc2lvbnM6IHsgaWRUb2tlbjogSm9iUGVybWlzc2lvbi5XUklURSwgY29udGVudHM6IEpvYlBlcm1pc3Npb24uUkVBRCB9LFxuICAgICAgICBzdGVwczogW3tcbiAgICAgICAgICBuYW1lOiAnQ2hlY2tvdXQnLFxuICAgICAgICAgIHVzZXM6ICdhY3Rpb25zL2NoZWNrb3V0QHYzJyxcbiAgICAgICAgfSwge1xuICAgICAgICAgIG5hbWU6ICdBV1MgQ3JlZGVudGlhbHMnLFxuICAgICAgICAgIHVzZXM6ICdhd3MtYWN0aW9ucy9jb25maWd1cmUtYXdzLWNyZWRlbnRpYWxzQG1hc3RlcicsXG4gICAgICAgICAgd2l0aDoge1xuICAgICAgICAgICAgJ3JvbGUtdG8tYXNzdW1lJzogdGhpcy5vcHRpb25zLmlhbVJvbGVBcm5zPy5kZXBsb3ltZW50Py5bc3RhZ2UubmFtZV0gPz8gdGhpcy5vcHRpb25zLmlhbVJvbGVBcm5zPy5kZWZhdWx0LFxuICAgICAgICAgICAgJ3JvbGUtc2Vzc2lvbi1uYW1lJzogJ0dpdEh1YkFjdGlvbicsXG4gICAgICAgICAgICAnYXdzLXJlZ2lvbic6IHN0YWdlLmVudi5yZWdpb24sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgLi4udGhpcy5nZXRJbnN0YWxsQ29tbWFuZHMoKS5tYXAoY21kID0+ICh7XG4gICAgICAgICAgcnVuOiBjbWQsXG4gICAgICAgIH0pKSxcbiAgICAgICAgLi4udGhpcy5nZXRJbnN0YWxsUGFja2FnZUNvbW1hbmRzKGAke3RoaXMub3B0aW9ucy5wa2dOYW1lc3BhY2V9LyR7dGhpcy5hcHAubmFtZX1AXFwke3tnaXRodWIuZXZlbnQuaW5wdXRzLnZlcnNpb259fWApLm1hcChjbWQgPT4gKHtcbiAgICAgICAgICBydW46IGNtZCxcbiAgICAgICAgfSkpLFxuICAgICAgICB7XG4gICAgICAgICAgcnVuOiBgbXYgLi9ub2RlX21vZHVsZXMvJHt0aGlzLm9wdGlvbnMucGtnTmFtZXNwYWNlfS8ke3RoaXMuYXBwLm5hbWV9ICR7dGhpcy5hcHAuY2RrQ29uZmlnLmNka291dH1gLFxuICAgICAgICB9LFxuICAgICAgICAuLi50aGlzLmdldERlcGxveUNvbW1hbmRzKHN0YWdlLm5hbWUpLm1hcChjbWQgPT4gKHtcbiAgICAgICAgICBydW46IGNtZCxcbiAgICAgICAgfSkpXSxcbiAgICAgIH0pO1xuXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEFkZCBkZXBsb3ltZW50IHRvIENJL0NEIHdvcmtmbG93XG4gICAgICB0aGlzLmRlcGxveW1lbnRXb3JrZmxvdy5hZGRKb2IoYGRlcGxveS0ke3N0YWdlLm5hbWV9YCwge1xuICAgICAgICBuYW1lOiBgRGVwbG95IHN0YWdlICR7c3RhZ2UubmFtZX0gdG8gQVdTYCxcbiAgICAgICAgbmVlZHM6IHRoaXMuZGVwbG95bWVudFN0YWdlcy5sZW5ndGggPiAwID8gWydhc3NldFVwbG9hZCcsIGBkZXBsb3ktJHt0aGlzLmRlcGxveW1lbnRTdGFnZXMuYXQoLTEpIX1gXSA6IFsnYXNzZXRVcGxvYWQnXSxcbiAgICAgICAgcnVuc09uOiBbJ3VidW50dS1sYXRlc3QnXSxcbiAgICAgICAgZW52OiB7XG4gICAgICAgICAgQ0k6ICd0cnVlJyxcbiAgICAgICAgfSxcbiAgICAgICAgcGVybWlzc2lvbnM6IHsgaWRUb2tlbjogSm9iUGVybWlzc2lvbi5XUklURSwgY29udGVudHM6IEpvYlBlcm1pc3Npb24uUkVBRCB9LFxuICAgICAgICBzdGVwczogW3tcbiAgICAgICAgICBuYW1lOiAnQ2hlY2tvdXQnLFxuICAgICAgICAgIHVzZXM6ICdhY3Rpb25zL2NoZWNrb3V0QHYzJyxcbiAgICAgICAgfSwge1xuICAgICAgICAgIG5hbWU6ICdBV1MgQ3JlZGVudGlhbHMnLFxuICAgICAgICAgIHVzZXM6ICdhd3MtYWN0aW9ucy9jb25maWd1cmUtYXdzLWNyZWRlbnRpYWxzQG1hc3RlcicsXG4gICAgICAgICAgd2l0aDoge1xuICAgICAgICAgICAgJ3JvbGUtdG8tYXNzdW1lJzogdGhpcy5vcHRpb25zLmlhbVJvbGVBcm5zPy5kZXBsb3ltZW50Py5bc3RhZ2UubmFtZV0gPz8gdGhpcy5vcHRpb25zLmlhbVJvbGVBcm5zPy5kZWZhdWx0LFxuICAgICAgICAgICAgJ3JvbGUtc2Vzc2lvbi1uYW1lJzogJ0dpdEh1YkFjdGlvbicsXG4gICAgICAgICAgICAnYXdzLXJlZ2lvbic6IHN0YWdlLmVudi5yZWdpb24sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSwge1xuICAgICAgICAgIHVzZXM6ICdhY3Rpb25zL2Rvd25sb2FkLWFydGlmYWN0QHYzJyxcbiAgICAgICAgICB3aXRoOiB7XG4gICAgICAgICAgICBuYW1lOiAnY2xvdWQtYXNzZW1ibHknLFxuICAgICAgICAgICAgcGF0aDogYCR7dGhpcy5hcHAuY2RrQ29uZmlnLmNka291dH0vYCxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICAuLi50aGlzLmdldEluc3RhbGxDb21tYW5kcygpLm1hcChjbWQgPT4gKHtcbiAgICAgICAgICBydW46IGNtZCxcbiAgICAgICAgfSkpLFxuICAgICAgICAuLi50aGlzLmdldERlcGxveUNvbW1hbmRzKHN0YWdlLm5hbWUpLm1hcChjbWQgPT4gKHtcbiAgICAgICAgICBydW46IGNtZCxcbiAgICAgICAgfSkpXSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5kZXBsb3ltZW50U3RhZ2VzLnB1c2goc3RhZ2UubmFtZSk7XG4gICAgfVxuICB9XG59XG4iXX0=
@@ -16,4 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./base"), exports);
18
18
  __exportStar(require("./github"), exports);
19
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZW5naW5lL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx5Q0FBdUI7QUFDdkIsMkNBQXlCIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9iYXNlJztcbmV4cG9ydCAqIGZyb20gJy4vZ2l0aHViJzsiXX0=
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXdzY2RrL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx5Q0FBdUI7QUFDdkIsMkNBQXlCIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9iYXNlJztcbmV4cG9ydCAqIGZyb20gJy4vZ2l0aHViJzsiXX0=
package/lib/index.d.ts CHANGED
@@ -1,2 +1 @@
1
- export * from './pipeline';
2
- export * from './engine';
1
+ export * from './awscdk';
package/lib/index.js CHANGED
@@ -14,6 +14,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./pipeline"), exports);
18
- __exportStar(require("./engine"), exports);
19
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDZDQUEyQjtBQUMzQiwyQ0FBeUIiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL3BpcGVsaW5lJztcbmV4cG9ydCAqIGZyb20gJy4vZW5naW5lJzsiXX0=
17
+ __exportStar(require("./awscdk"), exports);
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDJDQUF5QiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vYXdzY2RrJzsiXX0=
package/package.json CHANGED
@@ -67,7 +67,7 @@
67
67
  ],
68
68
  "main": "lib/index.js",
69
69
  "license": "Apache-2.0",
70
- "version": "0.0.17",
70
+ "version": "0.0.18",
71
71
  "jest": {
72
72
  "testMatch": [
73
73
  "<rootDir>/src/**/__tests__/**/*.ts?(x)",
@@ -1,23 +0,0 @@
1
- import { awscdk } from 'projen';
2
- import { CDKPipeline, CDKPipelineOptions, DeploymentStage } from '../pipeline';
3
- export interface SynthStageOptions {
4
- readonly commands: string[];
5
- }
6
- export interface AssetUploadStageOptions {
7
- readonly commands: string[];
8
- }
9
- export interface DeployStageOptions {
10
- readonly config: DeploymentStage;
11
- readonly installCommands: string[];
12
- readonly deployCommands: string[];
13
- }
14
- export declare abstract class BaseEngine {
15
- protected app: awscdk.AwsCdkTypeScriptApp;
16
- protected props: CDKPipelineOptions;
17
- protected pipeline: CDKPipeline;
18
- abstract readonly needsVersionedArtifacts: boolean;
19
- constructor(app: awscdk.AwsCdkTypeScriptApp, props: CDKPipelineOptions, pipeline: CDKPipeline);
20
- abstract createSynth(options: SynthStageOptions): void;
21
- abstract createAssetUpload(options: AssetUploadStageOptions): void;
22
- abstract createDeployment(options: DeployStageOptions): void;
23
- }
@@ -1,13 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BaseEngine = void 0;
4
- class BaseEngine {
5
- constructor(app, props, pipeline) {
6
- this.app = app;
7
- this.props = props;
8
- this.pipeline = pipeline;
9
- //
10
- }
11
- }
12
- exports.BaseEngine = BaseEngine;
13
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lbmdpbmUvYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFpQkEsTUFBc0IsVUFBVTtJQUk5QixZQUFzQixHQUErQixFQUFZLEtBQXlCLEVBQVksUUFBcUI7UUFBckcsUUFBRyxHQUFILEdBQUcsQ0FBNEI7UUFBWSxVQUFLLEdBQUwsS0FBSyxDQUFvQjtRQUFZLGFBQVEsR0FBUixRQUFRLENBQWE7UUFDekgsRUFBRTtJQUNKLENBQUM7Q0FNRjtBQVpELGdDQVlDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgYXdzY2RrIH0gZnJvbSAncHJvamVuJztcbmltcG9ydCB7IENES1BpcGVsaW5lLCBDREtQaXBlbGluZU9wdGlvbnMsIERlcGxveW1lbnRTdGFnZSB9IGZyb20gJy4uL3BpcGVsaW5lJztcblxuZXhwb3J0IGludGVyZmFjZSBTeW50aFN0YWdlT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGNvbW1hbmRzOiBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBc3NldFVwbG9hZFN0YWdlT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGNvbW1hbmRzOiBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEZXBsb3lTdGFnZU9wdGlvbnMge1xuICByZWFkb25seSBjb25maWc6IERlcGxveW1lbnRTdGFnZTtcbiAgcmVhZG9ubHkgaW5zdGFsbENvbW1hbmRzOiBzdHJpbmdbXTtcbiAgcmVhZG9ubHkgZGVwbG95Q29tbWFuZHM6IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQmFzZUVuZ2luZSB7XG5cbiAgcHVibGljIGFic3RyYWN0IHJlYWRvbmx5IG5lZWRzVmVyc2lvbmVkQXJ0aWZhY3RzOiBib29sZWFuO1xuXG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBhcHA6IGF3c2Nkay5Bd3NDZGtUeXBlU2NyaXB0QXBwLCBwcm90ZWN0ZWQgcHJvcHM6IENES1BpcGVsaW5lT3B0aW9ucywgcHJvdGVjdGVkIHBpcGVsaW5lOiBDREtQaXBlbGluZSkge1xuICAgIC8vXG4gIH1cblxuICBhYnN0cmFjdCBjcmVhdGVTeW50aChvcHRpb25zOiBTeW50aFN0YWdlT3B0aW9ucyk6IHZvaWQ7XG4gIGFic3RyYWN0IGNyZWF0ZUFzc2V0VXBsb2FkKG9wdGlvbnM6IEFzc2V0VXBsb2FkU3RhZ2VPcHRpb25zKTogdm9pZDtcbiAgYWJzdHJhY3QgY3JlYXRlRGVwbG95bWVudChvcHRpb25zOiBEZXBsb3lTdGFnZU9wdGlvbnMpOiB2b2lkO1xuXG59Il19
@@ -1,20 +0,0 @@
1
- import { awscdk } from 'projen';
2
- import { AssetUploadStageOptions, BaseEngine, DeployStageOptions, SynthStageOptions } from './base';
3
- import { CDKPipeline, CDKPipelineOptions } from '../pipeline';
4
- export interface GithubEngineConfig {
5
- readonly defaultAwsRoleArn?: string;
6
- readonly awsRoleArnForSynth?: string;
7
- readonly awsRoleArnForAssetPublishing?: string;
8
- readonly awsRoleArnForDeployment?: {
9
- [stage: string]: string;
10
- };
11
- }
12
- export declare class GitHubEngine extends BaseEngine {
13
- readonly needsVersionedArtifacts: boolean;
14
- private deploymentWorkflow;
15
- private deploymentStages;
16
- constructor(app: awscdk.AwsCdkTypeScriptApp, props: CDKPipelineOptions, pipeline: CDKPipeline);
17
- createSynth(options: SynthStageOptions): void;
18
- createAssetUpload(options: AssetUploadStageOptions): void;
19
- createDeployment(options: DeployStageOptions): void;
20
- }
@@ -1,180 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GitHubEngine = void 0;
4
- const workflows_model_1 = require("projen/lib/github/workflows-model");
5
- const base_1 = require("./base");
6
- class GitHubEngine extends base_1.BaseEngine {
7
- constructor(app, props, pipeline) {
8
- super(app, props, pipeline);
9
- this.deploymentStages = [];
10
- this.deploymentWorkflow = this.app.github.addWorkflow('deploy');
11
- this.deploymentWorkflow.on({
12
- push: {
13
- branches: ['main'], // TODO use defaultReleaseBranch
14
- },
15
- workflowDispatch: {},
16
- });
17
- this.needsVersionedArtifacts = this.props.stages.find(s => s.manualApproval === true) !== undefined;
18
- }
19
- createSynth(options) {
20
- var _a;
21
- const steps = [{
22
- name: 'Checkout',
23
- uses: 'actions/checkout@v3',
24
- }];
25
- if ((_a = this.props.githubConfig) === null || _a === void 0 ? void 0 : _a.awsRoleArnForSynth) {
26
- steps.push({
27
- name: 'AWS Credentials',
28
- uses: 'aws-actions/configure-aws-credentials@master',
29
- with: {
30
- 'role-to-assume': this.props.githubConfig.awsRoleArnForSynth,
31
- 'role-session-name': 'GitHubAction',
32
- 'aws-region': 'us-east-1',
33
- },
34
- });
35
- }
36
- steps.push(...options.commands.map(cmd => ({
37
- run: cmd,
38
- })));
39
- steps.push({
40
- uses: 'actions/upload-artifact@v3',
41
- with: {
42
- name: 'cloud-assembly',
43
- path: `${this.app.cdkConfig.cdkout}/`,
44
- },
45
- });
46
- this.deploymentWorkflow.addJob('synth', {
47
- name: 'Synth CDK application',
48
- runsOn: ['ubuntu-latest'],
49
- env: {
50
- CI: 'true',
51
- },
52
- permissions: { idToken: workflows_model_1.JobPermission.WRITE, contents: workflows_model_1.JobPermission.READ },
53
- steps,
54
- });
55
- }
56
- createAssetUpload(options) {
57
- var _a, _b, _c;
58
- this.deploymentWorkflow.addJob('assetUpload', {
59
- name: 'Publish assets to AWS',
60
- needs: ['synth'],
61
- runsOn: ['ubuntu-latest'],
62
- env: {
63
- CI: 'true',
64
- },
65
- permissions: { idToken: workflows_model_1.JobPermission.WRITE, contents: this.needsVersionedArtifacts ? workflows_model_1.JobPermission.WRITE : workflows_model_1.JobPermission.READ },
66
- steps: [{
67
- name: 'Checkout',
68
- uses: 'actions/checkout@v3',
69
- with: {
70
- 'fetch-depth': 0,
71
- },
72
- }, {
73
- name: 'Setup GIT identity',
74
- run: 'git config --global user.name "projen pipeline" && git config --global user.email "info@taimos.de"',
75
- }, {
76
- name: 'AWS Credentials',
77
- uses: 'aws-actions/configure-aws-credentials@master',
78
- with: {
79
- 'role-to-assume': (_b = (_a = this.props.githubConfig) === null || _a === void 0 ? void 0 : _a.awsRoleArnForAssetPublishing) !== null && _b !== void 0 ? _b : (_c = this.props.githubConfig) === null || _c === void 0 ? void 0 : _c.defaultAwsRoleArn,
80
- 'role-session-name': 'GitHubAction',
81
- 'aws-region': 'us-east-1',
82
- },
83
- }, {
84
- uses: 'actions/download-artifact@v3',
85
- with: {
86
- name: 'cloud-assembly',
87
- path: `${this.app.cdkConfig.cdkout}/`,
88
- },
89
- },
90
- ...options.commands.map(cmd => ({
91
- run: cmd,
92
- }))],
93
- });
94
- }
95
- createDeployment(options) {
96
- var _a, _b, _c, _d, _e, _f, _g, _h;
97
- if (options.config.manualApproval === true) {
98
- // Create new workflow for deployment
99
- const stageWorkflow = this.app.github.addWorkflow(`release-${options.config.name}`);
100
- stageWorkflow.on({
101
- workflowDispatch: {
102
- inputs: {
103
- version: {
104
- description: 'Package version',
105
- required: true,
106
- },
107
- },
108
- },
109
- });
110
- stageWorkflow.addJob('deploy', {
111
- name: `Release stage ${options.config.name} to AWS`,
112
- runsOn: ['ubuntu-latest'],
113
- env: {
114
- CI: 'true',
115
- },
116
- permissions: { idToken: workflows_model_1.JobPermission.WRITE, contents: workflows_model_1.JobPermission.READ },
117
- steps: [{
118
- name: 'Checkout',
119
- uses: 'actions/checkout@v3',
120
- }, {
121
- name: 'AWS Credentials',
122
- uses: 'aws-actions/configure-aws-credentials@master',
123
- with: {
124
- 'role-to-assume': (_c = (_b = (_a = this.props.githubConfig) === null || _a === void 0 ? void 0 : _a.awsRoleArnForDeployment) === null || _b === void 0 ? void 0 : _b[options.config.name]) !== null && _c !== void 0 ? _c : (_d = this.props.githubConfig) === null || _d === void 0 ? void 0 : _d.defaultAwsRoleArn,
125
- 'role-session-name': 'GitHubAction',
126
- 'aws-region': options.config.env.region,
127
- },
128
- },
129
- ...options.installCommands.map(cmd => ({
130
- run: cmd,
131
- })),
132
- {
133
- run: `yarn add ${this.props.pkgNamespace}/${this.app.name}@\${{github.event.inputs.version}} && mv ./node_modules/${this.props.pkgNamespace}/${this.app.name} ${this.app.cdkConfig.cdkout}`,
134
- },
135
- ...options.deployCommands.map(cmd => ({
136
- run: cmd,
137
- }))],
138
- });
139
- }
140
- else {
141
- // Add deployment to CI/CD workflow
142
- this.deploymentWorkflow.addJob(`deploy-${options.config.name}`, {
143
- name: `Deploy stage ${options.config.name} to AWS`,
144
- needs: this.deploymentStages.length > 0 ? ['assetUpload', `deploy-${this.deploymentStages.at(-1)}`] : ['assetUpload'],
145
- runsOn: ['ubuntu-latest'],
146
- env: {
147
- CI: 'true',
148
- },
149
- permissions: { idToken: workflows_model_1.JobPermission.WRITE, contents: workflows_model_1.JobPermission.READ },
150
- steps: [{
151
- name: 'Checkout',
152
- uses: 'actions/checkout@v3',
153
- }, {
154
- name: 'AWS Credentials',
155
- uses: 'aws-actions/configure-aws-credentials@master',
156
- with: {
157
- 'role-to-assume': (_g = (_f = (_e = this.props.githubConfig) === null || _e === void 0 ? void 0 : _e.awsRoleArnForDeployment) === null || _f === void 0 ? void 0 : _f[options.config.name]) !== null && _g !== void 0 ? _g : (_h = this.props.githubConfig) === null || _h === void 0 ? void 0 : _h.defaultAwsRoleArn,
158
- 'role-session-name': 'GitHubAction',
159
- 'aws-region': options.config.env.region,
160
- },
161
- }, {
162
- uses: 'actions/download-artifact@v3',
163
- with: {
164
- name: 'cloud-assembly',
165
- path: `${this.app.cdkConfig.cdkout}/`,
166
- },
167
- },
168
- ...options.installCommands.map(cmd => ({
169
- run: cmd,
170
- })),
171
- ...options.deployCommands.map(cmd => ({
172
- run: cmd,
173
- }))],
174
- });
175
- this.deploymentStages.push(options.config.name);
176
- }
177
- }
178
- }
179
- exports.GitHubEngine = GitHubEngine;
180
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2l0aHViLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2VuZ2luZS9naXRodWIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEsdUVBQTJFO0FBQzNFLGlDQUFvRztBQVVwRyxNQUFhLFlBQWEsU0FBUSxpQkFBVTtJQU8xQyxZQUFZLEdBQStCLEVBQUUsS0FBeUIsRUFBRSxRQUFxQjtRQUMzRixLQUFLLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztRQUh0QixxQkFBZ0IsR0FBYSxFQUFFLENBQUM7UUFLdEMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTyxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNqRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsRUFBRSxDQUFDO1lBQ3pCLElBQUksRUFBRTtnQkFDSixRQUFRLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxnQ0FBZ0M7YUFDckQ7WUFDRCxnQkFBZ0IsRUFBRSxFQUFFO1NBQ3JCLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyx1QkFBdUIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsY0FBYyxLQUFLLElBQUksQ0FBQyxLQUFLLFNBQVMsQ0FBQztJQUN0RyxDQUFDO0lBRU0sV0FBVyxDQUFDLE9BQTBCOztRQUMzQyxNQUFNLEtBQUssR0FBYyxDQUFDO2dCQUN4QixJQUFJLEVBQUUsVUFBVTtnQkFDaEIsSUFBSSxFQUFFLHFCQUFxQjthQUM1QixDQUFDLENBQUM7UUFFSCxJQUFJLE1BQUEsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLDBDQUFFLGtCQUFrQixFQUFFO1lBQy9DLEtBQUssQ0FBQyxJQUFJLENBQUM7Z0JBQ1QsSUFBSSxFQUFFLGlCQUFpQjtnQkFDdkIsSUFBSSxFQUFFLDhDQUE4QztnQkFDcEQs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QyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGF3c2NkayB9IGZyb20gJ3Byb2plbic7XG5pbXBvcnQgeyBHaXRodWJXb3JrZmxvdyB9IGZyb20gJ3Byb2plbi9saWIvZ2l0aHViJztcbmltcG9ydCB7IEpvYlBlcm1pc3Npb24sIEpvYlN0ZXAgfSBmcm9tICdwcm9qZW4vbGliL2dpdGh1Yi93b3JrZmxvd3MtbW9kZWwnO1xuaW1wb3J0IHsgQXNzZXRVcGxvYWRTdGFnZU9wdGlvbnMsIEJhc2VFbmdpbmUsIERlcGxveVN0YWdlT3B0aW9ucywgU3ludGhTdGFnZU9wdGlvbnMgfSBmcm9tICcuL2Jhc2UnO1xuaW1wb3J0IHsgQ0RLUGlwZWxpbmUsIENES1BpcGVsaW5lT3B0aW9ucyB9IGZyb20gJy4uL3BpcGVsaW5lJztcblxuZXhwb3J0IGludGVyZmFjZSBHaXRodWJFbmdpbmVDb25maWcge1xuICByZWFkb25seSBkZWZhdWx0QXdzUm9sZUFybj86IHN0cmluZztcbiAgcmVhZG9ubHkgYXdzUm9sZUFybkZvclN5bnRoPzogc3RyaW5nO1xuICByZWFkb25seSBhd3NSb2xlQXJuRm9yQXNzZXRQdWJsaXNoaW5nPzogc3RyaW5nO1xuICByZWFkb25seSBhd3NSb2xlQXJuRm9yRGVwbG95bWVudD86IHsgW3N0YWdlOiBzdHJpbmddOiBzdHJpbmcgfTtcbn1cblxuZXhwb3J0IGNsYXNzIEdpdEh1YkVuZ2luZSBleHRlbmRzIEJhc2VFbmdpbmUge1xuXG4gIHB1YmxpYyByZWFkb25seSBuZWVkc1ZlcnNpb25lZEFydGlmYWN0czogYm9vbGVhbjtcblxuICBwcml2YXRlIGRlcGxveW1lbnRXb3JrZmxvdzogR2l0aHViV29ya2Zsb3c7XG4gIHByaXZhdGUgZGVwbG95bWVudFN0YWdlczogc3RyaW5nW10gPSBbXTtcblxuICBjb25zdHJ1Y3RvcihhcHA6IGF3c2Nkay5Bd3NDZGtUeXBlU2NyaXB0QXBwLCBwcm9wczogQ0RLUGlwZWxpbmVPcHRpb25zLCBwaXBlbGluZTogQ0RLUGlwZWxpbmUpIHtcbiAgICBzdXBlcihhcHAsIHByb3BzLCBwaXBlbGluZSk7XG5cbiAgICB0aGlzLmRlcGxveW1lbnRXb3JrZmxvdyA9IHRoaXMuYXBwLmdpdGh1YiEuYWRkV29ya2Zsb3coJ2RlcGxveScpO1xuICAgIHRoaXMuZGVwbG95bWVudFdvcmtmbG93Lm9uKHtcbiAgICAgIHB1c2g6IHtcbiAgICAgICAgYnJhbmNoZXM6IFsnbWFpbiddLCAvLyBUT0RPIHVzZSBkZWZhdWx0UmVsZWFzZUJyYW5jaFxuICAgICAgfSxcbiAgICAgIHdvcmtmbG93RGlzcGF0Y2g6IHt9LFxuICAgIH0pO1xuXG4gICAgdGhpcy5uZWVkc1ZlcnNpb25lZEFydGlmYWN0cyA9IHRoaXMucHJvcHMuc3RhZ2VzLmZpbmQocyA9PiBzLm1hbnVhbEFwcHJvdmFsID09PSB0cnVlKSAhPT0gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHVibGljIGNyZWF0ZVN5bnRoKG9wdGlvbnM6IFN5bnRoU3RhZ2VPcHRpb25zKTogdm9pZCB7XG4gICAgY29uc3Qgc3RlcHM6IEpvYlN0ZXBbXSA9IFt7XG4gICAgICBuYW1lOiAnQ2hlY2tvdXQnLFxuICAgICAgdXNlczogJ2FjdGlvbnMvY2hlY2tvdXRAdjMnLFxuICAgIH1dO1xuXG4gICAgaWYgKHRoaXMucHJvcHMuZ2l0aHViQ29uZmlnPy5hd3NSb2xlQXJuRm9yU3ludGgpIHtcbiAgICAgIHN0ZXBzLnB1c2goe1xuICAgICAgICBuYW1lOiAnQVdTIENyZWRlbnRpYWxzJyxcbiAgICAgICAgdXNlczogJ2F3cy1hY3Rpb25zL2NvbmZpZ3VyZS1hd3MtY3JlZGVudGlhbHNAbWFzdGVyJyxcbiAgICAgICAgd2l0aDoge1xuICAgICAgICAgICdyb2xlLXRvLWFzc3VtZSc6IHRoaXMucHJvcHMuZ2l0aHViQ29uZmlnLmF3c1JvbGVBcm5Gb3JTeW50aCxcbiAgICAgICAgICAncm9sZS1zZXNzaW9uLW5hbWUnOiAnR2l0SHViQWN0aW9uJyxcbiAgICAgICAgICAnYXdzLXJlZ2lvbic6ICd1cy1lYXN0LTEnLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgc3RlcHMucHVzaCguLi5vcHRpb25zLmNvbW1hbmRzLm1hcChjbWQgPT4gKHtcbiAgICAgIHJ1bjogY21kLFxuICAgIH0pKSk7XG5cbiAgICBzdGVwcy5wdXNoKHtcbiAgICAgIHVzZXM6ICdhY3Rpb25zL3VwbG9hZC1hcnRpZmFjdEB2MycsXG4gICAgICB3aXRoOiB7XG4gICAgICAgIG5hbWU6ICdjbG91ZC1hc3NlbWJseScsXG4gICAgICAgIHBhdGg6IGAke3RoaXMuYXBwLmNka0NvbmZpZy5jZGtvdXR9L2AsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgdGhpcy5kZXBsb3ltZW50V29ya2Zsb3cuYWRkSm9iKCdzeW50aCcsIHtcbiAgICAgIG5hbWU6ICdTeW50aCBDREsgYXBwbGljYXRpb24nLFxuICAgICAgcnVuc09uOiBbJ3VidW50dS1sYXRlc3QnXSxcbiAgICAgIGVudjoge1xuICAgICAgICBDSTogJ3RydWUnLFxuICAgICAgfSxcbiAgICAgIHBlcm1pc3Npb25zOiB7IGlkVG9rZW46IEpvYlBlcm1pc3Npb24uV1JJVEUsIGNvbnRlbnRzOiBKb2JQZXJtaXNzaW9uLlJFQUQgfSxcbiAgICAgIHN0ZXBzLFxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGNyZWF0ZUFzc2V0VXBsb2FkKG9wdGlvbnM6IEFzc2V0VXBsb2FkU3RhZ2VPcHRpb25zKTogdm9pZCB7XG4gICAgdGhpcy5kZXBsb3ltZW50V29ya2Zsb3cuYWRkSm9iKCdhc3NldFVwbG9hZCcsIHtcbiAgICAgIG5hbWU6ICdQdWJsaXNoIGFzc2V0cyB0byBBV1MnLFxuICAgICAgbmVlZHM6IFsnc3ludGgnXSxcbiAgICAgIHJ1bnNPbjogWyd1YnVudHUtbGF0ZXN0J10sXG4gICAgICBlbnY6IHtcbiAgICAgICAgQ0k6ICd0cnVlJyxcbiAgICAgIH0sXG4gICAgICBwZXJtaXNzaW9uczogeyBpZFRva2VuOiBKb2JQZXJtaXNzaW9uLldSSVRFLCBjb250ZW50czogdGhpcy5uZWVkc1ZlcnNpb25lZEFydGlmYWN0cyA/IEpvYlBlcm1pc3Npb24uV1JJVEUgOiBKb2JQZXJtaXNzaW9uLlJFQUQgfSxcbiAgICAgIHN0ZXBzOiBbe1xuICAgICAgICBuYW1lOiAnQ2hlY2tvdXQnLFxuICAgICAgICB1c2VzOiAnYWN0aW9ucy9jaGVja291dEB2MycsXG4gICAgICAgIHdpdGg6IHtcbiAgICAgICAgICAnZmV0Y2gtZGVwdGgnOiAwLFxuICAgICAgICB9LFxuICAgICAgfSwge1xuICAgICAgICBuYW1lOiAnU2V0dXAgR0lUIGlkZW50aXR5JyxcbiAgICAgICAgcnVuOiAnZ2l0IGNvbmZpZyAtLWdsb2JhbCB1c2VyLm5hbWUgXCJwcm9qZW4gcGlwZWxpbmVcIiAmJiBnaXQgY29uZmlnIC0tZ2xvYmFsIHVzZXIuZW1haWwgXCJpbmZvQHRhaW1vcy5kZVwiJyxcbiAgICAgIH0sIHtcbiAgICAgICAgbmFtZTogJ0FXUyBDcmVkZW50aWFscycsXG4gICAgICAgIHVzZXM6ICdhd3MtYWN0aW9ucy9jb25maWd1cmUtYXdzLWNyZWRlbnRpYWxzQG1hc3RlcicsXG4gICAgICAgIHdpdGg6IHtcbiAgICAgICAgICAncm9sZS10by1hc3N1bWUnOiB0aGlzLnByb3BzLmdpdGh1YkNvbmZpZz8uYXdzUm9sZUFybkZvckFzc2V0UHVibGlzaGluZyA/PyB0aGlzLnByb3BzLmdpdGh1YkNvbmZpZz8uZGVmYXVsdEF3c1JvbGVBcm4sXG4gICAgICAgICAgJ3JvbGUtc2Vzc2lvbi1uYW1lJzogJ0dpdEh1YkFjdGlvbicsXG4gICAgICAgICAgJ2F3cy1yZWdpb24nOiAndXMtZWFzdC0xJyxcbiAgICAgICAgfSxcbiAgICAgIH0sIHtcbiAgICAgICAgdXNlczogJ2FjdGlvbnMvZG93bmxvYWQtYXJ0aWZhY3RAdjMnLFxuICAgICAgICB3aXRoOiB7XG4gICAgICAgICAgbmFtZTogJ2Nsb3VkLWFzc2VtYmx5JyxcbiAgICAgICAgICBwYXRoOiBgJHt0aGlzLmFwcC5jZGtDb25maWcuY2Rrb3V0fS9gLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIC4uLm9wdGlvbnMuY29tbWFuZHMubWFwKGNtZCA9PiAoe1xuICAgICAgICBydW46IGNtZCxcbiAgICAgIH0pKV0sXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgY3JlYXRlRGVwbG95bWVudChvcHRpb25zOiBEZXBsb3lTdGFnZU9wdGlvbnMpOiB2b2lkIHtcbiAgICBpZiAob3B0aW9ucy5jb25maWcubWFudWFsQXBwcm92YWwgPT09IHRydWUpIHtcbiAgICAgIC8vIENyZWF0ZSBuZXcgd29ya2Zsb3cgZm9yIGRlcGxveW1lbnRcbiAgICAgIGNvbnN0IHN0YWdlV29ya2Zsb3cgPSB0aGlzLmFwcC5naXRodWIhLmFkZFdvcmtmbG93KGByZWxlYXNlLSR7b3B0aW9ucy5jb25maWcubmFtZX1gKTtcbiAgICAgIHN0YWdlV29ya2Zsb3cub24oe1xuICAgICAgICB3b3JrZmxvd0Rpc3BhdGNoOiB7XG4gICAgICAgICAgaW5wdXRzOiB7XG4gICAgICAgICAgICB2ZXJzaW9uOiB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnUGFja2FnZSB2ZXJzaW9uJyxcbiAgICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIHN0YWdlV29ya2Zsb3cuYWRkSm9iKCdkZXBsb3knLCB7XG4gICAgICAgIG5hbWU6IGBSZWxlYXNlIHN0YWdlICR7b3B0aW9ucy5jb25maWcubmFtZX0gdG8gQVdTYCxcbiAgICAgICAgcnVuc09uOiBbJ3VidW50dS1sYXRlc3QnXSxcbiAgICAgICAgZW52OiB7XG4gICAgICAgICAgQ0k6ICd0cnVlJyxcbiAgICAgICAgfSxcbiAgICAgICAgcGVybWlzc2lvbnM6IHsgaWRUb2tlbjogSm9iUGVybWlzc2lvbi5XUklURSwgY29udGVudHM6IEpvYlBlcm1pc3Npb24uUkVBRCB9LFxuICAgICAgICBzdGVwczogW3tcbiAgICAgICAgICBuYW1lOiAnQ2hlY2tvdXQnLFxuICAgICAgICAgIHVzZXM6ICdhY3Rpb25zL2NoZWNrb3V0QHYzJyxcbiAgICAgICAgfSwge1xuICAgICAgICAgIG5hbWU6ICdBV1MgQ3JlZGVudGlhbHMnLFxuICAgICAgICAgIHVzZXM6ICdhd3MtYWN0aW9ucy9jb25maWd1cmUtYXdzLWNyZWRlbnRpYWxzQG1hc3RlcicsXG4gICAgICAgICAgd2l0aDoge1xuICAgICAgICAgICAgJ3JvbGUtdG8tYXNzdW1lJzogdGhpcy5wcm9wcy5naXRodWJDb25maWc/LmF3c1JvbGVBcm5Gb3JEZXBsb3ltZW50Py5bb3B0aW9ucy5jb25maWcubmFtZV0gPz8gdGhpcy5wcm9wcy5naXRodWJDb25maWc/LmRlZmF1bHRBd3NSb2xlQXJuLFxuICAgICAgICAgICAgJ3JvbGUtc2Vzc2lvbi1uYW1lJzogJ0dpdEh1YkFjdGlvbicsXG4gICAgICAgICAgICAnYXdzLXJlZ2lvbic6IG9wdGlvbnMuY29uZmlnLmVudi5yZWdpb24sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgLi4ub3B0aW9ucy5pbnN0YWxsQ29tbWFuZHMubWFwKGNtZCA9PiAoe1xuICAgICAgICAgIHJ1bjogY21kLFxuICAgICAgICB9KSksXG4gICAgICAgIHtcbiAgICAgICAgICBydW46IGB5YXJuIGFkZCAke3RoaXMucHJvcHMucGtnTmFtZXNwYWNlfS8ke3RoaXMuYXBwLm5hbWV9QFxcJHt7Z2l0aHViLmV2ZW50LmlucHV0cy52ZXJzaW9ufX0gJiYgbXYgLi9ub2RlX21vZHVsZXMvJHt0aGlzLnByb3BzLnBrZ05hbWVzcGFjZX0vJHt0aGlzLmFwcC5uYW1lfSAke3RoaXMuYXBwLmNka0NvbmZpZy5jZGtvdXR9YCxcbiAgICAgICAgfSxcbiAgICAgICAgLi4ub3B0aW9ucy5kZXBsb3lDb21tYW5kcy5tYXAoY21kID0+ICh7XG4gICAgICAgICAgcnVuOiBjbWQsXG4gICAgICAgIH0pKV0sXG4gICAgICB9KTtcblxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBBZGQgZGVwbG95bWVudCB0byBDSS9DRCB3b3JrZmxvd1xuICAgICAgdGhpcy5kZXBsb3ltZW50V29ya2Zsb3cuYWRkSm9iKGBkZXBsb3ktJHtvcHRpb25zLmNvbmZpZy5uYW1lfWAsIHtcbiAgICAgICAgbmFtZTogYERlcGxveSBzdGFnZSAke29wdGlvbnMuY29uZmlnLm5hbWV9IHRvIEFXU2AsXG4gICAgICAgIG5lZWRzOiB0aGlzLmRlcGxveW1lbnRTdGFnZXMubGVuZ3RoID4gMCA/IFsnYXNzZXRVcGxvYWQnLCBgZGVwbG95LSR7dGhpcy5kZXBsb3ltZW50U3RhZ2VzLmF0KC0xKSF9YF0gOiBbJ2Fzc2V0VXBsb2FkJ10sXG4gICAgICAgIHJ1bnNPbjogWyd1YnVudHUtbGF0ZXN0J10sXG4gICAgICAgIGVudjoge1xuICAgICAgICAgIENJOiAndHJ1ZScsXG4gICAgICAgIH0sXG4gICAgICAgIHBlcm1pc3Npb25zOiB7IGlkVG9rZW46IEpvYlBlcm1pc3Npb24uV1JJVEUsIGNvbnRlbnRzOiBKb2JQZXJtaXNzaW9uLlJFQUQgfSxcbiAgICAgICAgc3RlcHM6IFt7XG4gICAgICAgICAgbmFtZTogJ0NoZWNrb3V0JyxcbiAgICAgICAgICB1c2VzOiAnYWN0aW9ucy9jaGVja291dEB2MycsXG4gICAgICAgIH0sIHtcbiAgICAgICAgICBuYW1lOiAnQVdTIENyZWRlbnRpYWxzJyxcbiAgICAgICAgICB1c2VzOiAnYXdzLWFjdGlvbnMvY29uZmlndXJlLWF3cy1jcmVkZW50aWFsc0BtYXN0ZXInLFxuICAgICAgICAgIHdpdGg6IHtcbiAgICAgICAgICAgICdyb2xlLXRvLWFzc3VtZSc6IHRoaXMucHJvcHMuZ2l0aHViQ29uZmlnPy5hd3NSb2xlQXJuRm9yRGVwbG95bWVudD8uW29wdGlvbnMuY29uZmlnLm5hbWVdID8/IHRoaXMucHJvcHMuZ2l0aHViQ29uZmlnPy5kZWZhdWx0QXdzUm9sZUFybixcbiAgICAgICAgICAgICdyb2xlLXNlc3Npb24tbmFtZSc6ICdHaXRIdWJBY3Rpb24nLFxuICAgICAgICAgICAgJ2F3cy1yZWdpb24nOiBvcHRpb25zLmNvbmZpZy5lbnYucmVnaW9uLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB1c2VzOiAnYWN0aW9ucy9kb3dubG9hZC1hcnRpZmFjdEB2MycsXG4gICAgICAgICAgd2l0aDoge1xuICAgICAgICAgICAgbmFtZTogJ2Nsb3VkLWFzc2VtYmx5JyxcbiAgICAgICAgICAgIHBhdGg6IGAke3RoaXMuYXBwLmNka0NvbmZpZy5jZGtvdXR9L2AsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgLi4ub3B0aW9ucy5pbnN0YWxsQ29tbWFuZHMubWFwKGNtZCA9PiAoe1xuICAgICAgICAgIHJ1bjogY21kLFxuICAgICAgICB9KSksXG4gICAgICAgIC4uLm9wdGlvbnMuZGVwbG95Q29tbWFuZHMubWFwKGNtZCA9PiAoe1xuICAgICAgICAgIHJ1bjogY21kLFxuICAgICAgICB9KSldLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmRlcGxveW1lbnRTdGFnZXMucHVzaChvcHRpb25zLmNvbmZpZy5uYW1lKTtcbiAgICB9XG4gIH1cbn0iXX0=
package/lib/pipeline.js DELETED
@@ -1,277 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CDKPipeline = exports.DeploymentType = exports.PipelineEngine = void 0;
4
- const projen_1 = require("projen");
5
- const common_1 = require("projen/lib/common");
6
- const engine_1 = require("./engine");
7
- /**
8
- * The CI/CD tooling used to run your pipeline.
9
- * The component will render workflows for the given system
10
- */
11
- var PipelineEngine;
12
- (function (PipelineEngine) {
13
- /** Create GitHub actions */
14
- PipelineEngine[PipelineEngine["GITHUB"] = 0] = "GITHUB";
15
- /** Create a .gitlab-ci.yaml file */
16
- PipelineEngine[PipelineEngine["GITLAB"] = 1] = "GITLAB";
17
- // /** Create AWS CodeCatalyst workflows */
18
- // CODE_CATALYST,
19
- })(PipelineEngine || (exports.PipelineEngine = PipelineEngine = {}));
20
- /**
21
- * Describes the type of pipeline that will be created
22
- */
23
- var DeploymentType;
24
- (function (DeploymentType) {
25
- /** Deploy every commit as far as possible; hopefully into production */
26
- DeploymentType[DeploymentType["CONTINUOUS_DEPLOYMENT"] = 0] = "CONTINUOUS_DEPLOYMENT";
27
- /** Build every commit and prepare all assets for a later deployment */
28
- DeploymentType[DeploymentType["CONTINUOUS_DELIVERY"] = 1] = "CONTINUOUS_DELIVERY";
29
- })(DeploymentType || (exports.DeploymentType = DeploymentType = {}));
30
- /**
31
- * The CDKPipeline class extends the Component class and sets up the necessary configuration for deploying AWS CDK (Cloud Development Kit) applications across multiple stages.
32
- * It also manages tasks such as publishing CDK assets, bumping version based on git tags, and cleaning up conflicting tasks.
33
- */
34
- class CDKPipeline extends projen_1.Component {
35
- constructor(app, props) {
36
- var _a, _b, _c;
37
- super(app);
38
- this.app = app;
39
- this.props = props;
40
- // Add development dependencies
41
- this.app.addDevDeps('@types/standard-version', 'standard-version', 'cdk-assets');
42
- // this.app.addDeps(
43
- // );
44
- this.stackPrefix = (_a = props.stackPrefix) !== null && _a !== void 0 ? _a : app.name;
45
- // Create engine instance to use
46
- switch (props.engine) {
47
- case PipelineEngine.GITHUB:
48
- this.engine = new engine_1.GitHubEngine(app, props, this);
49
- break;
50
- default:
51
- throw new Error('Invalid engine');
52
- }
53
- // Removes the compiled cloud assembly before each synth
54
- (_b = this.project.tasks.tryFind('synth')) === null || _b === void 0 ? void 0 : _b.prependExec(`rm -rf ${this.app.cdkConfig.cdkout}`);
55
- (_c = this.project.tasks.tryFind('synth:silent')) === null || _c === void 0 ? void 0 : _c.prependExec(`rm -rf ${this.app.cdkConfig.cdkout}`);
56
- // Remove tasks that might conflict with the pipeline process
57
- this.project.removeTask('deploy');
58
- this.project.removeTask('diff');
59
- this.project.removeTask('destroy');
60
- this.project.removeTask('watch');
61
- this.createSynthStage();
62
- // Creates different deployment stages
63
- if (props.personalStage) {
64
- this.createPersonalStage();
65
- }
66
- if (props.featureStages) {
67
- this.createFeatureStage();
68
- }
69
- for (const stage of props.stages) {
70
- this.createPipelineStage(stage);
71
- }
72
- // Creates tasks to handle the release process
73
- this.createReleaseTasks();
74
- // Creates a specialized CDK App class
75
- this.createApplicationEntrypoint();
76
- }
77
- createSynthStage() {
78
- var _a, _b, _c, _d;
79
- this.engine.createSynth({
80
- commands: [
81
- ...((_a = this.props.preInstallCommands) !== null && _a !== void 0 ? _a : []),
82
- `npx projen ${this.app.package.installCiTask.name}`,
83
- ...((_b = this.props.preSynthCommands) !== null && _b !== void 0 ? _b : []),
84
- 'npx projen build',
85
- ...((_c = this.props.postSynthCommands) !== null && _c !== void 0 ? _c : []),
86
- ],
87
- });
88
- this.engine.createAssetUpload({
89
- commands: [
90
- ...((_d = this.props.preInstallCommands) !== null && _d !== void 0 ? _d : []),
91
- `npx projen ${this.app.package.installCiTask.name}`,
92
- 'npx projen publish:assets',
93
- ...(this.engine.needsVersionedArtifacts ? [
94
- 'npx projen bump',
95
- 'npx projen release:push-assembly',
96
- ] : []),
97
- ],
98
- });
99
- }
100
- /**
101
- * This method generates the entry point for the application, including interfaces and classes
102
- * necessary to set up the pipeline and define the AWS CDK stacks for different environments.
103
- */
104
- createApplicationEntrypoint() {
105
- let propsCode = '';
106
- let appCode = '';
107
- if (this.props.personalStage) {
108
- propsCode += ` /** This function will be used to generate a personal stack. */
109
- providePersonalStack: (app: App, stackId: string, props: PipelineAppStackProps) => Stack;
110
- `;
111
- appCode += ` // If the environment variable USER is set and a function is provided for creating a personal stack, it is called with necessary arguments.
112
- if (props.providePersonalStack && process.env.USER) {
113
- const stageName = 'personal-' + process.env.USER.toLowerCase().replace(/\\\//g, '-');
114
- props.providePersonalStack(this, '${this.stackPrefix}-personal', { env: ${JSON.stringify(this.props.personalStage.env)}, stackName: \`${this.stackPrefix}-\${stageName}\`, stageName });
115
- }
116
- `;
117
- }
118
- if (this.props.featureStages) {
119
- propsCode += ` /** This function will be used to generate a feature stack. */
120
- provideFeatureStack: (app: App, stackId: string, props: PipelineAppStackProps) => Stack;
121
- `;
122
- appCode += ` // If the environment variable BRANCH is set and a function is provided for creating a feature stack, it is called with necessary arguments.
123
- if (props.provideFeatureStack && process.env.BRANCH) {
124
- const stageName = 'feature-' + process.env.BRANCH.toLowerCase().replace(/\\\//g, '-');
125
- props.provideFeatureStack(this, '${this.stackPrefix}-feature', { env: ${JSON.stringify(this.props.featureStages.env)}, stackName: \`${this.stackPrefix}-\${stageName}\`, stageName });
126
- }
127
- `;
128
- }
129
- for (const stage of this.props.stages) {
130
- const nameUpperFirst = `${stage.name.charAt(0).toUpperCase()}${stage.name.substring(1)}`;
131
- propsCode += ` /** This function will be used to generate a ${stage.name} stack. */
132
- provide${nameUpperFirst}Stack: (app: App, stackId: string, props: PipelineAppStackProps) => Stack;
133
- `;
134
- appCode += ` // If a function is provided for creating a ${stage.name} stack, it is called with necessary arguments.
135
- if (props.provide${nameUpperFirst}Stack) {
136
- props.provide${nameUpperFirst}Stack(this, '${this.stackPrefix}-${stage.name}', { env: ${JSON.stringify(stage.env)}, stackName: '${this.stackPrefix}-${stage.name}', stageName: '${stage.name}' });
137
- }
138
- `;
139
- }
140
- const appFile = new projen_1.TextFile(this.project, `${this.app.srcdir}/app.ts`);
141
- appFile.addLine(`// ${common_1.PROJEN_MARKER}
142
- /* eslint-disable */
143
- import { App, AppProps, Stack, StackProps } from 'aws-cdk-lib';
144
-
145
- /**
146
- * PipelineAppProps is an extension of AppProps, which is part of the AWS CDK core.
147
- * It includes optional functions to provide AWS Stacks for different stages.
148
- *
149
- * Use these functions to instantiate your application stacks with the parameters for
150
- * each stage
151
- */
152
- export interface PipelineAppProps extends AppProps {
153
- ${propsCode}
154
- }
155
-
156
- /**
157
- * PipelineAppStackProps is an extension of StackProps, which is part of the AWS CDK core.
158
- * It includes an additional property to specify the stage name.
159
- */
160
- export interface PipelineAppStackProps extends StackProps {
161
- stageName: string;
162
- }
163
-
164
- /**
165
- * The PipelineApp class extends the App class from AWS CDK and overrides the constructor to support
166
- * different stages of the application (development, production, personal, feature) by invoking the provided
167
- * stack-providing functions from the props.
168
- */
169
- export class PipelineApp extends App {
170
- constructor(props: PipelineAppProps) {
171
- super(props);
172
-
173
- ${appCode}
174
-
175
- }
176
- }
177
- `);
178
- }
179
- /**
180
- * This method sets up tasks to publish CDK assets to all accounts and handle versioning, including bumping the version
181
- * based on the latest git tag and pushing the CDK assembly to the package repository.
182
- */
183
- createReleaseTasks() {
184
- // Task to publish the CDK assets to all accounts
185
- this.project.addTask('publish:assets', {
186
- steps: this.props.stages.map(stage => ({
187
- exec: `npx cdk-assets -p ${this.app.cdkConfig.cdkout}/${this.stackPrefix}-${stage.name}.assets.json publish`,
188
- })),
189
- });
190
- this.project.addTask('bump', {
191
- description: 'Bumps version based on latest git tag',
192
- steps: [
193
- {
194
- exec: 'pipelines-release bump',
195
- },
196
- {
197
- exec: 'git push --tags',
198
- },
199
- ],
200
- });
201
- this.project.addTask('release:push-assembly', {
202
- steps: [
203
- {
204
- exec: `pipelines-release create-manifest "${this.app.cdkConfig.cdkout}" "${this.props.pkgNamespace}"`,
205
- },
206
- {
207
- cwd: this.app.cdkConfig.cdkout,
208
- exec: 'npm version --no-git-tag-version from-git',
209
- },
210
- {
211
- cwd: this.app.cdkConfig.cdkout,
212
- exec: 'npm publish',
213
- },
214
- ],
215
- });
216
- }
217
- /**
218
- * This method sets up tasks for the personal deployment stage, including deployment, watching for changes,
219
- * comparing changes (diff), and destroying the stack when no longer needed.
220
- */
221
- createPersonalStage() {
222
- this.project.addTask('deploy:personal', {
223
- exec: `cdk deploy ${this.stackPrefix}-personal`,
224
- });
225
- this.project.addTask('watch:personal', {
226
- exec: `cdk deploy --watch --hotswap ${this.stackPrefix}-personal`,
227
- });
228
- this.project.addTask('diff:personal', {
229
- exec: `cdk diff ${this.stackPrefix}-personal`,
230
- });
231
- this.project.addTask('destroy:personal', {
232
- exec: `cdk destroy ${this.stackPrefix}-personal`,
233
- });
234
- }
235
- /**
236
- * This method sets up tasks for the feature deployment stage, including deployment, comparing changes (diff),
237
- * and destroying the stack when no longer needed.
238
- */
239
- createFeatureStage() {
240
- this.project.addTask('deploy:feature', {
241
- exec: `cdk --progress events --require-approval never deploy ${this.stackPrefix}-feature`,
242
- });
243
- this.project.addTask('diff:feature', {
244
- exec: `cdk diff ${this.stackPrefix}-feature`,
245
- });
246
- this.project.addTask('destroy:feature', {
247
- exec: `cdk destroy ${this.stackPrefix}-feature`,
248
- });
249
- }
250
- /**
251
- * This method sets up tasks for the general pipeline stages (dev, prod), including deployment and comparing changes (diff).
252
- * @param {DeployStageOptions} stage - The stage to create
253
- */
254
- createPipelineStage(stage) {
255
- var _a;
256
- this.project.addTask(`deploy:${stage.name}`, {
257
- exec: `cdk --app ${this.app.cdkConfig.cdkout} --progress events --require-approval never deploy ${this.stackPrefix}-${stage.name}`,
258
- });
259
- this.project.addTask(`diff:${stage.name}`, {
260
- exec: `cdk --app ${this.app.cdkConfig.cdkout} diff ${this.stackPrefix}-${stage.name}`,
261
- });
262
- this.engine.createDeployment({
263
- config: stage,
264
- installCommands: [
265
- ...((_a = this.props.preInstallCommands) !== null && _a !== void 0 ? _a : []),
266
- `npx projen ${this.app.package.installCiTask.name}`,
267
- ],
268
- deployCommands: [
269
- // TODO pre deploy steps
270
- `npx projen deploy:${stage.name}`,
271
- // TODO post deploy steps
272
- ],
273
- });
274
- }
275
- }
276
- exports.CDKPipeline = CDKPipeline;
277
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGlwZWxpbmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcGlwZWxpbmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQXFEO0FBQ3JELDhDQUFrRDtBQUNsRCxxQ0FBd0U7QUF1QnhFOzs7R0FHRztBQUNILElBQVksY0FPWDtBQVBELFdBQVksY0FBYztJQUN4Qiw0QkFBNEI7SUFDNUIsdURBQU0sQ0FBQTtJQUNOLG9DQUFvQztJQUNwQyx1REFBTSxDQUFBO0lBQ04sMkNBQTJDO0lBQzNDLGlCQUFpQjtBQUNuQixDQUFDLEVBUFcsY0FBYyw4QkFBZCxjQUFjLFFBT3pCO0FBRUQ7O0dBRUc7QUFDSCxJQUFZLGNBS1g7QUFMRCxXQUFZLGNBQWM7SUFDeEIsd0VBQXdFO0lBQ3hFLHFGQUFxQixDQUFBO0lBQ3JCLHVFQUF1RTtJQUN2RSxpRkFBbUIsQ0FBQTtBQUNyQixDQUFDLEVBTFcsY0FBYyw4QkFBZCxjQUFjLFFBS3pCO0FBa0VEOzs7R0FHRztBQUNILE1BQWEsV0FBWSxTQUFRLGtCQUFTO0lBS3hDLFlBQW9CLEdBQStCLEVBQVUsS0FBeUI7O1FBQ3BGLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQURPLFFBQUcsR0FBSCxHQUFHLENBQTRCO1FBQVUsVUFBSyxHQUFMLEtBQUssQ0FBb0I7UUFHcEYsK0JBQStCO1FBQy9CLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUNqQix5QkFBeUIsRUFDekIsa0JBQWtCLEVBQ2xCLFlBQVksQ0FDYixDQUFDO1FBQ0Ysb0JBQW9CO1FBQ3BCLEtBQUs7UUFFTCxJQUFJLENBQUMsV0FBVyxHQUFHLE1BQUEsS0FBSyxDQUFDLFdBQVcsbUNBQUksR0FBRyxDQUFDLElBQUksQ0FBQztRQUVqRCxnQ0FBZ0M7UUFDaEMsUUFBUSxLQUFLLENBQUMsTUFBTSxFQUFFO1lBQ3BCLEtBQUssY0FBYyxDQUFDLE1BQU07Z0JBQ3hCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxxQkFBWSxD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QyxXQUFXLFVBQVU7U0FDaEQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7T0FHRztJQUNLLG1CQUFtQixDQUFDLEtBQXNCOztRQUNoRCxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxVQUFVLEtBQUssQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUMzQyxJQUFJLEVBQUUsYUFBYSxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxNQUFNLHNEQUFzRCxJQUFJLENBQUMsV0FBVyxJQUFJLEtBQUssQ0FBQyxJQUFJLEVBQUU7U0FDbkksQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsUUFBUSxLQUFLLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFDekMsSUFBSSxFQUFFLGFBQWEsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsTUFBTSxTQUFTLElBQUksQ0FBQyxXQUFXLElBQUksS0FBSyxDQUFDLElBQUksRUFBRTtTQUN0RixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDO1lBQzNCLE1BQU0sRUFBRSxLQUFLO1lBQ2IsZUFBZSxFQUFFO2dCQUNmLEdBQUcsQ0FBQyxNQUFBLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLG1DQUFJLEVBQUUsQ0FBQztnQkFDeEMsY0FBYyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFO2FBQ3BEO1lBQ0QsY0FBYyxFQUFFO2dCQUNkLHdCQUF3QjtnQkFDeEIscUJBQXFCLEtBQUssQ0FBQyxJQUFJLEVBQUU7Z0JBQ2pDLHlCQUF5QjthQUMxQjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQTNRRCxrQ0EyUUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIFRleHRGaWxlLCBhd3NjZGsgfSBmcm9tICdwcm9qZW4nO1xuaW1wb3J0IHsgUFJPSkVOX01BUktFUiB9IGZyb20gJ3Byb2plbi9saWIvY29tbW9uJztcbmltcG9ydCB7IEJhc2VFbmdpbmUsIEdpdEh1YkVuZ2luZSwgR2l0aHViRW5naW5lQ29uZmlnIH0gZnJvbSAnLi9lbmdpbmUnO1xuXG4vKipcbiAqIFRoZSBFbnZpcm9ubWVudCBpbnRlcmZhY2UgaXMgZGVzaWduZWQgdG8gaG9sZCBBV1MgcmVsYXRlZCBpbmZvcm1hdGlvblxuICogZm9yIGEgc3BlY2lmaWMgZGVwbG95bWVudCBlbnZpcm9ubWVudCB3aXRoaW4geW91ciBpbmZyYXN0cnVjdHVyZS5cbiAqIEVhY2ggZW52aXJvbm1lbnQgcmVxdWlyZXMgYSBzcGVjaWZpYyBhY2NvdW50IGFuZCByZWdpb24gZm9yIGl0cyByZXNvdXJjZXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRW52aXJvbm1lbnQge1xuICAvKipcbiAgICogVGhlIEFXUyBBY2NvdW50IElEIGFzc29jaWF0ZWQgd2l0aCB0aGUgZW52aXJvbm1lbnQuIEl0J3MgaW1wb3J0YW50IGJlY2F1c2VcbiAgICogZGlmZmVyZW50IHNlcnZpY2VzIG9yIGZlYXR1cmVzIGNvdWxkIGhhdmUgZGlzdGluY3QgcGVybWlzc2lvbnMgYW5kIHNldHRpbmdzXG4gICAqIGluIGRpZmZlcmVudCBhY2NvdW50cy5cbiAgICovXG4gIHJlYWRvbmx5IGFjY291bnQ6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIEFXUyBSZWdpb24gZm9yIHRoZSBlbnZpcm9ubWVudC4gVGhpcyBkZXRlcm1pbmVzIHdoZXJlIHlvdXIgcmVzb3VyY2VzXG4gICAqIGFyZSBjcmVhdGVkIGFuZCB3aGVyZSB5b3VyIGFwcGxpY2F0aW9uIHdpbGwgcnVuLiBJdCBjYW4gYWZmZWN0IGxhdGVuY3ksXG4gICAqIGF2YWlsYWJpbGl0eSwgYW5kIHByaWNpbmcuXG4gICAqL1xuICByZWFkb25seSByZWdpb246IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGUgQ0kvQ0QgdG9vbGluZyB1c2VkIHRvIHJ1biB5b3VyIHBpcGVsaW5lLlxuICogVGhlIGNvbXBvbmVudCB3aWxsIHJlbmRlciB3b3JrZmxvd3MgZm9yIHRoZSBnaXZlbiBzeXN0ZW1cbiAqL1xuZXhwb3J0IGVudW0gUGlwZWxpbmVFbmdpbmUge1xuICAvKiogQ3JlYXRlIEdpdEh1YiBhY3Rpb25zICovXG4gIEdJVEhVQixcbiAgLyoqIENyZWF0ZSBhIC5naXRsYWItY2kueWFtbCBmaWxlICovXG4gIEdJVExBQixcbiAgLy8gLyoqIENyZWF0ZSBBV1MgQ29kZUNhdGFseXN0IHdvcmtmbG93cyAqL1xuICAvLyBDT0RFX0NBVEFMWVNULFxufVxuXG4vKipcbiAqIERlc2NyaWJlcyB0aGUgdHlwZSBvZiBwaXBlbGluZSB0aGF0IHdpbGwgYmUgY3JlYXRlZFxuICovXG5leHBvcnQgZW51bSBEZXBsb3ltZW50VHlwZSB7XG4gIC8qKiBEZXBsb3kgZXZlcnkgY29tbWl0IGFzIGZhciBhcyBwb3NzaWJsZTsgaG9wZWZ1bGx5IGludG8gcHJvZHVjdGlvbiAqL1xuICBDT05USU5VT1VTX0RFUExPWU1FTlQsXG4gIC8qKiBCdWlsZCBldmVyeSBjb21taXQgYW5kIHByZXBhcmUgYWxsIGFzc2V0cyBmb3IgYSBsYXRlciBkZXBsb3ltZW50ICovXG4gIENPTlRJTlVPVVNfREVMSVZFUlksXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVwbG95bWVudFN0YWdlIHtcbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICByZWFkb25seSBlbnY6IEVudmlyb25tZW50O1xuICByZWFkb25seSBtYW51YWxBcHByb3ZhbD86IGJvb2xlYW47XG59XG5cbi8qKlxuICogVGhlIENES1BpcGVsaW5lT3B0aW9ucyBpbnRlcmZhY2UgaXMgZGVzaWduZWQgdG8gcHJvdmlkZSBjb25maWd1cmF0aW9uXG4gKiBvcHRpb25zIGZvciBhIENESyAoQ2xvdWQgRGV2ZWxvcG1lbnQgS2l0KSBwaXBlbGluZS4gSXQgYWxsb3dzIHRoZSBkZWZpbml0aW9uXG4gKiBvZiBzZXR0aW5ncyBzdWNoIGFzIHRoZSBzdGFjayBwcmVmaXggYW5kIHBhY2thZ2UgbmFtZXNwYWNlIHRvIGJlIHVzZWQgaW4gdGhlXG4gKiBBV1Mgc3RhY2ssIGFsb25nIHdpdGggdGhlIGVudmlyb25tZW50cyBjb25maWd1cmF0aW9uIHRvIGJlIHVzZWQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ0RLUGlwZWxpbmVPcHRpb25zIHtcblxuICAvKipcbiAgICogVGhpcyBmaWVsZCBpcyB1c2VkIHRvIGRlZmluZSBhIHByZWZpeCBmb3IgdGhlIEFXUyBTdGFjayByZXNvdXJjZXMgY3JlYXRlZFxuICAgKiBkdXJpbmcgdGhlIHBpcGVsaW5lJ3Mgb3BlcmF0aW9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCBwcm9qZWN0IG5hbWVcbiAgICovXG4gIHJlYWRvbmx5IHN0YWNrUHJlZml4Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGlzIGZpZWxkIGRldGVybWluZXMgdGhlIE5QTSBuYW1lc3BhY2UgdG8gYmUgdXNlZCB3aGVuIHBhY2thZ2luZyBDREsgY2xvdWRcbiAgICogYXNzZW1ibGllcy4gQSBuYW1lc3BhY2UgaGVscHMgZ3JvdXAgcmVsYXRlZCByZXNvdXJjZXMgdG9nZXRoZXIsIHByb3ZpZGluZ1xuICAgKiBiZXR0ZXIgb3JnYW5pemF0aW9uIGFuZCBlYXNlIG9mIG1hbmFnZW1lbnQuXG4gICAqL1xuICByZWFkb25seSBwa2dOYW1lc3BhY2U6IHN0cmluZztcblxuICByZWFkb25seSBzdGFnZXM6IERlcGxveW1lbnRTdGFnZVtdO1xuXG4gIHJlYWRvbmx5IHBlcnNvbmFsU3RhZ2U/OiB7XG4gICAgcmVhZG9ubHkgZW52OiBFbnZpcm9ubWVudDtcbiAgfTtcblxuICByZWFkb25seSBmZWF0dXJlU3RhZ2VzPzoge1xuICAgIHJlYWRvbmx5IGVudjogRW52aXJvbm1lbnQ7XG4gIH07XG5cbiAgLyoqXG4gICAqIFRoaXMgZmllbGQgc3BlY2lmaWVzIHRoZSB0eXBlIG9mIHBpcGVsaW5lIHRvIGNyZWF0ZS4gSWYgc2V0IHRvIENPTlRJTlVPVVNfREVQTE9ZTUVOVCxcbiAgICogZXZlcnkgY29tbWl0IGlzIGRlcGxveWVkIGFzIGZhciBhcyBwb3NzaWJsZSwgaG9wZWZ1bGx5IGludG8gcHJvZHVjdGlvbi4gSWYgc2V0IHRvXG4gICAqIENPTlRJTlVPVVNfREVMSVZFUlksIGV2ZXJ5IGNvbW1pdCBpcyBidWlsdCBhbmQgYWxsIGFzc2V0cyBhcmUgcHJlcGFyZWQgZm9yIGEgbGF0ZXIgZGVwbG95bWVudC5cbiAgICpcbiAgICogQGRlZmF1bHQgQ09OVElOVU9VU19ERUxJVkVSWVxuICAgKi9cbiAgcmVhZG9ubHkgZGVwbG95bWVudFR5cGU/OiBEZXBsb3ltZW50VHlwZTtcblxuICAvKipcbiAgICogVGhpcyBmaWVsZCBkZXRlcm1pbmVzIHRoZSBDSS9DRCB0b29saW5nIHRoYXQgd2lsbCBiZSB1c2VkIHRvIHJ1biB0aGUgcGlwZWxpbmUuIFRoZSBjb21wb25lbnRcbiAgICogd2lsbCByZW5kZXIgd29ya2Zsb3dzIGZvciB0aGUgZ2l2ZW4gc3lzdGVtLiBPcHRpb25zIGluY2x1ZGUgR2l0SHViIGFuZCBHaXRMYWIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdHJpZXMgdG8gZGVyaXZlIGl0IGZyb20gdGhlIHByb2plY3RzIGNvbmZpZ3VyYXRpb25cbiAgICovXG4gIHJlYWRvbmx5IGVuZ2luZT86IFBpcGVsaW5lRW5naW5lO1xuXG4gIHJlYWRvbmx5IGdpdGh1YkNvbmZpZz86IEdpdGh1YkVuZ2luZUNvbmZpZztcblxuICByZWFkb25seSBwcmVJbnN0YWxsQ29tbWFuZHM/OiBzdHJpbmdbXTtcbiAgcmVhZG9ubHkgcHJlU3ludGhDb21tYW5kcz86IHN0cmluZ1tdO1xuICByZWFkb25seSBwb3N0U3ludGhDb21tYW5kcz86IHN0cmluZ1tdO1xuXG59XG5cbi8qKlxuICogVGhlIENES1BpcGVsaW5lIGNsYXNzIGV4dGVuZHMgdGhlIENvbXBvbmVudCBjbGFzcyBhbmQgc2V0cyB1cCB0aGUgbmVjZXNzYXJ5IGNvbmZpZ3VyYXRpb24gZm9yIGRlcGxveWluZyBBV1MgQ0RLIChDbG91ZCBEZXZlbG9wbWVudCBLaXQpIGFwcGxpY2F0aW9ucyBhY3Jvc3MgbXVsdGlwbGUgc3RhZ2VzLlxuICogSXQgYWxzbyBtYW5hZ2VzIHRhc2tzIHN1Y2ggYXMgcHVibGlzaGluZyBDREsgYXNzZXRzLCBidW1waW5nIHZlcnNpb24gYmFzZWQgb24gZ2l0IHRhZ3MsIGFuZCBjbGVhbmluZyB1cCBjb25mbGljdGluZyB0YXNrcy5cbiAqL1xuZXhwb3J0IGNsYXNzIENES1BpcGVsaW5lIGV4dGVuZHMgQ29tcG9uZW50IHtcblxuICBwdWJsaWMgcmVhZG9ubHkgc3RhY2tQcmVmaXg6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGVuZ2luZTogQmFzZUVuZ2luZTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGFwcDogYXdzY2RrLkF3c0Nka1R5cGVTY3JpcHRBcHAsIHByaXZhdGUgcHJvcHM6IENES1BpcGVsaW5lT3B0aW9ucykge1xuICAgIHN1cGVyKGFwcCk7XG5cbiAgICAvLyBBZGQgZGV2ZWxvcG1lbnQgZGVwZW5kZW5jaWVzXG4gICAgdGhpcy5hcHAuYWRkRGV2RGVwcyhcbiAgICAgICdAdHlwZXMvc3RhbmRhcmQtdmVyc2lvbicsXG4gICAgICAnc3RhbmRhcmQtdmVyc2lvbicsXG4gICAgICAnY2RrLWFzc2V0cycsXG4gICAgKTtcbiAgICAvLyB0aGlzLmFwcC5hZGREZXBzKFxuICAgIC8vICk7XG5cbiAgICB0aGlzLnN0YWNrUHJlZml4ID0gcHJvcHMuc3RhY2tQcmVmaXggPz8gYXBwLm5hbWU7XG5cbiAgICAvLyBDcmVhdGUgZW5naW5lIGluc3RhbmNlIHRvIHVzZVxuICAgIHN3aXRjaCAocHJvcHMuZW5naW5lKSB7XG4gICAgICBjYXNlIFBpcGVsaW5lRW5naW5lLkdJVEhVQjpcbiAgICAgICAgdGhpcy5lbmdpbmUgPSBuZXcgR2l0SHViRW5naW5lKGFwcCwgcHJvcHMsIHRoaXMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBlbmdpbmUnKTtcbiAgICB9XG5cbiAgICAvLyBSZW1vdmVzIHRoZSBjb21waWxlZCBjbG91ZCBhc3NlbWJseSBiZWZvcmUgZWFjaCBzeW50aFxuICAgIHRoaXMucHJvamVjdC50YXNrcy50cnlGaW5kKCdzeW50aCcpPy5wcmVwZW5kRXhlYyhgcm0gLXJmICR7dGhpcy5hcHAuY2RrQ29uZmlnLmNka291dH1gKTtcbiAgICB0aGlzLnByb2plY3QudGFza3MudHJ5RmluZCgnc3ludGg6c2lsZW50Jyk/LnByZXBlbmRFeGVjKGBybSAtcmYgJHt0aGlzLmFwcC5jZGtDb25maWcuY2Rrb3V0fWApO1xuXG4gICAgLy8gUmVtb3ZlIHRhc2tzIHRoYXQgbWlnaHQgY29uZmxpY3Qgd2l0aCB0aGUgcGlwZWxpbmUgcHJvY2Vzc1xuICAgIHRoaXMucHJvamVjdC5yZW1vdmVUYXNrKCdkZXBsb3knKTtcbiAgICB0aGlzLnByb2plY3QucmVtb3ZlVGFzaygnZGlmZicpO1xuICAgIHRoaXMucHJvamVjdC5yZW1vdmVUYXNrKCdkZXN0cm95Jyk7XG4gICAgdGhpcy5wcm9qZWN0LnJlbW92ZVRhc2soJ3dhdGNoJyk7XG5cbiAgICB0aGlzLmNyZWF0ZVN5bnRoU3RhZ2UoKTtcblxuICAgIC8vIENyZWF0ZXMgZGlmZmVyZW50IGRlcGxveW1lbnQgc3RhZ2VzXG4gICAgaWYgKHByb3BzLnBlcnNvbmFsU3RhZ2UpIHtcbiAgICAgIHRoaXMuY3JlYXRlUGVyc29uYWxTdGFnZSgpO1xuICAgIH1cbiAgICBpZiAocHJvcHMuZmVhdHVyZVN0YWdlcykge1xuICAgICAgdGhpcy5jcmVhdGVGZWF0dXJlU3RhZ2UoKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBzdGFnZSBvZiBwcm9wcy5zdGFnZXMpIHtcbiAgICAgIHRoaXMuY3JlYXRlUGlwZWxpbmVTdGFnZShzdGFnZSk7XG4gICAgfVxuXG4gICAgLy8gQ3JlYXRlcyB0YXNrcyB0byBoYW5kbGUgdGhlIHJlbGVhc2UgcHJvY2Vzc1xuICAgIHRoaXMuY3JlYXRlUmVsZWFzZVRhc2tzKCk7XG5cbiAgICAvLyBDcmVhdGVzIGEgc3BlY2lhbGl6ZWQgQ0RLIEFwcCBjbGFzc1xuICAgIHRoaXMuY3JlYXRlQXBwbGljYXRpb25FbnRyeXBvaW50KCk7XG5cbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlU3ludGhTdGFnZSgpIHtcbiAgICB0aGlzLmVuZ2luZS5jcmVhdGVTeW50aCh7XG4gICAgICBjb21tYW5kczogW1xuICAgICAgICAuLi4odGhpcy5wcm9wcy5wcmVJbnN0YWxsQ29tbWFuZHMgPz8gW10pLFxuICAgICAgICBgbnB4IHByb2plbiAke3RoaXMuYXBwLnBhY2thZ2UuaW5zdGFsbENpVGFzay5uYW1lfWAsXG4gICAgICAgIC4uLih0aGlzLnByb3BzLnByZVN5bnRoQ29tbWFuZHMgPz8gW10pLFxuICAgICAgICAnbnB4IHByb2plbiBidWlsZCcsXG4gICAgICAgIC4uLih0aGlzLnByb3BzLnBvc3RTeW50aENvbW1hbmRzID8/IFtdKSxcbiAgICAgIF0sXG4gICAgfSk7XG4gICAgdGhpcy5lbmdpbmUuY3JlYXRlQXNzZXRVcGxvYWQoe1xuICAgICAgY29tbWFuZHM6IFtcbiAgICAgICAgLi4uKHRoaXMucHJvcHMucHJlSW5zdGFsbENvbW1hbmRzID8/IFtdKSxcbiAgICAgICAgYG5weCBwcm9qZW4gJHt0aGlzLmFwcC5wYWNrYWdlLmluc3RhbGxDaVRhc2submFtZX1gLFxuICAgICAgICAnbnB4IHByb2plbiBwdWJsaXNoOmFzc2V0cycsXG4gICAgICAgIC4uLih0aGlzLmVuZ2luZS5uZWVkc1ZlcnNpb25lZEFydGlmYWN0cyA/IFtcbiAgICAgICAgICAnbnB4IHByb2plbiBidW1wJyxcbiAgICAgICAgICAnbnB4IHByb2plbiByZWxlYXNlOnB1c2gtYXNzZW1ibHknLFxuICAgICAgICBdIDogW10pLFxuICAgICAgXSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBnZW5lcmF0ZXMgdGhlIGVudHJ5IHBvaW50IGZvciB0aGUgYXBwbGljYXRpb24sIGluY2x1ZGluZyBpbnRlcmZhY2VzIGFuZCBjbGFzc2VzXG4gICAqIG5lY2Vzc2FyeSB0byBzZXQgdXAgdGhlIHBpcGVsaW5lIGFuZCBkZWZpbmUgdGhlIEFXUyBDREsgc3RhY2tzIGZvciBkaWZmZXJlbnQgZW52aXJvbm1lbnRzLlxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVBcHBsaWNhdGlvbkVudHJ5cG9pbnQoKSB7XG4gICAgbGV0IHByb3BzQ29kZSA9ICcnO1xuICAgIGxldCBhcHBDb2RlID0gJyc7XG5cbiAgICBpZiAodGhpcy5wcm9wcy5wZXJzb25hbFN0YWdlKSB7XG4gICAgICBwcm9wc0NvZGUgKz0gYCAgLyoqIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSB1c2VkIHRvIGdlbmVyYXRlIGEgcGVyc29uYWwgc3RhY2suICovXG4gIHByb3ZpZGVQZXJzb25hbFN0YWNrOiAoYXBwOiBBcHAsIHN0YWNrSWQ6IHN0cmluZywgcHJvcHM6IFBpcGVsaW5lQXBwU3RhY2tQcm9wcykgPT4gU3RhY2s7XG5gO1xuICAgICAgYXBwQ29kZSArPSBgICAgIC8vIElmIHRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZSBVU0VSIGlzIHNldCBhbmQgYSBmdW5jdGlvbiBpcyBwcm92aWRlZCBmb3IgY3JlYXRpbmcgYSBwZXJzb25hbCBzdGFjaywgaXQgaXMgY2FsbGVkIHdpdGggbmVjZXNzYXJ5IGFyZ3VtZW50cy5cbiAgICBpZiAocHJvcHMucHJvdmlkZVBlcnNvbmFsU3RhY2sgJiYgcHJvY2Vzcy5lbnYuVVNFUikge1xuICAgICAgY29uc3Qgc3RhZ2VOYW1lID0gJ3BlcnNvbmFsLScgKyBwcm9jZXNzLmVudi5VU0VSLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvXFxcXFxcLy9nLCAnLScpO1xuICAgICAgcHJvcHMucHJvdmlkZVBlcnNvbmFsU3RhY2sodGhpcywgJyR7dGhpcy5zdGFja1ByZWZpeH0tcGVyc29uYWwnLCB7IGVudjogJHtKU09OLnN0cmluZ2lmeSh0aGlzLnByb3BzLnBlcnNvbmFsU3RhZ2UuZW52KX0sIHN0YWNrTmFtZTogXFxgJHt0aGlzLnN0YWNrUHJlZml4fS1cXCR7c3RhZ2VOYW1lfVxcYCwgc3RhZ2VOYW1lIH0pO1xuICAgIH1cbmA7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucHJvcHMuZmVhdHVyZVN0YWdlcykge1xuICAgICAgcHJvcHNDb2RlICs9IGAgIC8qKiBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgdXNlZCB0byBnZW5lcmF0ZSBhIGZlYXR1cmUgc3RhY2suICovXG4gIHByb3ZpZGVGZWF0dXJlU3RhY2s6IChhcHA6IEFwcCwgc3RhY2tJZDogc3RyaW5nLCBwcm9wczogUGlwZWxpbmVBcHBTdGFja1Byb3BzKSA9PiBTdGFjaztcbmA7XG4gICAgICBhcHBDb2RlICs9IGAgICAgLy8gSWYgdGhlIGVudmlyb25tZW50IHZhcmlhYmxlIEJSQU5DSCBpcyBzZXQgYW5kIGEgZnVuY3Rpb24gaXMgcHJvdmlkZWQgZm9yIGNyZWF0aW5nIGEgZmVhdHVyZSBzdGFjaywgaXQgaXMgY2FsbGVkIHdpdGggbmVjZXNzYXJ5IGFyZ3VtZW50cy5cbiAgICBpZiAocHJvcHMucHJvdmlkZUZlYXR1cmVTdGFjayAmJiBwcm9jZXNzLmVudi5CUkFOQ0gpIHtcbiAgICAgIGNvbnN0IHN0YWdlTmFtZSA9ICdmZWF0dXJlLScgKyBwcm9jZXNzLmVudi5CUkFOQ0gudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9cXFxcXFwvL2csICctJyk7XG4gICAgICBwcm9wcy5wcm92aWRlRmVhdHVyZVN0YWNrKHRoaXMsICcke3RoaXMuc3RhY2tQcmVmaXh9LWZlYXR1cmUnLCB7IGVudjogJHtKU09OLnN0cmluZ2lmeSh0aGlzLnByb3BzLmZlYXR1cmVTdGFnZXMuZW52KX0sIHN0YWNrTmFtZTogXFxgJHt0aGlzLnN0YWNrUHJlZml4fS1cXCR7c3RhZ2VOYW1lfVxcYCwgc3RhZ2VOYW1lIH0pO1xuICAgIH1cbmA7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBzdGFnZSBvZiB0aGlzLnByb3BzLnN0YWdlcykge1xuICAgICAgY29uc3QgbmFtZVVwcGVyRmlyc3QgPSBgJHtzdGFnZS5uYW1lLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpfSR7c3RhZ2UubmFtZS5zdWJzdHJpbmcoMSl9YDtcblxuICAgICAgcHJvcHNDb2RlICs9IGAgIC8qKiBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgdXNlZCB0byBnZW5lcmF0ZSBhICR7c3RhZ2UubmFtZX0gc3RhY2suICovXG4gIHByb3ZpZGUke25hbWVVcHBlckZpcnN0fVN0YWNrOiAoYXBwOiBBcHAsIHN0YWNrSWQ6IHN0cmluZywgcHJvcHM6IFBpcGVsaW5lQXBwU3RhY2tQcm9wcykgPT4gU3RhY2s7XG5gO1xuICAgICAgYXBwQ29kZSArPSBgICAgIC8vIElmIGEgZnVuY3Rpb24gaXMgcHJvdmlkZWQgZm9yIGNyZWF0aW5nIGEgJHtzdGFnZS5uYW1lfSBzdGFjaywgaXQgaXMgY2FsbGVkIHdpdGggbmVjZXNzYXJ5IGFyZ3VtZW50cy5cbiAgICBpZiAocHJvcHMucHJvdmlkZSR7bmFtZVVwcGVyRmlyc3R9U3RhY2spIHtcbiAgICAgIHByb3BzLnByb3ZpZGUke25hbWVVcHBlckZpcnN0fVN0YWNrKHRoaXMsICcke3RoaXMuc3RhY2tQcmVmaXh9LSR7c3RhZ2UubmFtZX0nLCB7IGVudjogJHtKU09OLnN0cmluZ2lmeShzdGFnZS5lbnYpfSwgc3RhY2tOYW1lOiAnJHt0aGlzLnN0YWNrUHJlZml4fS0ke3N0YWdlLm5hbWV9Jywgc3RhZ2VOYW1lOiAnJHtzdGFnZS5uYW1lfScgfSk7XG4gICAgfVxuYDtcbiAgICB9XG5cbiAgICBjb25zdCBhcHBGaWxlID0gbmV3IFRleHRGaWxlKHRoaXMucHJvamVjdCwgYCR7dGhpcy5hcHAuc3JjZGlyfS9hcHAudHNgKTtcbiAgICBhcHBGaWxlLmFkZExpbmUoYC8vICR7UFJPSkVOX01BUktFUn1cbi8qIGVzbGludC1kaXNhYmxlICovXG5pbXBvcnQgeyBBcHAsIEFwcFByb3BzLCBTdGFjaywgU3RhY2tQcm9wcyB9IGZyb20gJ2F3cy1jZGstbGliJztcblxuLyoqXG4gKiBQaXBlbGluZUFwcFByb3BzIGlzIGFuIGV4dGVuc2lvbiBvZiBBcHBQcm9wcywgd2hpY2ggaXMgcGFydCBvZiB0aGUgQVdTIENESyBjb3JlLlxuICogSXQgaW5jbHVkZXMgb3B0aW9uYWwgZnVuY3Rpb25zIHRvIHByb3ZpZGUgQVdTIFN0YWNrcyBmb3IgZGlmZmVyZW50IHN0YWdlcy5cbiAqXG4gKiBVc2UgdGhlc2UgZnVuY3Rpb25zIHRvIGluc3RhbnRpYXRlIHlvdXIgYXBwbGljYXRpb24gc3RhY2tzIHdpdGggdGhlIHBhcmFtZXRlcnMgZm9yXG4gKiBlYWNoIHN0YWdlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGlwZWxpbmVBcHBQcm9wcyBleHRlbmRzIEFwcFByb3BzIHtcbiR7cHJvcHNDb2RlfVxufVxuXG4vKipcbiAqIFBpcGVsaW5lQXBwU3RhY2tQcm9wcyBpcyBhbiBleHRlbnNpb24gb2YgU3RhY2tQcm9wcywgd2hpY2ggaXMgcGFydCBvZiB0aGUgQVdTIENESyBjb3JlLlxuICogSXQgaW5jbHVkZXMgYW4gYWRkaXRpb25hbCBwcm9wZXJ0eSB0byBzcGVjaWZ5IHRoZSBzdGFnZSBuYW1lLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBpcGVsaW5lQXBwU3RhY2tQcm9wcyBleHRlbmRzIFN0YWNrUHJvcHMge1xuICBzdGFnZU5hbWU6IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGUgUGlwZWxpbmVBcHAgY2xhc3MgZXh0ZW5kcyB0aGUgQXBwIGNsYXNzIGZyb20gQVdTIENESyBhbmQgb3ZlcnJpZGVzIHRoZSBjb25zdHJ1Y3RvciB0byBzdXBwb3J0XG4gKiBkaWZmZXJlbnQgc3RhZ2VzIG9mIHRoZSBhcHBsaWNhdGlvbiAoZGV2ZWxvcG1lbnQsIHByb2R1Y3Rpb24sIHBlcnNvbmFsLCBmZWF0dXJlKSBieSBpbnZva2luZyB0aGUgcHJvdmlkZWRcbiAqIHN0YWNrLXByb3ZpZGluZyBmdW5jdGlvbnMgZnJvbSB0aGUgcHJvcHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBQaXBlbGluZUFwcCBleHRlbmRzIEFwcCB7XG4gIGNvbnN0cnVjdG9yKHByb3BzOiBQaXBlbGluZUFwcFByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuXG4ke2FwcENvZGV9XG5cbiAgfVxufVxuYCk7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBtZXRob2Qgc2V0cyB1cCB0YXNrcyB0byBwdWJsaXNoIENESyBhc3NldHMgdG8gYWxsIGFjY291bnRzIGFuZCBoYW5kbGUgdmVyc2lvbmluZywgaW5jbHVkaW5nIGJ1bXBpbmcgdGhlIHZlcnNpb25cbiAgICogYmFzZWQgb24gdGhlIGxhdGVzdCBnaXQgdGFnIGFuZCBwdXNoaW5nIHRoZSBDREsgYXNzZW1ibHkgdG8gdGhlIHBhY2thZ2UgcmVwb3NpdG9yeS5cbiAgICovXG4gIHByaXZhdGUgY3JlYXRlUmVsZWFzZVRhc2tzKCkge1xuICAgIC8vIFRhc2sgdG8gcHVibGlzaCB0aGUgQ0RLIGFzc2V0cyB0byBhbGwgYWNjb3VudHNcbiAgICB0aGlzLnByb2plY3QuYWRkVGFzaygncHVibGlzaDphc3NldHMnLCB7XG4gICAgICBzdGVwczogdGhpcy5wcm9wcy5zdGFnZXMubWFwKHN0YWdlID0+ICh7XG4gICAgICAgIGV4ZWM6IGBucHggY2RrLWFzc2V0cyAtcCAke3RoaXMuYXBwLmNka0NvbmZpZy5jZGtvdXR9LyR7dGhpcy5zdGFja1ByZWZpeH0tJHtzdGFnZS5uYW1lfS5hc3NldHMuanNvbiBwdWJsaXNoYCxcbiAgICAgIH0pKSxcbiAgICB9KTtcblxuICAgIHRoaXMucHJvamVjdC5hZGRUYXNrKCdidW1wJywge1xuICAgICAgZGVzY3JpcHRpb246ICdCdW1wcyB2ZXJzaW9uIGJhc2VkIG9uIGxhdGVzdCBnaXQgdGFnJyxcbiAgICAgIHN0ZXBzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBleGVjOiAncGlwZWxpbmVzLXJlbGVhc2UgYnVtcCcsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBleGVjOiAnZ2l0IHB1c2ggLS10YWdzJyxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG4gICAgdGhpcy5wcm9qZWN0LmFkZFRhc2soJ3JlbGVhc2U6cHVzaC1hc3NlbWJseScsIHtcbiAgICAgIHN0ZXBzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBleGVjOiBgcGlwZWxpbmVzLXJlbGVhc2UgY3JlYXRlLW1hbmlmZXN0IFwiJHt0aGlzLmFwcC5jZGtDb25maWcuY2Rrb3V0fVwiICBcIiR7dGhpcy5wcm9wcy5wa2dOYW1lc3BhY2V9XCJgLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgY3dkOiB0aGlzLmFwcC5jZGtDb25maWcuY2Rrb3V0LFxuICAgICAgICAgIGV4ZWM6ICducG0gdmVyc2lvbiAtLW5vLWdpdC10YWctdmVyc2lvbiBmcm9tLWdpdCcsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBjd2Q6IHRoaXMuYXBwLmNka0NvbmZpZy5jZGtvdXQsXG4gICAgICAgICAgZXhlYzogJ25wbSBwdWJsaXNoJyxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBtZXRob2Qgc2V0cyB1cCB0YXNrcyBmb3IgdGhlIHBlcnNvbmFsIGRlcGxveW1lbnQgc3RhZ2UsIGluY2x1ZGluZyBkZXBsb3ltZW50LCB3YXRjaGluZyBmb3IgY2hhbmdlcyxcbiAgICogY29tcGFyaW5nIGNoYW5nZXMgKGRpZmYpLCBhbmQgZGVzdHJveWluZyB0aGUgc3RhY2sgd2hlbiBubyBsb25nZXIgbmVlZGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVQZXJzb25hbFN0YWdlKCkge1xuICAgIHRoaXMucHJvamVjdC5hZGRUYXNrKCdkZXBsb3k6cGVyc29uYWwnLCB7XG4gICAgICBleGVjOiBgY2RrIGRlcGxveSAke3RoaXMuc3RhY2tQcmVmaXh9LXBlcnNvbmFsYCxcbiAgICB9KTtcbiAgICB0aGlzLnByb2plY3QuYWRkVGFzaygnd2F0Y2g6cGVyc29uYWwnLCB7XG4gICAgICBleGVjOiBgY2RrIGRlcGxveSAtLXdhdGNoIC0taG90c3dhcCAke3RoaXMuc3RhY2tQcmVmaXh9LXBlcnNvbmFsYCxcbiAgICB9KTtcbiAgICB0aGlzLnByb2plY3QuYWRkVGFzaygnZGlmZjpwZXJzb25hbCcsIHtcbiAgICAgIGV4ZWM6IGBjZGsgZGlmZiAke3RoaXMuc3RhY2tQcmVmaXh9LXBlcnNvbmFsYCxcbiAgICB9KTtcbiAgICB0aGlzLnByb2plY3QuYWRkVGFzaygnZGVzdHJveTpwZXJzb25hbCcsIHtcbiAgICAgIGV4ZWM6IGBjZGsgZGVzdHJveSAke3RoaXMuc3RhY2tQcmVmaXh9LXBlcnNvbmFsYCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBzZXRzIHVwIHRhc2tzIGZvciB0aGUgZmVhdHVyZSBkZXBsb3ltZW50IHN0YWdlLCBpbmNsdWRpbmcgZGVwbG95bWVudCwgY29tcGFyaW5nIGNoYW5nZXMgKGRpZmYpLFxuICAgKiBhbmQgZGVzdHJveWluZyB0aGUgc3RhY2sgd2hlbiBubyBsb25nZXIgbmVlZGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVGZWF0dXJlU3RhZ2UoKSB7XG4gICAgdGhpcy5wcm9qZWN0LmFkZFRhc2soJ2RlcGxveTpmZWF0dXJlJywge1xuICAgICAgZXhlYzogYGNkayAtLXByb2dyZXNzIGV2ZW50cyAtLXJlcXVpcmUtYXBwcm92YWwgbmV2ZXIgZGVwbG95ICR7dGhpcy5zdGFja1ByZWZpeH0tZmVhdHVyZWAsXG4gICAgfSk7XG4gICAgdGhpcy5wcm9qZWN0LmFkZFRhc2soJ2RpZmY6ZmVhdHVyZScsIHtcbiAgICAgIGV4ZWM6IGBjZGsgZGlmZiAke3RoaXMuc3RhY2tQcmVmaXh9LWZlYXR1cmVgLFxuICAgIH0pO1xuICAgIHRoaXMucHJvamVjdC5hZGRUYXNrKCdkZXN0cm95OmZlYXR1cmUnLCB7XG4gICAgICBleGVjOiBgY2RrIGRlc3Ryb3kgJHt0aGlzLnN0YWNrUHJlZml4fS1mZWF0dXJlYCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBzZXRzIHVwIHRhc2tzIGZvciB0aGUgZ2VuZXJhbCBwaXBlbGluZSBzdGFnZXMgKGRldiwgcHJvZCksIGluY2x1ZGluZyBkZXBsb3ltZW50IGFuZCBjb21wYXJpbmcgY2hhbmdlcyAoZGlmZikuXG4gICAqIEBwYXJhbSB7RGVwbG95U3RhZ2VPcHRpb25zfSBzdGFnZSAtIFRoZSBzdGFnZSB0byBjcmVhdGVcbiAgICovXG4gIHByaXZhdGUgY3JlYXRlUGlwZWxpbmVTdGFnZShzdGFnZTogRGVwbG95bWVudFN0YWdlKSB7XG4gICAgdGhpcy5wcm9qZWN0LmFkZFRhc2soYGRlcGxveToke3N0YWdlLm5hbWV9YCwge1xuICAgICAgZXhlYzogYGNkayAtLWFwcCAke3RoaXMuYXBwLmNka0NvbmZpZy5jZGtvdXR9IC0tcHJvZ3Jlc3MgZXZlbnRzIC0tcmVxdWlyZS1hcHByb3ZhbCBuZXZlciBkZXBsb3kgJHt0aGlzLnN0YWNrUHJlZml4fS0ke3N0YWdlLm5hbWV9YCxcbiAgICB9KTtcbiAgICB0aGlzLnByb2plY3QuYWRkVGFzayhgZGlmZjoke3N0YWdlLm5hbWV9YCwge1xuICAgICAgZXhlYzogYGNkayAtLWFwcCAke3RoaXMuYXBwLmNka0NvbmZpZy5jZGtvdXR9IGRpZmYgJHt0aGlzLnN0YWNrUHJlZml4fS0ke3N0YWdlLm5hbWV9YCxcbiAgICB9KTtcblxuICAgIHRoaXMuZW5naW5lLmNyZWF0ZURlcGxveW1lbnQoe1xuICAgICAgY29uZmlnOiBzdGFnZSxcbiAgICAgIGluc3RhbGxDb21tYW5kczogW1xuICAgICAgICAuLi4odGhpcy5wcm9wcy5wcmVJbnN0YWxsQ29tbWFuZHMgPz8gW10pLFxuICAgICAgICBgbnB4IHByb2plbiAke3RoaXMuYXBwLnBhY2thZ2UuaW5zdGFsbENpVGFzay5uYW1lfWAsXG4gICAgICBdLFxuICAgICAgZGVwbG95Q29tbWFuZHM6IFtcbiAgICAgICAgLy8gVE9ETyBwcmUgZGVwbG95IHN0ZXBzXG4gICAgICAgIGBucHggcHJvamVuIGRlcGxveToke3N0YWdlLm5hbWV9YCxcbiAgICAgICAgLy8gVE9ETyBwb3N0IGRlcGxveSBzdGVwc1xuICAgICAgXSxcbiAgICB9KTtcbiAgfVxufSJdfQ==
File without changes