eas-cli 3.18.0 → 3.18.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/README.md +55 -55
- package/build/branch/actions/SelectBranch.d.ts +33 -0
- package/build/branch/actions/SelectBranch.js +67 -0
- package/build/build/local.js +1 -1
- package/build/build/runBuildAndSubmit.js +0 -2
- package/build/channel/actions/SelectChannel.d.ts +16 -0
- package/build/channel/actions/SelectChannel.js +42 -24
- package/build/channel/branch-mapping.d.ts +17 -1
- package/build/channel/branch-mapping.js +48 -7
- package/build/channel/queries.d.ts +1 -6
- package/build/channel/queries.js +1 -25
- package/build/commands/build/version/get.js +0 -1
- package/build/commands/build/version/sync.js +0 -1
- package/build/commands/channel/rollout-preview.d.ts +32 -0
- package/build/commands/channel/rollout-preview.js +109 -0
- package/build/commands/metadata/lint.js +0 -1
- package/build/commands/metadata/pull.js +0 -1
- package/build/commands/metadata/push.js +0 -1
- package/build/commands/submit.js +0 -1
- package/build/commands/update/republish.js +23 -74
- package/build/graphql/generated.d.ts +192 -18
- package/build/graphql/generated.js +8 -2
- package/build/graphql/queries/BranchQuery.d.ts +3 -2
- package/build/graphql/queries/BranchQuery.js +43 -1
- package/build/graphql/queries/ChannelQuery.d.ts +3 -2
- package/build/graphql/queries/ChannelQuery.js +19 -5
- package/build/graphql/queries/RuntimeQuery.d.ts +6 -0
- package/build/graphql/queries/RuntimeQuery.js +70 -0
- package/build/graphql/types/Runtime.d.ts +1 -0
- package/build/graphql/types/Runtime.js +11 -0
- package/build/graphql/types/UpdateBranch.js +3 -1
- package/build/graphql/types/UpdateBranchBasicInfo.d.ts +1 -0
- package/build/graphql/types/UpdateBranchBasicInfo.js +11 -0
- package/build/metadata/apple/config/reader.js +1 -1
- package/build/rollout/actions/CreateRollout.d.ts +23 -0
- package/build/rollout/actions/CreateRollout.js +153 -0
- package/build/rollout/actions/EditRollout.d.ts +17 -0
- package/build/rollout/actions/EditRollout.js +79 -0
- package/build/rollout/actions/EndRollout.d.ts +24 -0
- package/build/rollout/actions/EndRollout.js +164 -0
- package/build/rollout/actions/ManageRollout.d.ts +24 -0
- package/build/rollout/actions/ManageRollout.js +78 -0
- package/build/rollout/actions/NonInteractiveRollout.d.ts +18 -0
- package/build/rollout/actions/NonInteractiveRollout.js +46 -0
- package/build/rollout/actions/RolloutMainMenu.d.ts +28 -0
- package/build/rollout/actions/RolloutMainMenu.js +110 -0
- package/build/rollout/actions/SelectRollout.js +18 -8
- package/build/rollout/actions/SelectRuntime.d.ts +36 -0
- package/build/rollout/actions/SelectRuntime.js +167 -0
- package/build/rollout/branch-mapping.d.ts +52 -4
- package/build/rollout/branch-mapping.js +68 -19
- package/build/rollout/utils.d.ts +9 -2
- package/build/rollout/utils.js +66 -21
- package/build/update/configure.d.ts +6 -1
- package/build/update/configure.js +18 -8
- package/build/update/republish.d.ts +26 -0
- package/build/update/republish.js +83 -0
- package/build/utils/profiles.d.ts +1 -2
- package/build/utils/profiles.js +3 -35
- package/build/utils/relay.d.ts +80 -15
- package/build/utils/relay.js +211 -28
- package/oclif.manifest.json +1 -1
- package/package.json +2 -2
|
@@ -140,7 +140,7 @@ class AppleConfigReader {
|
|
|
140
140
|
return {
|
|
141
141
|
locale,
|
|
142
142
|
description: info.description,
|
|
143
|
-
keywords: (_b = info.keywords) === null || _b === void 0 ? void 0 : _b.join(',
|
|
143
|
+
keywords: (_b = info.keywords) === null || _b === void 0 ? void 0 : _b.join(','),
|
|
144
144
|
// TODO: maybe move this to task logic, it's more an exception than data handling
|
|
145
145
|
whatsNew: context.versionIsFirst ? undefined : info.releaseNotes || exports.DEFAULT_WHATSNEW,
|
|
146
146
|
marketingUrl: info.marketingUrl,
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { EASUpdateAction, EASUpdateContext } from '../../eas-update/utils';
|
|
2
|
+
import { UpdateBranchBasicInfoFragment, UpdateChannelBasicInfoFragment, UpdateFragment } from '../../graphql/generated';
|
|
3
|
+
import { UpdateChannelObject } from '../../graphql/queries/ChannelQuery';
|
|
4
|
+
export type NonInteractiveOptions = {
|
|
5
|
+
branchNameToRollout: string;
|
|
6
|
+
percent: number;
|
|
7
|
+
runtimeVersion: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Create a rollout for the project.
|
|
11
|
+
*/
|
|
12
|
+
export declare class CreateRollout implements EASUpdateAction<UpdateChannelBasicInfoFragment> {
|
|
13
|
+
private channelInfo;
|
|
14
|
+
private options;
|
|
15
|
+
constructor(channelInfo: UpdateChannelBasicInfoFragment, options?: Partial<NonInteractiveOptions>);
|
|
16
|
+
runAsync(ctx: EASUpdateContext): Promise<UpdateChannelBasicInfoFragment>;
|
|
17
|
+
confirmCreationAsync(ctx: EASUpdateContext): Promise<boolean>;
|
|
18
|
+
getChannelObjectAsync(ctx: EASUpdateContext, runtimeVersion: string): Promise<UpdateChannelObject>;
|
|
19
|
+
getLatestUpdateGroupOnBranchAsync(ctx: EASUpdateContext, branchInfo: UpdateBranchBasicInfoFragment, runtimeVersion: string): Promise<UpdateFragment[] | null>;
|
|
20
|
+
selectRuntimeVersionAsync(ctx: EASUpdateContext, branchToRollout: UpdateBranchBasicInfoFragment, defaultBranchId: string): Promise<string>;
|
|
21
|
+
selectBranchAsync(ctx: EASUpdateContext, defaultBranchId: string): Promise<UpdateBranchBasicInfoFragment>;
|
|
22
|
+
resolveBranchNameAsync(ctx: EASUpdateContext, branchName: string): Promise<UpdateBranchBasicInfoFragment>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CreateRollout = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
|
+
const SelectBranch_1 = require("../../branch/actions/SelectBranch");
|
|
7
|
+
const branch_mapping_1 = require("../../channel/branch-mapping");
|
|
8
|
+
const utils_1 = require("../../channel/utils");
|
|
9
|
+
const edit_1 = require("../../commands/channel/edit");
|
|
10
|
+
const BranchQuery_1 = require("../../graphql/queries/BranchQuery");
|
|
11
|
+
const ChannelQuery_1 = require("../../graphql/queries/ChannelQuery");
|
|
12
|
+
const UpdateQuery_1 = require("../../graphql/queries/UpdateQuery");
|
|
13
|
+
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
14
|
+
const prompts_1 = require("../../prompts");
|
|
15
|
+
const branch_mapping_2 = require("../branch-mapping");
|
|
16
|
+
const utils_2 = require("../utils");
|
|
17
|
+
const SelectRuntime_1 = require("./SelectRuntime");
|
|
18
|
+
function isNonInteractiveOptions(options) {
|
|
19
|
+
return !!options.branchNameToRollout && !!options.percent && !!options.runtimeVersion;
|
|
20
|
+
}
|
|
21
|
+
function assertNonInteractiveOptions(options) {
|
|
22
|
+
(0, assert_1.default)(isNonInteractiveOptions(options), '--branch, --percent and --runtime-version are required for creating a rollout in non-interactive mode.');
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Create a rollout for the project.
|
|
26
|
+
*/
|
|
27
|
+
class CreateRollout {
|
|
28
|
+
constructor(channelInfo, options = {}) {
|
|
29
|
+
this.channelInfo = channelInfo;
|
|
30
|
+
this.options = options;
|
|
31
|
+
}
|
|
32
|
+
async runAsync(ctx) {
|
|
33
|
+
var _a, _b;
|
|
34
|
+
const { branchNameToRollout } = this.options;
|
|
35
|
+
const { nonInteractive, graphqlClient } = ctx;
|
|
36
|
+
if (nonInteractive) {
|
|
37
|
+
assertNonInteractiveOptions(this.options);
|
|
38
|
+
}
|
|
39
|
+
if ((0, branch_mapping_2.isRollout)(this.channelInfo)) {
|
|
40
|
+
throw new Error(`A rollout is already in progress for channel ${this.channelInfo.name}`);
|
|
41
|
+
}
|
|
42
|
+
if (!(0, branch_mapping_1.hasStandardBranchMap)(this.channelInfo)) {
|
|
43
|
+
throw new Error(`You have a custom branch mapping. Map your channel to a single branch before creating a rollout. Received: ${this.channelInfo.branchMapping}`);
|
|
44
|
+
}
|
|
45
|
+
const defaultBranchId = (0, branch_mapping_1.getStandardBranchId)(this.channelInfo);
|
|
46
|
+
const branchInfoToRollout = branchNameToRollout
|
|
47
|
+
? await this.resolveBranchNameAsync(ctx, branchNameToRollout)
|
|
48
|
+
: await this.selectBranchAsync(ctx, defaultBranchId);
|
|
49
|
+
if (branchInfoToRollout.id === defaultBranchId) {
|
|
50
|
+
throw new Error(`Channel ${this.channelInfo.name} is already mapped to branch ${branchInfoToRollout.name}.`);
|
|
51
|
+
}
|
|
52
|
+
const runtimeVersion = (_a = this.options.runtimeVersion) !== null && _a !== void 0 ? _a : (await this.selectRuntimeVersionAsync(ctx, branchInfoToRollout, defaultBranchId));
|
|
53
|
+
log_1.default.newLine();
|
|
54
|
+
const promptMessage = `What percent of users should be routed to branch ${branchInfoToRollout.name}?`;
|
|
55
|
+
const percent = (_b = this.options.percent) !== null && _b !== void 0 ? _b : (await (0, utils_2.promptForRolloutPercentAsync)({ promptMessage }));
|
|
56
|
+
const rolloutBranchMapping = (0, branch_mapping_2.createRolloutBranchMapping)({
|
|
57
|
+
defaultBranchId,
|
|
58
|
+
rolloutBranchId: branchInfoToRollout.id,
|
|
59
|
+
percent,
|
|
60
|
+
runtimeVersion,
|
|
61
|
+
});
|
|
62
|
+
const channelObject = await this.getChannelObjectAsync(ctx, runtimeVersion);
|
|
63
|
+
const defaultBranch = (0, utils_1.getUpdateBranch)(channelObject, defaultBranchId);
|
|
64
|
+
const defaultUpdateGroup = defaultBranch.updateGroups[0];
|
|
65
|
+
const rolloutInfo = (0, branch_mapping_2.getRolloutInfoFromBranchMapping)(rolloutBranchMapping);
|
|
66
|
+
const rolledOutBranchUpdateGroup = await this.getLatestUpdateGroupOnBranchAsync(ctx, branchInfoToRollout, runtimeVersion);
|
|
67
|
+
const rolledOutBranch = (0, ChannelQuery_1.composeUpdateBranchObject)(branchInfoToRollout, rolledOutBranchUpdateGroup ? [rolledOutBranchUpdateGroup] : []);
|
|
68
|
+
const rollout = (0, branch_mapping_2.composeRollout)(rolloutInfo, defaultBranch, rolledOutBranch);
|
|
69
|
+
(0, utils_2.displayRolloutDetails)(this.channelInfo.name, rollout);
|
|
70
|
+
log_1.default.log((0, utils_2.formatBranchWithUpdateGroup)(defaultUpdateGroup, defaultBranch, 100 - rollout.percentRolledOut));
|
|
71
|
+
log_1.default.addNewLineIfNone();
|
|
72
|
+
log_1.default.log((0, utils_2.formatBranchWithUpdateGroup)(rolledOutBranchUpdateGroup, rolledOutBranch, rollout.percentRolledOut));
|
|
73
|
+
log_1.default.addNewLineIfNone();
|
|
74
|
+
const didConfirm = await this.confirmCreationAsync(ctx);
|
|
75
|
+
if (!didConfirm) {
|
|
76
|
+
throw new Error('Aborting...');
|
|
77
|
+
}
|
|
78
|
+
const newChannelInfo = await (0, edit_1.updateChannelBranchMappingAsync)(graphqlClient, {
|
|
79
|
+
channelId: this.channelInfo.id,
|
|
80
|
+
branchMapping: JSON.stringify(rolloutBranchMapping),
|
|
81
|
+
});
|
|
82
|
+
log_1.default.succeed('✅ Successfully created rollout');
|
|
83
|
+
return newChannelInfo;
|
|
84
|
+
}
|
|
85
|
+
async confirmCreationAsync(ctx) {
|
|
86
|
+
const { nonInteractive } = ctx;
|
|
87
|
+
if (nonInteractive) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
return await (0, prompts_1.confirmAsync)({
|
|
91
|
+
message: `Create rollout?`,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
async getChannelObjectAsync(ctx, runtimeVersion) {
|
|
95
|
+
const { graphqlClient, app } = ctx;
|
|
96
|
+
const { projectId } = app;
|
|
97
|
+
return await ChannelQuery_1.ChannelQuery.viewUpdateChannelAsync(graphqlClient, {
|
|
98
|
+
appId: projectId,
|
|
99
|
+
channelName: this.channelInfo.name,
|
|
100
|
+
filter: { runtimeVersions: [runtimeVersion] },
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
async getLatestUpdateGroupOnBranchAsync(ctx, branchInfo, runtimeVersion) {
|
|
104
|
+
var _a;
|
|
105
|
+
const { graphqlClient, app } = ctx;
|
|
106
|
+
const { projectId } = app;
|
|
107
|
+
const updateGroups = await UpdateQuery_1.UpdateQuery.viewUpdateGroupsOnBranchAsync(graphqlClient, {
|
|
108
|
+
appId: projectId,
|
|
109
|
+
branchName: branchInfo.name,
|
|
110
|
+
limit: 1,
|
|
111
|
+
offset: 0,
|
|
112
|
+
filter: {
|
|
113
|
+
runtimeVersions: [runtimeVersion],
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
(0, assert_1.default)(updateGroups.length < 2, `Expected at most one update group. Received: ${JSON.stringify(updateGroups)}`);
|
|
117
|
+
return (_a = updateGroups[0]) !== null && _a !== void 0 ? _a : null;
|
|
118
|
+
}
|
|
119
|
+
async selectRuntimeVersionAsync(ctx, branchToRollout, defaultBranchId) {
|
|
120
|
+
const { graphqlClient, app } = ctx;
|
|
121
|
+
const { projectId } = app;
|
|
122
|
+
// we just want the branch name, not the update group
|
|
123
|
+
const channelObjectRtvAgnostic = await ChannelQuery_1.ChannelQuery.viewUpdateChannelAsync(graphqlClient, {
|
|
124
|
+
appId: projectId,
|
|
125
|
+
channelName: this.channelInfo.name,
|
|
126
|
+
});
|
|
127
|
+
const defaultBranchRtvAgnostic = (0, utils_1.getUpdateBranch)(channelObjectRtvAgnostic, defaultBranchId);
|
|
128
|
+
const selectRuntimeAction = new SelectRuntime_1.SelectRuntime(branchToRollout, {
|
|
129
|
+
anotherBranchToIntersectRuntimesBy: defaultBranchRtvAgnostic,
|
|
130
|
+
});
|
|
131
|
+
return await selectRuntimeAction.runAsync(ctx);
|
|
132
|
+
}
|
|
133
|
+
async selectBranchAsync(ctx, defaultBranchId) {
|
|
134
|
+
const selectBranchAction = new SelectBranch_1.SelectBranch({
|
|
135
|
+
printedType: 'branch to rollout',
|
|
136
|
+
// we don't want to show the default branch as an option
|
|
137
|
+
filterPredicate: (branchInfo) => branchInfo.id !== defaultBranchId,
|
|
138
|
+
});
|
|
139
|
+
const branchInfo = await selectBranchAction.runAsync(ctx);
|
|
140
|
+
if (!branchInfo) {
|
|
141
|
+
throw new Error(`You dont have any branches. Create one with 'eas branch:create'`);
|
|
142
|
+
}
|
|
143
|
+
return branchInfo;
|
|
144
|
+
}
|
|
145
|
+
async resolveBranchNameAsync(ctx, branchName) {
|
|
146
|
+
const { graphqlClient, app } = ctx;
|
|
147
|
+
return await BranchQuery_1.BranchQuery.getBranchByNameAsync(graphqlClient, {
|
|
148
|
+
appId: app.projectId,
|
|
149
|
+
name: branchName,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
exports.CreateRollout = CreateRollout;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { EASUpdateAction, EASUpdateContext } from '../../eas-update/utils';
|
|
2
|
+
import { UpdateChannelBasicInfoFragment } from '../../graphql/generated';
|
|
3
|
+
import { UpdateChannelObject } from '../../graphql/queries/ChannelQuery';
|
|
4
|
+
export type NonInteractiveOptions = {
|
|
5
|
+
percent: number;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Edit an existing rollout for the project.
|
|
9
|
+
*/
|
|
10
|
+
export declare class EditRollout implements EASUpdateAction<UpdateChannelBasicInfoFragment> {
|
|
11
|
+
private channelInfo;
|
|
12
|
+
private options;
|
|
13
|
+
constructor(channelInfo: UpdateChannelBasicInfoFragment, options?: Partial<NonInteractiveOptions>);
|
|
14
|
+
runAsync(ctx: EASUpdateContext): Promise<UpdateChannelBasicInfoFragment>;
|
|
15
|
+
confirmEditAsync(ctx: EASUpdateContext): Promise<boolean>;
|
|
16
|
+
getChannelObjectAsync(ctx: EASUpdateContext): Promise<UpdateChannelObject>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EditRollout = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
7
|
+
const edit_1 = require("../../commands/channel/edit");
|
|
8
|
+
const ChannelQuery_1 = require("../../graphql/queries/ChannelQuery");
|
|
9
|
+
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
10
|
+
const prompts_1 = require("../../prompts");
|
|
11
|
+
const branch_mapping_1 = require("../branch-mapping");
|
|
12
|
+
const utils_1 = require("../utils");
|
|
13
|
+
function isNonInteractiveOptions(options) {
|
|
14
|
+
return !!options.percent;
|
|
15
|
+
}
|
|
16
|
+
function assertNonInteractiveOptions(options) {
|
|
17
|
+
(0, assert_1.default)(isNonInteractiveOptions(options), '--percent is required for editing a rollout in non-interactive mode.');
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Edit an existing rollout for the project.
|
|
21
|
+
*/
|
|
22
|
+
class EditRollout {
|
|
23
|
+
constructor(channelInfo, options = {}) {
|
|
24
|
+
this.channelInfo = channelInfo;
|
|
25
|
+
this.options = options;
|
|
26
|
+
}
|
|
27
|
+
async runAsync(ctx) {
|
|
28
|
+
var _a;
|
|
29
|
+
const { nonInteractive, graphqlClient } = ctx;
|
|
30
|
+
if (nonInteractive) {
|
|
31
|
+
assertNonInteractiveOptions(this.options);
|
|
32
|
+
}
|
|
33
|
+
const channelObject = await this.getChannelObjectAsync(ctx);
|
|
34
|
+
const rollout = (0, branch_mapping_1.getRollout)(channelObject);
|
|
35
|
+
const { rolledOutBranch, defaultBranch } = rollout;
|
|
36
|
+
const promptMessage = `What percent of users should be directed to the ${rolledOutBranch.name} branch ?`;
|
|
37
|
+
const percent = (_a = this.options.percent) !== null && _a !== void 0 ? _a : (await (0, utils_1.promptForRolloutPercentAsync)({ promptMessage }));
|
|
38
|
+
const oldBranchMapping = (0, branch_mapping_1.getRolloutBranchMapping)(channelObject.branchMapping);
|
|
39
|
+
const newBranchMapping = (0, branch_mapping_1.editRolloutBranchMapping)(oldBranchMapping, percent);
|
|
40
|
+
log_1.default.newLine();
|
|
41
|
+
log_1.default.log(`📝 The updated rollout will send ${chalk_1.default.bold(percent)}% of users to the ${chalk_1.default.bold(rolledOutBranch.name)} branch and ${chalk_1.default.bold(100 - percent)}% to the ${chalk_1.default.bold(defaultBranch.name)} branch.`);
|
|
42
|
+
const confirmEdit = await this.confirmEditAsync(ctx);
|
|
43
|
+
if (!confirmEdit) {
|
|
44
|
+
throw new Error('Aborting...');
|
|
45
|
+
}
|
|
46
|
+
const newChannelInfo = await (0, edit_1.updateChannelBranchMappingAsync)(graphqlClient, {
|
|
47
|
+
channelId: channelObject.id,
|
|
48
|
+
branchMapping: JSON.stringify(newBranchMapping),
|
|
49
|
+
});
|
|
50
|
+
log_1.default.addNewLineIfNone();
|
|
51
|
+
log_1.default.log(`✅ Successfuly updated rollout`);
|
|
52
|
+
return newChannelInfo;
|
|
53
|
+
}
|
|
54
|
+
async confirmEditAsync(ctx) {
|
|
55
|
+
const { nonInteractive } = ctx;
|
|
56
|
+
if (nonInteractive) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
return await (0, prompts_1.confirmAsync)({
|
|
60
|
+
message: `Confirm changes?`,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
async getChannelObjectAsync(ctx) {
|
|
64
|
+
const { graphqlClient, app } = ctx;
|
|
65
|
+
const { projectId } = app;
|
|
66
|
+
if (!(0, branch_mapping_1.isRollout)(this.channelInfo)) {
|
|
67
|
+
throw new Error(`The channel ${chalk_1.default.bold(this.channelInfo.name)} is not a rollout. To end a rollout, you must specify a channel with an ongoing rollout.`);
|
|
68
|
+
}
|
|
69
|
+
const rolloutInfo = (0, branch_mapping_1.getRolloutInfo)(this.channelInfo);
|
|
70
|
+
return await ChannelQuery_1.ChannelQuery.viewUpdateChannelAsync(graphqlClient, {
|
|
71
|
+
appId: projectId,
|
|
72
|
+
channelName: this.channelInfo.name,
|
|
73
|
+
...((0, branch_mapping_1.isConstrainedRolloutInfo)(rolloutInfo)
|
|
74
|
+
? { filter: { runtimeVersions: [rolloutInfo.runtimeVersion] } }
|
|
75
|
+
: {}),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.EditRollout = EditRollout;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { EASUpdateAction, EASUpdateContext } from '../../eas-update/utils';
|
|
2
|
+
import { UpdateChannelBasicInfoFragment } from '../../graphql/generated';
|
|
3
|
+
import { UpdateChannelObject } from '../../graphql/queries/ChannelQuery';
|
|
4
|
+
import { Rollout } from '../branch-mapping';
|
|
5
|
+
export declare enum EndOutcome {
|
|
6
|
+
REPUBLISH_AND_ROUTE_BACK = "republish-and-route-back",
|
|
7
|
+
ROUTE_BACK = "route-back"
|
|
8
|
+
}
|
|
9
|
+
export type NonInteractiveOptions = {
|
|
10
|
+
outcome: EndOutcome;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* End an existing rollout for the project.
|
|
14
|
+
*/
|
|
15
|
+
export declare class EndRollout implements EASUpdateAction<UpdateChannelBasicInfoFragment> {
|
|
16
|
+
private channelInfo;
|
|
17
|
+
private options;
|
|
18
|
+
constructor(channelInfo: UpdateChannelBasicInfoFragment, options?: Partial<NonInteractiveOptions>);
|
|
19
|
+
runAsync(ctx: EASUpdateContext): Promise<UpdateChannelBasicInfoFragment>;
|
|
20
|
+
getChannelObjectAsync(ctx: EASUpdateContext): Promise<UpdateChannelObject>;
|
|
21
|
+
selectOutcomeAsync(rollout: Rollout): Promise<EndOutcome>;
|
|
22
|
+
performOutcomeAsync(ctx: EASUpdateContext, rollout: Rollout, outcome: EndOutcome): Promise<UpdateChannelBasicInfoFragment>;
|
|
23
|
+
confirmOutcomeAsync(ctx: EASUpdateContext, selectedOutcome: EndOutcome, rollout: Rollout): Promise<boolean>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EndRollout = exports.EndOutcome = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
7
|
+
const branch_mapping_1 = require("../../channel/branch-mapping");
|
|
8
|
+
const edit_1 = require("../../commands/channel/edit");
|
|
9
|
+
const ChannelQuery_1 = require("../../graphql/queries/ChannelQuery");
|
|
10
|
+
const log_1 = tslib_1.__importDefault(require("../../log"));
|
|
11
|
+
const prompts_1 = require("../../prompts");
|
|
12
|
+
const republish_1 = require("../../update/republish");
|
|
13
|
+
const formatFields_1 = tslib_1.__importDefault(require("../../utils/formatFields"));
|
|
14
|
+
const branch_mapping_2 = require("../branch-mapping");
|
|
15
|
+
const utils_1 = require("../utils");
|
|
16
|
+
var EndOutcome;
|
|
17
|
+
(function (EndOutcome) {
|
|
18
|
+
EndOutcome["REPUBLISH_AND_ROUTE_BACK"] = "republish-and-route-back";
|
|
19
|
+
EndOutcome["ROUTE_BACK"] = "route-back";
|
|
20
|
+
})(EndOutcome = exports.EndOutcome || (exports.EndOutcome = {}));
|
|
21
|
+
function isNonInteractiveOptions(options) {
|
|
22
|
+
return !!options.outcome;
|
|
23
|
+
}
|
|
24
|
+
function assertNonInteractiveOptions(options) {
|
|
25
|
+
(0, assert_1.default)(isNonInteractiveOptions(options), '--outcome is required for ending a rollout in non-interactive mode.');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* End an existing rollout for the project.
|
|
29
|
+
*/
|
|
30
|
+
class EndRollout {
|
|
31
|
+
constructor(channelInfo, options = {}) {
|
|
32
|
+
this.channelInfo = channelInfo;
|
|
33
|
+
this.options = options;
|
|
34
|
+
}
|
|
35
|
+
async runAsync(ctx) {
|
|
36
|
+
var _a;
|
|
37
|
+
const { nonInteractive } = ctx;
|
|
38
|
+
if (nonInteractive) {
|
|
39
|
+
assertNonInteractiveOptions(this.options);
|
|
40
|
+
}
|
|
41
|
+
const channelObject = await this.getChannelObjectAsync(ctx);
|
|
42
|
+
const rollout = (0, branch_mapping_2.getRollout)(channelObject);
|
|
43
|
+
const { rolledOutBranch } = rollout;
|
|
44
|
+
const rolledOutUpdateGroup = rolledOutBranch.updateGroups[0];
|
|
45
|
+
let outcome;
|
|
46
|
+
if (!rolledOutUpdateGroup) {
|
|
47
|
+
log_1.default.log(`⚠️ There is no Update Group being served on ${rolledOutBranch.name}.`);
|
|
48
|
+
(0, assert_1.default)(this.options.outcome !== EndOutcome.REPUBLISH_AND_ROUTE_BACK, 'The only valid outcome for this rollout is to route back to the default branch. ');
|
|
49
|
+
outcome = EndOutcome.ROUTE_BACK;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
outcome = (_a = this.options.outcome) !== null && _a !== void 0 ? _a : (await this.selectOutcomeAsync(rollout));
|
|
53
|
+
}
|
|
54
|
+
const didConfirm = await this.confirmOutcomeAsync(ctx, outcome, rollout);
|
|
55
|
+
if (!didConfirm) {
|
|
56
|
+
if (!rolledOutUpdateGroup) {
|
|
57
|
+
log_1.default.log(`If you wish to stop serving updates to your users, you can edit your rollout to 100% on ${chalk_1.default.bold(rolledOutBranch.name)} instead`);
|
|
58
|
+
}
|
|
59
|
+
throw new Error('Aborting...');
|
|
60
|
+
}
|
|
61
|
+
return await this.performOutcomeAsync(ctx, rollout, outcome);
|
|
62
|
+
}
|
|
63
|
+
async getChannelObjectAsync(ctx) {
|
|
64
|
+
const { graphqlClient, app } = ctx;
|
|
65
|
+
const { projectId } = app;
|
|
66
|
+
if (!(0, branch_mapping_2.isRollout)(this.channelInfo)) {
|
|
67
|
+
throw new Error(`The channel ${chalk_1.default.bold(this.channelInfo.name)} is not a rollout. To end a rollout, you must specify a channel with an ongoing rollout.`);
|
|
68
|
+
}
|
|
69
|
+
const rolloutInfo = (0, branch_mapping_2.getRolloutInfo)(this.channelInfo);
|
|
70
|
+
return await ChannelQuery_1.ChannelQuery.viewUpdateChannelAsync(graphqlClient, {
|
|
71
|
+
appId: projectId,
|
|
72
|
+
channelName: this.channelInfo.name,
|
|
73
|
+
...((0, branch_mapping_2.isConstrainedRolloutInfo)(rolloutInfo)
|
|
74
|
+
? { filter: { runtimeVersions: [rolloutInfo.runtimeVersion] } }
|
|
75
|
+
: {}),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
async selectOutcomeAsync(rollout) {
|
|
79
|
+
const { rolledOutBranch, percentRolledOut, defaultBranch } = rollout;
|
|
80
|
+
const rolledOutUpdateGroup = rolledOutBranch.updateGroups[0];
|
|
81
|
+
const defaultUpdateGroup = defaultBranch.updateGroups[0];
|
|
82
|
+
const outcomes = [
|
|
83
|
+
{
|
|
84
|
+
value: EndOutcome.REPUBLISH_AND_ROUTE_BACK,
|
|
85
|
+
title: (0, utils_1.formatBranchWithUpdateGroup)(rolledOutUpdateGroup, rolledOutBranch, percentRolledOut),
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
value: EndOutcome.ROUTE_BACK,
|
|
89
|
+
title: (0, utils_1.formatBranchWithUpdateGroup)(defaultUpdateGroup, defaultBranch, 100 - percentRolledOut),
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
const { outcome: selectedOutcome } = await (0, prompts_1.promptAsync)({
|
|
93
|
+
type: 'select',
|
|
94
|
+
name: 'outcome',
|
|
95
|
+
message: `Which Update Group would you like to serve?`,
|
|
96
|
+
choices: outcomes,
|
|
97
|
+
});
|
|
98
|
+
log_1.default.newLine();
|
|
99
|
+
if (selectedOutcome === EndOutcome.REPUBLISH_AND_ROUTE_BACK) {
|
|
100
|
+
log_1.default.log(`🍽️ The Update Group you chose is served by branch ${chalk_1.default.bold(rolledOutBranch.name)}`);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
log_1.default.log(`🍽️ The Update Group you chose is served by branch ${chalk_1.default.bold(defaultBranch.name)}`);
|
|
104
|
+
}
|
|
105
|
+
return selectedOutcome;
|
|
106
|
+
}
|
|
107
|
+
async performOutcomeAsync(ctx, rollout, outcome) {
|
|
108
|
+
const { graphqlClient, app } = ctx;
|
|
109
|
+
const { rolledOutBranch, defaultBranch } = rollout;
|
|
110
|
+
const rolledOutUpdateGroup = rolledOutBranch.updateGroups[0];
|
|
111
|
+
if (outcome === EndOutcome.REPUBLISH_AND_ROUTE_BACK) {
|
|
112
|
+
const arbitraryUpdate = rolledOutUpdateGroup[0];
|
|
113
|
+
const { message: oldUpdateMessage, group: oldGroupId } = arbitraryUpdate;
|
|
114
|
+
const newUpdateMessage = `Republish "${oldUpdateMessage}" - group: ${oldGroupId}`;
|
|
115
|
+
await (0, republish_1.republishAsync)({
|
|
116
|
+
graphqlClient,
|
|
117
|
+
app,
|
|
118
|
+
updatesToPublish: rolledOutUpdateGroup.map(update => ({
|
|
119
|
+
...update,
|
|
120
|
+
groupId: update.group,
|
|
121
|
+
branchId: update.branch.id,
|
|
122
|
+
branchName: update.branch.name,
|
|
123
|
+
})),
|
|
124
|
+
targetBranch: { branchId: defaultBranch.id, branchName: defaultBranch.name },
|
|
125
|
+
updateMessage: newUpdateMessage,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
const alwaysTrueDefaultBranchMapping = (0, branch_mapping_1.getAlwaysTrueBranchMapping)(defaultBranch.id);
|
|
129
|
+
const newChannelInfo = await (0, edit_1.updateChannelBranchMappingAsync)(graphqlClient, {
|
|
130
|
+
channelId: this.channelInfo.id,
|
|
131
|
+
branchMapping: JSON.stringify(alwaysTrueDefaultBranchMapping),
|
|
132
|
+
});
|
|
133
|
+
log_1.default.addNewLineIfNone();
|
|
134
|
+
log_1.default.log(`🚗 Routed all traffic back to branch ${chalk_1.default.bold(defaultBranch.name)}`);
|
|
135
|
+
log_1.default.log(`✅ Successfully ended rollout`);
|
|
136
|
+
return newChannelInfo;
|
|
137
|
+
}
|
|
138
|
+
async confirmOutcomeAsync(ctx, selectedOutcome, rollout) {
|
|
139
|
+
const { nonInteractive } = ctx;
|
|
140
|
+
if (nonInteractive) {
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
const { rolledOutBranch, defaultBranch } = rollout;
|
|
144
|
+
log_1.default.newLine();
|
|
145
|
+
if (selectedOutcome === EndOutcome.REPUBLISH_AND_ROUTE_BACK) {
|
|
146
|
+
log_1.default.log(`Ending the rollout will do the following:`);
|
|
147
|
+
const actions = (0, formatFields_1.default)([
|
|
148
|
+
{
|
|
149
|
+
label: '1.',
|
|
150
|
+
value: `🔁 Republish the Update Group from ${chalk_1.default.bold(rolledOutBranch.name)} onto ${chalk_1.default.bold(defaultBranch.name)}`,
|
|
151
|
+
},
|
|
152
|
+
{ label: '2.', value: `⬅️ Route all users back to ${chalk_1.default.bold(defaultBranch.name)}` },
|
|
153
|
+
]);
|
|
154
|
+
log_1.default.log(actions);
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
log_1.default.log(`⬅️ Ending the rollout will route all users back to ${chalk_1.default.bold(defaultBranch.name)}`);
|
|
158
|
+
}
|
|
159
|
+
return await (0, prompts_1.confirmAsync)({
|
|
160
|
+
message: `Continue?`,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
exports.EndRollout = EndRollout;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { EASUpdateAction, EASUpdateContext } from '../../eas-update/utils';
|
|
2
|
+
import { UpdateChannelBasicInfoFragment } from '../../graphql/generated';
|
|
3
|
+
import { UpdateChannelObject } from '../../graphql/queries/ChannelQuery';
|
|
4
|
+
import { NonInteractiveOptions as EditRolloutNonInteractiveOptions } from './EditRollout';
|
|
5
|
+
import { NonInteractiveOptions as EndRolloutNonInteractiveOptions } from './EndRollout';
|
|
6
|
+
export declare enum ManageRolloutActions {
|
|
7
|
+
EDIT = "Edit",
|
|
8
|
+
END = "End",
|
|
9
|
+
GO_BACK = "Go back"
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Manage a rollout for the project.
|
|
13
|
+
*/
|
|
14
|
+
export declare class ManageRollout implements EASUpdateAction<EASUpdateAction> {
|
|
15
|
+
private channelInfo;
|
|
16
|
+
private options;
|
|
17
|
+
constructor(channelInfo: UpdateChannelBasicInfoFragment, options?: {
|
|
18
|
+
callingAction?: EASUpdateAction;
|
|
19
|
+
action?: ManageRolloutActions.EDIT | ManageRolloutActions.END;
|
|
20
|
+
} & Partial<EditRolloutNonInteractiveOptions> & Partial<EndRolloutNonInteractiveOptions>);
|
|
21
|
+
runAsync(ctx: EASUpdateContext): Promise<EASUpdateAction>;
|
|
22
|
+
selectActionAsync(): Promise<ManageRolloutActions>;
|
|
23
|
+
getChannelObjectAsync(ctx: EASUpdateContext): Promise<UpdateChannelObject>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ManageRollout = exports.ManageRolloutActions = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
7
|
+
const ChannelQuery_1 = require("../../graphql/queries/ChannelQuery");
|
|
8
|
+
const prompts_1 = require("../../prompts");
|
|
9
|
+
const branch_mapping_1 = require("../branch-mapping");
|
|
10
|
+
const utils_1 = require("../utils");
|
|
11
|
+
const EditRollout_1 = require("./EditRollout");
|
|
12
|
+
const EndRollout_1 = require("./EndRollout");
|
|
13
|
+
var ManageRolloutActions;
|
|
14
|
+
(function (ManageRolloutActions) {
|
|
15
|
+
ManageRolloutActions["EDIT"] = "Edit";
|
|
16
|
+
ManageRolloutActions["END"] = "End";
|
|
17
|
+
ManageRolloutActions["GO_BACK"] = "Go back";
|
|
18
|
+
})(ManageRolloutActions = exports.ManageRolloutActions || (exports.ManageRolloutActions = {}));
|
|
19
|
+
/**
|
|
20
|
+
* Manage a rollout for the project.
|
|
21
|
+
*/
|
|
22
|
+
class ManageRollout {
|
|
23
|
+
constructor(channelInfo, options = {}) {
|
|
24
|
+
this.channelInfo = channelInfo;
|
|
25
|
+
this.options = options;
|
|
26
|
+
}
|
|
27
|
+
async runAsync(ctx) {
|
|
28
|
+
var _a;
|
|
29
|
+
const { nonInteractive } = ctx;
|
|
30
|
+
if (nonInteractive) {
|
|
31
|
+
throw new Error(`rollout selection cannot be run in non-interactive mode.`);
|
|
32
|
+
}
|
|
33
|
+
const channelObject = await this.getChannelObjectAsync(ctx);
|
|
34
|
+
(0, utils_1.printRollout)(channelObject);
|
|
35
|
+
const action = (_a = this.options.action) !== null && _a !== void 0 ? _a : (await this.selectActionAsync());
|
|
36
|
+
switch (action) {
|
|
37
|
+
case ManageRolloutActions.EDIT:
|
|
38
|
+
return new EditRollout_1.EditRollout(this.channelInfo, this.options);
|
|
39
|
+
case ManageRolloutActions.END:
|
|
40
|
+
return new EndRollout_1.EndRollout(this.channelInfo, this.options);
|
|
41
|
+
case ManageRolloutActions.GO_BACK:
|
|
42
|
+
(0, assert_1.default)(this.options.callingAction, 'calling action must be defined');
|
|
43
|
+
return this.options.callingAction;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async selectActionAsync() {
|
|
47
|
+
const manageOptions = [ManageRolloutActions.EDIT, ManageRolloutActions.END];
|
|
48
|
+
if (this.options.callingAction) {
|
|
49
|
+
manageOptions.push(ManageRolloutActions.GO_BACK);
|
|
50
|
+
}
|
|
51
|
+
const { manageOption: selectedManageOption } = await (0, prompts_1.promptAsync)({
|
|
52
|
+
type: 'select',
|
|
53
|
+
name: 'manageOption',
|
|
54
|
+
message: `What would you like to do?`,
|
|
55
|
+
choices: manageOptions.map(manageOption => ({
|
|
56
|
+
value: manageOption,
|
|
57
|
+
title: manageOption,
|
|
58
|
+
})),
|
|
59
|
+
});
|
|
60
|
+
return selectedManageOption;
|
|
61
|
+
}
|
|
62
|
+
async getChannelObjectAsync(ctx) {
|
|
63
|
+
const { graphqlClient, app } = ctx;
|
|
64
|
+
const { projectId } = app;
|
|
65
|
+
if (!(0, branch_mapping_1.isRollout)(this.channelInfo)) {
|
|
66
|
+
throw new Error(`The channel ${chalk_1.default.bold(this.channelInfo.name)} is not a rollout. To manage a rollout, you must specify a channel with an ongoing rollout.`);
|
|
67
|
+
}
|
|
68
|
+
const rolloutInfo = (0, branch_mapping_1.getRolloutInfo)(this.channelInfo);
|
|
69
|
+
return await ChannelQuery_1.ChannelQuery.viewUpdateChannelAsync(graphqlClient, {
|
|
70
|
+
appId: projectId,
|
|
71
|
+
channelName: this.channelInfo.name,
|
|
72
|
+
...((0, branch_mapping_1.isConstrainedRolloutInfo)(rolloutInfo)
|
|
73
|
+
? { filter: { runtimeVersions: [rolloutInfo.runtimeVersion] } }
|
|
74
|
+
: {}),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.ManageRollout = ManageRollout;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { EASUpdateAction, EASUpdateContext } from '../../eas-update/utils';
|
|
2
|
+
import { UpdateChannelBasicInfoFragment } from '../../graphql/generated';
|
|
3
|
+
import { NonInteractiveOptions as CreateRolloutNonInteractiveOptions } from './CreateRollout';
|
|
4
|
+
import { NonInteractiveOptions as EditRolloutNonInteractiveOptions } from './EditRollout';
|
|
5
|
+
import { NonInteractiveOptions as EndRolloutNonInteractiveOptions } from './EndRollout';
|
|
6
|
+
import { RolloutActions } from './RolloutMainMenu';
|
|
7
|
+
/**
|
|
8
|
+
* Control a rollout in non interactive mode.
|
|
9
|
+
*/
|
|
10
|
+
export declare class NonInteractiveRollout implements EASUpdateAction<void> {
|
|
11
|
+
private options;
|
|
12
|
+
constructor(options?: {
|
|
13
|
+
channelName?: string;
|
|
14
|
+
action?: RolloutActions;
|
|
15
|
+
} & Partial<EditRolloutNonInteractiveOptions> & Partial<EndRolloutNonInteractiveOptions> & Partial<CreateRolloutNonInteractiveOptions>);
|
|
16
|
+
runAsync(ctx: EASUpdateContext): Promise<void>;
|
|
17
|
+
runActionAsync(ctx: EASUpdateContext, action: RolloutActions, channelInfo: UpdateChannelBasicInfoFragment, options: Partial<EditRolloutNonInteractiveOptions> & Partial<EndRolloutNonInteractiveOptions> & Partial<CreateRolloutNonInteractiveOptions>): Promise<UpdateChannelBasicInfoFragment>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NonInteractiveRollout = void 0;
|
|
4
|
+
const ChannelQuery_1 = require("../../graphql/queries/ChannelQuery");
|
|
5
|
+
const CreateRollout_1 = require("./CreateRollout");
|
|
6
|
+
const EditRollout_1 = require("./EditRollout");
|
|
7
|
+
const EndRollout_1 = require("./EndRollout");
|
|
8
|
+
const ManageRollout_1 = require("./ManageRollout");
|
|
9
|
+
const RolloutMainMenu_1 = require("./RolloutMainMenu");
|
|
10
|
+
/**
|
|
11
|
+
* Control a rollout in non interactive mode.
|
|
12
|
+
*/
|
|
13
|
+
class NonInteractiveRollout {
|
|
14
|
+
constructor(options = {}) {
|
|
15
|
+
this.options = options;
|
|
16
|
+
}
|
|
17
|
+
async runAsync(ctx) {
|
|
18
|
+
const { channelName, action } = this.options;
|
|
19
|
+
const { nonInteractive, app, graphqlClient } = ctx;
|
|
20
|
+
if (!nonInteractive) {
|
|
21
|
+
throw new Error(`This action is meant for non-interactive mode.`);
|
|
22
|
+
}
|
|
23
|
+
if (!channelName) {
|
|
24
|
+
throw new Error(`The channel argument is required in non-interactive mode. Run eas channel:rollout [channel-name]`);
|
|
25
|
+
}
|
|
26
|
+
const channelInfo = await ChannelQuery_1.ChannelQuery.viewUpdateChannelAsync(graphqlClient, {
|
|
27
|
+
appId: app.projectId,
|
|
28
|
+
channelName,
|
|
29
|
+
});
|
|
30
|
+
if (!action) {
|
|
31
|
+
throw new Error(`--action is required in non-interactive mode.`);
|
|
32
|
+
}
|
|
33
|
+
await this.runActionAsync(ctx, action, channelInfo, this.options);
|
|
34
|
+
}
|
|
35
|
+
async runActionAsync(ctx, action, channelInfo, options) {
|
|
36
|
+
switch (action) {
|
|
37
|
+
case RolloutMainMenu_1.MainMenuActions.CREATE_NEW:
|
|
38
|
+
return await new CreateRollout_1.CreateRollout(channelInfo, options).runAsync(ctx);
|
|
39
|
+
case ManageRollout_1.ManageRolloutActions.EDIT:
|
|
40
|
+
return await new EditRollout_1.EditRollout(channelInfo, options).runAsync(ctx);
|
|
41
|
+
case ManageRollout_1.ManageRolloutActions.END:
|
|
42
|
+
return await new EndRollout_1.EndRollout(channelInfo, options).runAsync(ctx);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.NonInteractiveRollout = NonInteractiveRollout;
|