@optimizely/ocp-cli 1.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +18 -0
- package/bin/opti.js +3 -0
- package/dist/commands/accounts/Whoami.d.ts +3 -0
- package/dist/commands/accounts/Whoami.js +34 -0
- package/dist/commands/accounts/Whoami.js.map +1 -0
- package/dist/commands/accounts/Whois.d.ts +6 -0
- package/dist/commands/accounts/Whois.js +65 -0
- package/dist/commands/accounts/Whois.js.map +1 -0
- package/dist/commands/app/BaseBuildCommand.d.ts +23 -0
- package/dist/commands/app/BaseBuildCommand.js +227 -0
- package/dist/commands/app/BaseBuildCommand.js.map +1 -0
- package/dist/commands/app/Init.d.ts +20 -0
- package/dist/commands/app/Init.js +285 -0
- package/dist/commands/app/Init.js.map +1 -0
- package/dist/commands/app/Logs.d.ts +19 -0
- package/dist/commands/app/Logs.js +230 -0
- package/dist/commands/app/Logs.js.map +1 -0
- package/dist/commands/app/Package.d.ts +4 -0
- package/dist/commands/app/Package.js +51 -0
- package/dist/commands/app/Package.js.map +1 -0
- package/dist/commands/app/Prepare.d.ts +8 -0
- package/dist/commands/app/Prepare.js +112 -0
- package/dist/commands/app/Prepare.js.map +1 -0
- package/dist/commands/app/Register.d.ts +7 -0
- package/dist/commands/app/Register.js +58 -0
- package/dist/commands/app/Register.js.map +1 -0
- package/dist/commands/app/Validate.d.ts +4 -0
- package/dist/commands/app/Validate.js +27 -0
- package/dist/commands/app/Validate.js.map +1 -0
- package/dist/commands/availability/List.d.ts +4 -0
- package/dist/commands/availability/List.js +47 -0
- package/dist/commands/availability/List.js.map +1 -0
- package/dist/commands/directory/Info.d.ts +7 -0
- package/dist/commands/directory/Info.js +92 -0
- package/dist/commands/directory/Info.js.map +1 -0
- package/dist/commands/directory/Install.d.ts +6 -0
- package/dist/commands/directory/Install.js +54 -0
- package/dist/commands/directory/Install.js.map +1 -0
- package/dist/commands/directory/List.d.ts +8 -0
- package/dist/commands/directory/List.js +102 -0
- package/dist/commands/directory/List.js.map +1 -0
- package/dist/commands/directory/ListFunctions.d.ts +7 -0
- package/dist/commands/directory/ListFunctions.js +77 -0
- package/dist/commands/directory/ListFunctions.js.map +1 -0
- package/dist/commands/directory/ListGlobalFunctions.d.ts +6 -0
- package/dist/commands/directory/ListGlobalFunctions.js +72 -0
- package/dist/commands/directory/ListGlobalFunctions.js.map +1 -0
- package/dist/commands/directory/ListInstalls.d.ts +8 -0
- package/dist/commands/directory/ListInstalls.js +81 -0
- package/dist/commands/directory/ListInstalls.js.map +1 -0
- package/dist/commands/directory/Publish.d.ts +8 -0
- package/dist/commands/directory/Publish.js +180 -0
- package/dist/commands/directory/Publish.js.map +1 -0
- package/dist/commands/directory/Status.d.ts +5 -0
- package/dist/commands/directory/Status.js +60 -0
- package/dist/commands/directory/Status.js.map +1 -0
- package/dist/commands/directory/Uninstall.d.ts +6 -0
- package/dist/commands/directory/Uninstall.js +50 -0
- package/dist/commands/directory/Uninstall.js.map +1 -0
- package/dist/commands/directory/Unpublish.d.ts +10 -0
- package/dist/commands/directory/Unpublish.js +181 -0
- package/dist/commands/directory/Unpublish.js.map +1 -0
- package/dist/commands/directory/Uprade.d.ts +8 -0
- package/dist/commands/directory/Uprade.js +100 -0
- package/dist/commands/directory/Uprade.js.map +1 -0
- package/dist/commands/env/GetEnvironment.d.ts +3 -0
- package/dist/commands/env/GetEnvironment.js +28 -0
- package/dist/commands/env/GetEnvironment.js.map +1 -0
- package/dist/commands/env/SetEnvironment.d.ts +4 -0
- package/dist/commands/env/SetEnvironment.js +63 -0
- package/dist/commands/env/SetEnvironment.js.map +1 -0
- package/dist/commands/jobs/List.d.ts +21 -0
- package/dist/commands/jobs/List.js +268 -0
- package/dist/commands/jobs/List.js.map +1 -0
- package/dist/commands/jobs/RuntimeStatus.d.ts +5 -0
- package/dist/commands/jobs/RuntimeStatus.js +65 -0
- package/dist/commands/jobs/RuntimeStatus.js.map +1 -0
- package/dist/commands/jobs/Terminate.d.ts +5 -0
- package/dist/commands/jobs/Terminate.js +45 -0
- package/dist/commands/jobs/Terminate.js.map +1 -0
- package/dist/commands/jobs/Trigger.d.ts +8 -0
- package/dist/commands/jobs/Trigger.js +58 -0
- package/dist/commands/jobs/Trigger.js.map +1 -0
- package/dist/commands/review/List.d.ts +5 -0
- package/dist/commands/review/List.js +81 -0
- package/dist/commands/review/List.js.map +1 -0
- package/dist/commands/review/Open.d.ts +4 -0
- package/dist/commands/review/Open.js +42 -0
- package/dist/commands/review/Open.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/AppContext.d.ts +9 -0
- package/dist/lib/AppContext.js +43 -0
- package/dist/lib/AppContext.js.map +1 -0
- package/dist/lib/AppPackager.d.ts +8 -0
- package/dist/lib/AppPackager.js +40 -0
- package/dist/lib/AppPackager.js.map +1 -0
- package/dist/lib/AppUpdater.d.ts +9 -0
- package/dist/lib/AppUpdater.js +155 -0
- package/dist/lib/AppUpdater.js.map +1 -0
- package/dist/lib/AppUploader.d.ts +8 -0
- package/dist/lib/AppUploader.js +36 -0
- package/dist/lib/AppUploader.js.map +1 -0
- package/dist/lib/Config.d.ts +15 -0
- package/dist/lib/Config.js +47 -0
- package/dist/lib/Config.js.map +1 -0
- package/dist/lib/EnvironmentalOutput.d.ts +1 -0
- package/dist/lib/EnvironmentalOutput.js +21 -0
- package/dist/lib/EnvironmentalOutput.js.map +1 -0
- package/dist/lib/Moria.d.ts +51 -0
- package/dist/lib/Moria.js +30 -0
- package/dist/lib/Moria.js.map +1 -0
- package/dist/lib/MoriaApi.d.ts +22 -0
- package/dist/lib/MoriaApi.js +75 -0
- package/dist/lib/MoriaApi.js.map +1 -0
- package/dist/lib/Rivendell.d.ts +351 -0
- package/dist/lib/Rivendell.js +328 -0
- package/dist/lib/Rivendell.js.map +1 -0
- package/dist/lib/RivendellApi.d.ts +22 -0
- package/dist/lib/RivendellApi.js +90 -0
- package/dist/lib/RivendellApi.js.map +1 -0
- package/dist/lib/Shards.d.ts +3 -0
- package/dist/lib/Shards.js +34 -0
- package/dist/lib/Shards.js.map +1 -0
- package/dist/lib/StringUtils.d.ts +1 -0
- package/dist/lib/StringUtils.js +9 -0
- package/dist/lib/StringUtils.js.map +1 -0
- package/dist/lib/TeminalPassthru.d.ts +5 -0
- package/dist/lib/TeminalPassthru.js +12 -0
- package/dist/lib/TeminalPassthru.js.map +1 -0
- package/dist/lib/TerminalConfirm.d.ts +3 -0
- package/dist/lib/TerminalConfirm.js +26 -0
- package/dist/lib/TerminalConfirm.js.map +1 -0
- package/dist/lib/TerminalInput.d.ts +32 -0
- package/dist/lib/TerminalInput.js +207 -0
- package/dist/lib/TerminalInput.js.map +1 -0
- package/dist/lib/TerminalMenu.d.ts +34 -0
- package/dist/lib/TerminalMenu.js +186 -0
- package/dist/lib/TerminalMenu.js.map +1 -0
- package/dist/lib/TerminalOutput.d.ts +5 -0
- package/dist/lib/TerminalOutput.js +12 -0
- package/dist/lib/TerminalOutput.js.map +1 -0
- package/dist/lib/TerminalSpinner.d.ts +15 -0
- package/dist/lib/TerminalSpinner.js +71 -0
- package/dist/lib/TerminalSpinner.js.map +1 -0
- package/dist/lib/build.d.ts +5 -0
- package/dist/lib/build.js +35 -0
- package/dist/lib/build.js.map +1 -0
- package/dist/lib/checkForUpdate.d.ts +2 -0
- package/dist/lib/checkForUpdate.js +58 -0
- package/dist/lib/checkForUpdate.js.map +1 -0
- package/dist/lib/dev/app.d.ts +8 -0
- package/dist/lib/dev/app.js +53 -0
- package/dist/lib/dev/app.js.map +1 -0
- package/dist/lib/dev/index.d.ts +1 -0
- package/dist/lib/dev/index.js +14 -0
- package/dist/lib/dev/index.js.map +1 -0
- package/dist/lib/dev/logger.d.ts +15 -0
- package/dist/lib/dev/logger.js +58 -0
- package/dist/lib/dev/logger.js.map +1 -0
- package/dist/lib/die.d.ts +5 -0
- package/dist/lib/die.js +14 -0
- package/dist/lib/die.js.map +1 -0
- package/dist/lib/directoryExists.d.ts +1 -0
- package/dist/lib/directoryExists.js +9 -0
- package/dist/lib/directoryExists.js.map +1 -0
- package/dist/lib/formatBuildState.d.ts +2 -0
- package/dist/lib/formatBuildState.js +23 -0
- package/dist/lib/formatBuildState.js.map +1 -0
- package/dist/lib/formatError.d.ts +1 -0
- package/dist/lib/formatError.js +45 -0
- package/dist/lib/formatError.js.map +1 -0
- package/dist/lib/formatJobStatus.d.ts +3 -0
- package/dist/lib/formatJobStatus.js +28 -0
- package/dist/lib/formatJobStatus.js.map +1 -0
- package/dist/lib/formatReviewStatus.d.ts +4 -0
- package/dist/lib/formatReviewStatus.js +28 -0
- package/dist/lib/formatReviewStatus.js.map +1 -0
- package/dist/lib/formatTimstamp.d.ts +1 -0
- package/dist/lib/formatTimstamp.js +25 -0
- package/dist/lib/formatTimstamp.js.map +1 -0
- package/dist/lib/formatVersionState.d.ts +2 -0
- package/dist/lib/formatVersionState.js +35 -0
- package/dist/lib/formatVersionState.js.map +1 -0
- package/dist/lib/gatherAppEnv.d.ts +3 -0
- package/dist/lib/gatherAppEnv.js +71 -0
- package/dist/lib/gatherAppEnv.js.map +1 -0
- package/dist/lib/handleInterrupt.d.ts +1 -0
- package/dist/lib/handleInterrupt.js +17 -0
- package/dist/lib/handleInterrupt.js.map +1 -0
- package/dist/lib/jobRuntime.d.ts +3 -0
- package/dist/lib/jobRuntime.js +16 -0
- package/dist/lib/jobRuntime.js.map +1 -0
- package/dist/lib/parseDate.d.ts +2 -0
- package/dist/lib/parseDate.js +26 -0
- package/dist/lib/parseDate.js.map +1 -0
- package/dist/lib/templating/TemplateRenderer.d.ts +13 -0
- package/dist/lib/templating/TemplateRenderer.js +62 -0
- package/dist/lib/templating/TemplateRenderer.js.map +1 -0
- package/dist/lib/templating/fetchTemplatesManifest.d.ts +1 -0
- package/dist/lib/templating/fetchTemplatesManifest.js +10 -0
- package/dist/lib/templating/fetchTemplatesManifest.js.map +1 -0
- package/dist/lib/templating/types.d.ts +27 -0
- package/dist/lib/templating/types.js +3 -0
- package/dist/lib/templating/types.js.map +1 -0
- package/dist/oo-cli.manifest.json +1142 -0
- package/dist/test/setup.d.ts +0 -0
- package/dist/test/setup.js +4 -0
- package/dist/test/setup.js.map +1 -0
- package/package.json +94 -0
- package/src/commands/accounts/Whoami.ts +19 -0
- package/src/commands/accounts/Whois.ts +51 -0
- package/src/commands/app/BaseBuildCommand.ts +266 -0
- package/src/commands/app/Init.ts +303 -0
- package/src/commands/app/Logs.ts +241 -0
- package/src/commands/app/Package.ts +39 -0
- package/src/commands/app/Prepare.ts +108 -0
- package/src/commands/app/Register.ts +41 -0
- package/src/commands/app/Validate.ts +13 -0
- package/src/commands/availability/List.ts +37 -0
- package/src/commands/directory/Info.ts +83 -0
- package/src/commands/directory/Install.ts +37 -0
- package/src/commands/directory/List.ts +96 -0
- package/src/commands/directory/ListFunctions.ts +60 -0
- package/src/commands/directory/ListGlobalFunctions.ts +54 -0
- package/src/commands/directory/ListInstalls.ts +73 -0
- package/src/commands/directory/Publish.ts +179 -0
- package/src/commands/directory/Status.ts +45 -0
- package/src/commands/directory/Uninstall.ts +32 -0
- package/src/commands/directory/Unpublish.ts +173 -0
- package/src/commands/directory/Uprade.ts +85 -0
- package/src/commands/env/GetEnvironment.ts +14 -0
- package/src/commands/env/SetEnvironment.ts +52 -0
- package/src/commands/jobs/List.ts +278 -0
- package/src/commands/jobs/RuntimeStatus.ts +49 -0
- package/src/commands/jobs/Terminate.ts +29 -0
- package/src/commands/jobs/Trigger.ts +41 -0
- package/src/commands/review/List.ts +76 -0
- package/src/commands/review/Open.ts +28 -0
- package/src/index.ts +15 -0
- package/src/lib/AppContext.ts +47 -0
- package/src/lib/AppPackager.ts +47 -0
- package/src/lib/AppUpdater.ts +177 -0
- package/src/lib/AppUploader.ts +39 -0
- package/src/lib/Config.ts +60 -0
- package/src/lib/EnvironmentalOutput.ts +18 -0
- package/src/lib/Moria.ts +66 -0
- package/src/lib/MoriaApi.ts +86 -0
- package/src/lib/Rivendell.ts +572 -0
- package/src/lib/RivendellApi.ts +99 -0
- package/src/lib/Shards.ts +37 -0
- package/src/lib/StringUtils.ts +4 -0
- package/src/lib/TeminalPassthru.ts +7 -0
- package/src/lib/TerminalConfirm.ts +27 -0
- package/src/lib/TerminalInput.ts +236 -0
- package/src/lib/TerminalMenu.ts +221 -0
- package/src/lib/TerminalOutput.ts +7 -0
- package/src/lib/TerminalSpinner.ts +76 -0
- package/src/lib/build.ts +36 -0
- package/src/lib/checkForUpdate.ts +63 -0
- package/src/lib/dev/app.ts +58 -0
- package/src/lib/dev/index.ts +1 -0
- package/src/lib/dev/logger.ts +77 -0
- package/src/lib/die.ts +10 -0
- package/src/lib/directoryExists.ts +5 -0
- package/src/lib/formatBuildState.ts +20 -0
- package/src/lib/formatError.ts +39 -0
- package/src/lib/formatJobStatus.ts +24 -0
- package/src/lib/formatReviewStatus.ts +27 -0
- package/src/lib/formatTimstamp.ts +21 -0
- package/src/lib/formatVersionState.ts +31 -0
- package/src/lib/gatherAppEnv.ts +75 -0
- package/src/lib/handleInterrupt.ts +13 -0
- package/src/lib/jobRuntime.ts +12 -0
- package/src/lib/parseDate.ts +21 -0
- package/src/lib/templating/TemplateRenderer.ts +65 -0
- package/src/lib/templating/fetchTemplatesManifest.ts +6 -0
- package/src/lib/templating/types.ts +30 -0
- package/src/test/setup.ts +2 -0
- package/src/types/columnify.d.ts +27 -0
- package/src/types/gitignore-parser.d.ts +11 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {command, flag, help, namespace, option, param} from 'oo-cli';
|
|
2
|
+
import {die} from '../../lib/die';
|
|
3
|
+
import {formatError} from '../../lib/formatError';
|
|
4
|
+
import {Rivendell} from '../../lib/Rivendell';
|
|
5
|
+
import {applicableShards} from '../../lib/Shards';
|
|
6
|
+
|
|
7
|
+
@namespace('app')
|
|
8
|
+
export class RegisterCommand {
|
|
9
|
+
@param
|
|
10
|
+
@help('The app id to reserve')
|
|
11
|
+
public id!: string;
|
|
12
|
+
|
|
13
|
+
@param
|
|
14
|
+
@help('The display name of the app')
|
|
15
|
+
public name!: string;
|
|
16
|
+
|
|
17
|
+
@flag
|
|
18
|
+
@help(
|
|
19
|
+
'Do not share this app with other developers in your organization. ' +
|
|
20
|
+
'If not set, the app will be shared with all developers in your organization'
|
|
21
|
+
)
|
|
22
|
+
public personal: boolean = false;
|
|
23
|
+
|
|
24
|
+
@option('a')
|
|
25
|
+
@help('The availability zone that will be targeted (default: us)')
|
|
26
|
+
private availability: string = '';
|
|
27
|
+
|
|
28
|
+
@command
|
|
29
|
+
@help('Register an app version')
|
|
30
|
+
public async register() {
|
|
31
|
+
try {
|
|
32
|
+
const shards = await applicableShards(this.availability);
|
|
33
|
+
for (const shard of shards) {
|
|
34
|
+
const app = await Rivendell.registerApp(this.id, this.name, this.personal, shard);
|
|
35
|
+
console.log(`Registered app ${app.id} with name "${app.name} in ${shard}`);
|
|
36
|
+
}
|
|
37
|
+
} catch (e) {
|
|
38
|
+
die(formatError(e));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import {command, help, namespace} from 'oo-cli';
|
|
3
|
+
import {BaseBuildCommand} from './BaseBuildCommand';
|
|
4
|
+
|
|
5
|
+
@namespace('app')
|
|
6
|
+
export class ValidateCommand extends BaseBuildCommand {
|
|
7
|
+
@command
|
|
8
|
+
@help('Validate an app locally')
|
|
9
|
+
public async validate() {
|
|
10
|
+
await this.run(false, false, false);
|
|
11
|
+
console.log(chalk.gray(`\nUse ${chalk.white('ocp app prepare')} to upload and build your app\n`));
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {command, help, namespace} from 'oo-cli';
|
|
2
|
+
import {die} from '../../lib/die';
|
|
3
|
+
import {formatError} from '../../lib/formatError';
|
|
4
|
+
import {Rivendell} from '../../lib/Rivendell';
|
|
5
|
+
import Shard = Rivendell.Shard;
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import * as table from 'text-table';
|
|
8
|
+
import {styledStringLength} from '../../lib/StringUtils';
|
|
9
|
+
|
|
10
|
+
@namespace('availability')
|
|
11
|
+
export class ListCommand {
|
|
12
|
+
@command
|
|
13
|
+
@help('List all availability zones')
|
|
14
|
+
public async list() {
|
|
15
|
+
try {
|
|
16
|
+
this.render(await Rivendell.shards());
|
|
17
|
+
} catch (e) {
|
|
18
|
+
die(formatError(e));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
private render(accounts: Shard[]) {
|
|
23
|
+
const header = ['Name', 'Description'].map((item) => chalk.grey(item));
|
|
24
|
+
const rows = accounts.map((shard) => [shard.id, shard.description]);
|
|
25
|
+
const t = table(
|
|
26
|
+
[
|
|
27
|
+
header,
|
|
28
|
+
...rows
|
|
29
|
+
],
|
|
30
|
+
{
|
|
31
|
+
hsep: ' '.repeat(8),
|
|
32
|
+
stringLength: styledStringLength
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
console.log(`\n${t}\n`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import {command, help, namespace, option, param} from 'oo-cli';
|
|
3
|
+
import {die} from '../../lib/die';
|
|
4
|
+
import {formatVersionState} from '../../lib/formatVersionState';
|
|
5
|
+
import {formatReviewStatus} from '../../lib/formatReviewStatus';
|
|
6
|
+
import {formatError} from '../../lib/formatError';
|
|
7
|
+
import {Rivendell} from '../../lib/Rivendell';
|
|
8
|
+
import * as table from 'text-table';
|
|
9
|
+
import {styledStringLength} from '../../lib/StringUtils';
|
|
10
|
+
import SortDirection = Rivendell.SortDirection;
|
|
11
|
+
import AppVersion = Rivendell.AppVersion;
|
|
12
|
+
import AppVersionState = Rivendell.AppVersionState;
|
|
13
|
+
import App = Rivendell.App;
|
|
14
|
+
import ReviewStatus = Rivendell.ReviewStatus;
|
|
15
|
+
|
|
16
|
+
@namespace('directory')
|
|
17
|
+
export class InfoCommand {
|
|
18
|
+
@param
|
|
19
|
+
@help('The App ID to look up')
|
|
20
|
+
public appId!: string;
|
|
21
|
+
|
|
22
|
+
@option('a')
|
|
23
|
+
@help('The availability zone that will be targeted (default: us)')
|
|
24
|
+
private availability: string = '';
|
|
25
|
+
|
|
26
|
+
@command
|
|
27
|
+
@help('Get information about an app')
|
|
28
|
+
public async info() {
|
|
29
|
+
try {
|
|
30
|
+
await this.render(await Rivendell.fetchApp(this.appId, this.availability));
|
|
31
|
+
} catch (e) {
|
|
32
|
+
die(formatError(e));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private async render(app: App): Promise<void> {
|
|
37
|
+
console.log('');
|
|
38
|
+
console.log(` ${chalk.bold.underline('General')}\n`);
|
|
39
|
+
console.log(` ${chalk.cyanBright('id')}\t\t${app.id}`);
|
|
40
|
+
console.log(` ${chalk.cyanBright('name')}\t${app.name}`);
|
|
41
|
+
console.log(` ${chalk.cyanBright('created')}\t${app.createdAt}`);
|
|
42
|
+
console.log('');
|
|
43
|
+
|
|
44
|
+
// Versions
|
|
45
|
+
console.log(` ${chalk.bold.underline('Versions')}\n`);
|
|
46
|
+
const versions = await this.fetchAppVersions();
|
|
47
|
+
if (!versions) {
|
|
48
|
+
console.log(` ${chalk.italic('None')}`);
|
|
49
|
+
} else {
|
|
50
|
+
const rows = versions.map((appVersion) => {
|
|
51
|
+
const r = [
|
|
52
|
+
'',
|
|
53
|
+
appVersion.id.version,
|
|
54
|
+
formatVersionState(appVersion.state as AppVersionState)
|
|
55
|
+
];
|
|
56
|
+
if (appVersion.reviewStatus) {
|
|
57
|
+
r.push(formatReviewStatus(appVersion.reviewStatus as ReviewStatus, appVersion.state as AppVersionState));
|
|
58
|
+
}
|
|
59
|
+
return r;
|
|
60
|
+
});
|
|
61
|
+
const t = table(rows, {
|
|
62
|
+
hsep: ' '.repeat(4),
|
|
63
|
+
stringLength: styledStringLength
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
console.log(`\n${t}\n`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private async fetchAppVersions(): Promise<AppVersion[]> {
|
|
71
|
+
return await Rivendell.searchAppVersions(
|
|
72
|
+
{
|
|
73
|
+
appId: this.appId,
|
|
74
|
+
sorts: [
|
|
75
|
+
{
|
|
76
|
+
field: 'createdAt',
|
|
77
|
+
direction: SortDirection.DESC
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
}, this.availability
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import {command, help, namespace, option, param} from 'oo-cli';
|
|
3
|
+
import {die} from '../../lib/die';
|
|
4
|
+
import {Rivendell} from '../../lib/Rivendell';
|
|
5
|
+
import {formatError} from '../../lib/formatError';
|
|
6
|
+
|
|
7
|
+
@namespace('directory')
|
|
8
|
+
export class InstallCommand {
|
|
9
|
+
@param
|
|
10
|
+
@help('The App ID and version (e.g. my_app@1.0.0)')
|
|
11
|
+
public appVersion!: string;
|
|
12
|
+
|
|
13
|
+
@param
|
|
14
|
+
@help('The Tracker ID of the account to install into')
|
|
15
|
+
public trackerId!: string;
|
|
16
|
+
|
|
17
|
+
@option('a')
|
|
18
|
+
@help('The availability zone that will be targeted (default: us)')
|
|
19
|
+
private availability: string = '';
|
|
20
|
+
|
|
21
|
+
@command
|
|
22
|
+
@help('Install a specific app version into an account')
|
|
23
|
+
public async install() {
|
|
24
|
+
if (!/[\w-]+@\d+\.\d+\.\d+(?:-\w+\.\d+)?/.test(this.appVersion)) {
|
|
25
|
+
return die('appVersion is required in the format of app@1.0.0');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const [appId, version] = this.appVersion.split('@');
|
|
29
|
+
try {
|
|
30
|
+
const install = await Rivendell.install(appId, version, this.trackerId, this.availability);
|
|
31
|
+
console.log(chalk.green(`Installed ${appId}@${version} for ${this.trackerId} ` +
|
|
32
|
+
`with install id ${install.id} in ${this.availability || 'us'}`));
|
|
33
|
+
} catch (e) {
|
|
34
|
+
die(formatError(e));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import {command, flag, help, namespace, option, optional, param} from 'oo-cli';
|
|
3
|
+
import * as semver from 'semver';
|
|
4
|
+
import * as table from 'text-table';
|
|
5
|
+
import {die} from '../../lib/die';
|
|
6
|
+
import {formatVersionState} from '../../lib/formatVersionState';
|
|
7
|
+
import {styledStringLength} from '../../lib/StringUtils';
|
|
8
|
+
import {Rivendell} from '../../lib/Rivendell';
|
|
9
|
+
import {formatError} from '../../lib/formatError';
|
|
10
|
+
import AppVersion = Rivendell.AppVersion;
|
|
11
|
+
import AppVersionState = Rivendell.AppVersionState;
|
|
12
|
+
import DeploymentStage = Rivendell.DeploymentStage;
|
|
13
|
+
import AppVersionSearchCriteria = Rivendell.AppVersionSearchCriteria;
|
|
14
|
+
import ReviewStatus = Rivendell.ReviewStatus;
|
|
15
|
+
|
|
16
|
+
@namespace('directory')
|
|
17
|
+
export class ListCommand {
|
|
18
|
+
@param
|
|
19
|
+
@optional
|
|
20
|
+
@help('A specific App ID to filter down to (lists all apps by default)')
|
|
21
|
+
private appId!: string;
|
|
22
|
+
|
|
23
|
+
@flag
|
|
24
|
+
@help('Include all statuses. STOPPED is filtered by default')
|
|
25
|
+
private allStatuses: boolean = false;
|
|
26
|
+
|
|
27
|
+
@option('a')
|
|
28
|
+
@help('The availability zone that will be targeted (default: us)')
|
|
29
|
+
private availability: string = '';
|
|
30
|
+
|
|
31
|
+
@command
|
|
32
|
+
@help('List registered app versions')
|
|
33
|
+
public async list(): Promise<void> {
|
|
34
|
+
try {
|
|
35
|
+
const criteria: AppVersionSearchCriteria = {
|
|
36
|
+
stages: [DeploymentStage.TEST, DeploymentStage.PRODUCTION]
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
if (this.appId) {
|
|
40
|
+
criteria.appId = this.appId;
|
|
41
|
+
}
|
|
42
|
+
this.render(await Rivendell.searchAppVersions(criteria, this.availability));
|
|
43
|
+
} catch (e) {
|
|
44
|
+
die(formatError(e));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private render(appVersions: AppVersion[]) {
|
|
49
|
+
const header = ['App ID', 'Version', 'State', 'Created At', 'Updated At'].map(
|
|
50
|
+
(item) => chalk.grey(item)
|
|
51
|
+
);
|
|
52
|
+
const rows = appVersions
|
|
53
|
+
.filter((appVersion) =>
|
|
54
|
+
this.allStatuses || appVersion.state as AppVersionState !== AppVersionState.STOPPED
|
|
55
|
+
)
|
|
56
|
+
.sort((lhs, rhs) => {
|
|
57
|
+
let result = lhs.id.appId.localeCompare(rhs.id.appId);
|
|
58
|
+
if (result === 0) {
|
|
59
|
+
const lhsVersion = lhs.id.version;
|
|
60
|
+
const rhsVersion = rhs.id.version;
|
|
61
|
+
if (lhsVersion !== rhsVersion) {
|
|
62
|
+
result = semver.gt(lhsVersion, rhsVersion) ? -1 : 1;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return result;
|
|
66
|
+
})
|
|
67
|
+
.map((appVersion) => [
|
|
68
|
+
appVersion.id.appId,
|
|
69
|
+
appVersion.id.version,
|
|
70
|
+
this.renderState(appVersion),
|
|
71
|
+
appVersion.createdAt,
|
|
72
|
+
appVersion.updatedAt
|
|
73
|
+
]);
|
|
74
|
+
|
|
75
|
+
const t = table(
|
|
76
|
+
[
|
|
77
|
+
header,
|
|
78
|
+
...rows
|
|
79
|
+
],
|
|
80
|
+
{
|
|
81
|
+
hsep: ' '.repeat(8),
|
|
82
|
+
stringLength: styledStringLength
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
console.log(`\n${t}\n`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private renderState(appVersion: AppVersion): string {
|
|
89
|
+
const state = appVersion.state as AppVersionState;
|
|
90
|
+
const reviewStatus = appVersion.reviewStatus as Rivendell.ReviewStatus;
|
|
91
|
+
const includeReviewStatus = reviewStatus === ReviewStatus.APPROVED || reviewStatus === ReviewStatus.IN_REVIEW;
|
|
92
|
+
return state === AppVersionState.PUBLISHED && includeReviewStatus
|
|
93
|
+
? `${formatVersionState(state)} (${chalk.yellow(reviewStatus)})`
|
|
94
|
+
: formatVersionState(state);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import {command, help, namespace, option, param} from 'oo-cli';
|
|
3
|
+
import {die} from '../../lib/die';
|
|
4
|
+
import {formatError} from '../../lib/formatError';
|
|
5
|
+
import {Rivendell} from '../../lib/Rivendell';
|
|
6
|
+
import Webhook = Rivendell.Webhook;
|
|
7
|
+
|
|
8
|
+
@namespace('directory')
|
|
9
|
+
export class ListFunctionsCommand {
|
|
10
|
+
@param
|
|
11
|
+
@help('The App ID (e.g. my_app)')
|
|
12
|
+
public appId!: string;
|
|
13
|
+
|
|
14
|
+
@param
|
|
15
|
+
@help('The Tracker ID of the installed account')
|
|
16
|
+
public trackerId!: string;
|
|
17
|
+
|
|
18
|
+
@option('a')
|
|
19
|
+
@help('The availability zone that will be targeted (default: us)')
|
|
20
|
+
private availability: string = '';
|
|
21
|
+
|
|
22
|
+
@command('list-functions')
|
|
23
|
+
@help('List the functions exposed by an app installation')
|
|
24
|
+
public async listFunctions() {
|
|
25
|
+
try {
|
|
26
|
+
const appInstallation = await Rivendell.fetchAppInstallation(this.appId, this.trackerId, this.availability);
|
|
27
|
+
const webhooks = await Rivendell.searchWebhooks({
|
|
28
|
+
appInstallId: appInstallation.id,
|
|
29
|
+
includeInternal: true,
|
|
30
|
+
includeDisabled: true
|
|
31
|
+
}, this.availability);
|
|
32
|
+
|
|
33
|
+
this.render(webhooks);
|
|
34
|
+
} catch (e) {
|
|
35
|
+
die(formatError(e));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private render(webhooks: Webhook[]) {
|
|
40
|
+
if (webhooks.length === 0) {
|
|
41
|
+
console.log(chalk.yellow(`${this.appId} install for ${this.trackerId} does not have functions.`));
|
|
42
|
+
} else {
|
|
43
|
+
webhooks.forEach((webhook) => {
|
|
44
|
+
const attrs = webhook.attributes!;
|
|
45
|
+
const caveats = [];
|
|
46
|
+
if (attrs.internal) {
|
|
47
|
+
caveats.push('internal');
|
|
48
|
+
}
|
|
49
|
+
if (!attrs.enabled) {
|
|
50
|
+
caveats.push('disabled');
|
|
51
|
+
}
|
|
52
|
+
if (caveats.length === 0) {
|
|
53
|
+
console.log(webhook.url);
|
|
54
|
+
} else {
|
|
55
|
+
console.log(chalk.yellow(`${webhook.url} (${caveats.join(', ')})`));
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import {command, help, namespace, option, param} from 'oo-cli';
|
|
3
|
+
import {die} from '../../lib/die';
|
|
4
|
+
import {Rivendell} from '../../lib/Rivendell';
|
|
5
|
+
import {formatError} from '../../lib/formatError';
|
|
6
|
+
import Webhook = Rivendell.Webhook;
|
|
7
|
+
|
|
8
|
+
@namespace('directory')
|
|
9
|
+
export class ListGlobalFunctionsCommand {
|
|
10
|
+
@param
|
|
11
|
+
@help('The App ID (e.g. my_app)')
|
|
12
|
+
public appId!: string;
|
|
13
|
+
|
|
14
|
+
@option('a')
|
|
15
|
+
@help('The availability zone that will be targeted (default: us)')
|
|
16
|
+
private availability: string = '';
|
|
17
|
+
|
|
18
|
+
@command('list-global-functions')
|
|
19
|
+
@help('List the global functions exposed by an app')
|
|
20
|
+
public async listGlobalFunctions() {
|
|
21
|
+
try {
|
|
22
|
+
this.render(await Rivendell.searchWebhooks({
|
|
23
|
+
appId: this.appId,
|
|
24
|
+
appInstallId: 0,
|
|
25
|
+
includeInternal: true,
|
|
26
|
+
includeDisabled: true
|
|
27
|
+
}, this.availability));
|
|
28
|
+
} catch (e) {
|
|
29
|
+
die(formatError(e));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private render(webhooks: Webhook[]) {
|
|
34
|
+
if (webhooks.length === 0) {
|
|
35
|
+
console.log(chalk.yellow(`${this.appId} does not contain global functions.`));
|
|
36
|
+
} else {
|
|
37
|
+
webhooks.forEach((webhook) => {
|
|
38
|
+
const attrs = webhook.attributes;
|
|
39
|
+
const caveats = [];
|
|
40
|
+
if (attrs.internal) {
|
|
41
|
+
caveats.push('internal');
|
|
42
|
+
}
|
|
43
|
+
if (!attrs.enabled) {
|
|
44
|
+
caveats.push('disabled');
|
|
45
|
+
}
|
|
46
|
+
if (caveats.length === 0) {
|
|
47
|
+
console.log(webhook.url);
|
|
48
|
+
} else {
|
|
49
|
+
console.log(chalk.yellow(`${webhook.url} (${caveats.join(', ')})`));
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import {command, help, namespace, option, param} from 'oo-cli';
|
|
3
|
+
import * as table from 'text-table';
|
|
4
|
+
import {die} from '../../lib/die';
|
|
5
|
+
import {styledStringLength} from '../../lib/StringUtils';
|
|
6
|
+
import {Rivendell} from '../../lib/Rivendell';
|
|
7
|
+
import {formatError} from '../../lib/formatError';
|
|
8
|
+
import SortDirection = Rivendell.SortDirection;
|
|
9
|
+
import AppInstallation = Rivendell.AppInstallation;
|
|
10
|
+
|
|
11
|
+
@namespace('directory')
|
|
12
|
+
export class ListInstallsCommand {
|
|
13
|
+
@param
|
|
14
|
+
@help('The App ID and optional version (e.g. my_app or my_app@1.0.0)')
|
|
15
|
+
public appVersion!: string;
|
|
16
|
+
|
|
17
|
+
@option('a')
|
|
18
|
+
@help('The availability zone that will be targeted (default: us)')
|
|
19
|
+
private availability: string = '';
|
|
20
|
+
|
|
21
|
+
@command('list-installs')
|
|
22
|
+
@help('List installations of a specific app version')
|
|
23
|
+
public async listInstalls() {
|
|
24
|
+
const [appId, version] = this.appVersion.split('@');
|
|
25
|
+
try {
|
|
26
|
+
const appInstallations = await Rivendell.searchAppInstallations({
|
|
27
|
+
appId,
|
|
28
|
+
version,
|
|
29
|
+
sorts: [{
|
|
30
|
+
field: 'trackerId', direction: SortDirection.DESC
|
|
31
|
+
}]
|
|
32
|
+
},
|
|
33
|
+
this.availability
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
this.render(version, appInstallations);
|
|
37
|
+
} catch (e) {
|
|
38
|
+
die(formatError(e));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private render(version: string, appInstallations: AppInstallation[]) {
|
|
43
|
+
const header = this.getHeaders(version).map((item) => chalk.grey(item));
|
|
44
|
+
const rows = appInstallations.map((install) => this.getRow(install, version));
|
|
45
|
+
const t = table(
|
|
46
|
+
[
|
|
47
|
+
header,
|
|
48
|
+
...rows
|
|
49
|
+
],
|
|
50
|
+
{
|
|
51
|
+
hsep: ' '.repeat(8),
|
|
52
|
+
stringLength: styledStringLength
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
console.log(`\n${t}\n`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private getHeaders(version: string): string[] {
|
|
59
|
+
const headers = ['Tracker', 'Created At', 'Updated At'];
|
|
60
|
+
if (!version) {
|
|
61
|
+
headers.splice(1, 0, 'Version');
|
|
62
|
+
}
|
|
63
|
+
return headers;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private getRow(install: AppInstallation, version: string): Array<{}> {
|
|
67
|
+
const row = [install.trackerId, install.createdAt, install.updatedAt];
|
|
68
|
+
if (!version) {
|
|
69
|
+
row.splice(1, 0, install.version);
|
|
70
|
+
}
|
|
71
|
+
return row;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import {command, flag, help, namespace, param} from 'oo-cli';
|
|
3
|
+
import {terminal} from 'terminal-kit';
|
|
4
|
+
import {AppContext} from '../../lib/AppContext';
|
|
5
|
+
import {die} from '../../lib/die';
|
|
6
|
+
import {formatVersionState} from '../../lib/formatVersionState';
|
|
7
|
+
import {handleInterrupt} from '../../lib/handleInterrupt';
|
|
8
|
+
import {TerminalSpinner} from '../../lib/TerminalSpinner';
|
|
9
|
+
import {Rivendell} from '../../lib/Rivendell';
|
|
10
|
+
import {formatError} from '../../lib/formatError';
|
|
11
|
+
import AppVersionState = Rivendell.AppVersionState;
|
|
12
|
+
import {applicableShards} from '../../lib/Shards';
|
|
13
|
+
import { AppManifest } from '@zaiusinc/app-sdk';
|
|
14
|
+
import { prerelease, rcompare } from 'semver';
|
|
15
|
+
import { UnpublishCommand } from './Unpublish';
|
|
16
|
+
import { TerminalConfirm } from '../../lib/TerminalConfirm';
|
|
17
|
+
|
|
18
|
+
const STOPPED_STATES = [AppVersionState.START_FAILED, AppVersionState.STOPPED, AppVersionState.STOP_FAILED];
|
|
19
|
+
const UNPUBLISHABLE_STATES = [AppVersionState.RUNNING, AppVersionState.START_FAILED, AppVersionState.STOP_FAILED];
|
|
20
|
+
const PUBLISHABLE_STATES = [
|
|
21
|
+
AppVersionState.NEW,
|
|
22
|
+
AppVersionState.PUBLISHED,
|
|
23
|
+
AppVersionState.START_FAILED,
|
|
24
|
+
AppVersionState.STOPPED
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
@namespace('directory')
|
|
28
|
+
export class PublishCommand {
|
|
29
|
+
@flag('no-progress')
|
|
30
|
+
public noProgress!: boolean;
|
|
31
|
+
|
|
32
|
+
@param
|
|
33
|
+
@help('The App ID and version (e.g. my_app@1.0.0)')
|
|
34
|
+
public appVersion!: string;
|
|
35
|
+
|
|
36
|
+
@command
|
|
37
|
+
@help('Publish (make available) a specific app version that has been reviewed and approved')
|
|
38
|
+
public async publish() {
|
|
39
|
+
handleInterrupt();
|
|
40
|
+
|
|
41
|
+
if (!/[\w-]+@\d+\.\d+\.\d+(?:-\w+\.\d+)?/.test(this.appVersion)) {
|
|
42
|
+
return die('appVersion is required in the format of app@1.0.0');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const [appId, version] = this.appVersion.split('@');
|
|
46
|
+
console.log(chalk.gray(`Publishing ${this.appVersion} to the directory...`));
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
const appVersion = await Rivendell.fetchAppVersion({appId, version}, 'us');
|
|
50
|
+
|
|
51
|
+
if (!PUBLISHABLE_STATES.includes(appVersion.state as AppVersionState)) {
|
|
52
|
+
throw new Error(`AppVersion must be in a publishable state. ` +
|
|
53
|
+
`Currently: ${formatVersionState(appVersion.state as AppVersionState)}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const manifest = JSON.parse(appVersion.manifestJson) as AppManifest;
|
|
57
|
+
const shards = await applicableShards('', manifest);
|
|
58
|
+
const errors: string[] = [];
|
|
59
|
+
|
|
60
|
+
for (const shard of shards) {
|
|
61
|
+
try {
|
|
62
|
+
await Rivendell.publish(appId, version, shard);
|
|
63
|
+
console.log(chalk.green(`Success. ${this.appVersion} is being published to ${shard}.`));
|
|
64
|
+
const context = {appId, version};
|
|
65
|
+
await this.watchForPublishCompletion(context, await this.isStopped(context, shard), shard);
|
|
66
|
+
// since we are handling the interrupt, disable the handler so we can exit
|
|
67
|
+
terminal.removeAllListeners('key');
|
|
68
|
+
} catch (error) {
|
|
69
|
+
errors.push(`${formatError(error)} (${shard})`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (errors.length) {
|
|
73
|
+
console.error(chalk.red(errors.join('\n')));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const pre = prerelease(version);
|
|
77
|
+
if (pre && pre[0] !== 'dev') {
|
|
78
|
+
await this.checkOrphanedDeploys(appId, shards);
|
|
79
|
+
}
|
|
80
|
+
} catch (e) {
|
|
81
|
+
die(formatError(e));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private async checkOrphanedDeploys(appId: string, currentShards: string[]) {
|
|
86
|
+
const criteria: Rivendell.AppVersionSearchCriteria = {
|
|
87
|
+
appId,
|
|
88
|
+
states: UNPUBLISHABLE_STATES,
|
|
89
|
+
};
|
|
90
|
+
const versions: Rivendell.AppVersion[] = await Rivendell.searchAppVersions(criteria, 'us');
|
|
91
|
+
|
|
92
|
+
if (versions.length) {
|
|
93
|
+
versions.sort((x, y) => {
|
|
94
|
+
return rcompare(x.id.version, y.id.version);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const undeployVersions: {[key: string]: Rivendell.AppVersion[]} = {};
|
|
98
|
+
for (const version of versions) {
|
|
99
|
+
const appVersion = await Rivendell.fetchAppVersion({appId, version: version.id.version}, 'us');
|
|
100
|
+
const shards = await applicableShards('', JSON.parse(appVersion.manifestJson) as AppManifest);
|
|
101
|
+
const check = shards.filter((x: string) => !currentShards.includes(x));
|
|
102
|
+
for (const s of check) {
|
|
103
|
+
undeployVersions[s] = await Rivendell.searchAppVersions(criteria, s);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (Object.keys(undeployVersions).length) {
|
|
108
|
+
console.log(`You are no longer targeting the availability: ${Object.keys(undeployVersions)}, ` +
|
|
109
|
+
`do you want to unpublish the following apps:`);
|
|
110
|
+
console.log(Object.entries(undeployVersions)
|
|
111
|
+
.map((x) => x[1].map((y) => `* ${y.id.appId}@${y.id.version} in ${x[0]}`).join('\n')).join('\n'));
|
|
112
|
+
if (await TerminalConfirm.ask(chalk.red('Do you want to unpublish the listed AppVersions now?'))) {
|
|
113
|
+
for (const [shard, toUndeploy] of Object.entries(undeployVersions)) {
|
|
114
|
+
for (const version of toUndeploy) {
|
|
115
|
+
const unpublish = new UnpublishCommand();
|
|
116
|
+
unpublish.appVersion = `${version.id.appId}@${version.id.version}`;
|
|
117
|
+
unpublish.availability = shard;
|
|
118
|
+
await unpublish.unpublish();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
private async isStopped(context: AppContext, shard: string) {
|
|
127
|
+
const appVersion = await Rivendell.fetchAppVersion(context, shard);
|
|
128
|
+
return STOPPED_STATES.includes(appVersion.state as AppVersionState);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private watchForPublishCompletion(context: AppContext, wasStopped: boolean, shard: string) {
|
|
132
|
+
console.log(chalk.gray(`Watching for publish (${shard}) to complete... CTRL+C to stop checking.`));
|
|
133
|
+
return new Promise((resolve, reject) => {
|
|
134
|
+
const spinner = this.noProgress ? null : new TerminalSpinner().start('');
|
|
135
|
+
let attempts = 0;
|
|
136
|
+
let ignoreStopped = wasStopped;
|
|
137
|
+
const checkStatus = () => {
|
|
138
|
+
attempts++;
|
|
139
|
+
Rivendell.fetchAppVersion(context, shard)
|
|
140
|
+
.then((appVersion) => {
|
|
141
|
+
const state = appVersion.state as AppVersionState;
|
|
142
|
+
if (ignoreStopped && !STOPPED_STATES.includes(state)) {
|
|
143
|
+
ignoreStopped = false;
|
|
144
|
+
}
|
|
145
|
+
if (state === AppVersionState.RUNNING || (!ignoreStopped && STOPPED_STATES.includes(state))) {
|
|
146
|
+
if (spinner) {
|
|
147
|
+
spinner.stop();
|
|
148
|
+
}
|
|
149
|
+
clearInterval(interval);
|
|
150
|
+
if (state === AppVersionState.RUNNING) {
|
|
151
|
+
console.log(chalk.green(`${context.appId}@${context.version} has been published to ${shard}.`));
|
|
152
|
+
} else {
|
|
153
|
+
die(`Publish to ${shard} failed. ${context.appId}@${context.version} ` +
|
|
154
|
+
`in ${formatVersionState(state)} state.`);
|
|
155
|
+
}
|
|
156
|
+
resolve();
|
|
157
|
+
} else {
|
|
158
|
+
if (attempts > 300) {
|
|
159
|
+
die('Timed out waiting for completion');
|
|
160
|
+
}
|
|
161
|
+
if (spinner) {
|
|
162
|
+
spinner.update(`Status: ${formatVersionState(state)}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
})
|
|
166
|
+
.catch((e) => {
|
|
167
|
+
clearInterval(interval);
|
|
168
|
+
if (spinner) {
|
|
169
|
+
spinner.stop();
|
|
170
|
+
}
|
|
171
|
+
reject(e);
|
|
172
|
+
});
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
const interval = setInterval(checkStatus, 2000);
|
|
176
|
+
checkStatus();
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|