eas-cli 0.46.0 → 0.47.0
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 +842 -2
- package/build/build/android/syncProjectConfiguration.js +2 -2
- package/build/build/ios/syncProjectConfiguration.js +2 -2
- package/build/build/metadata.js +1 -2
- package/build/build/utils/updates.d.ts +0 -1
- package/build/build/utils/updates.js +1 -7
- package/build/commands/build/configure.js +1 -2
- package/build/commands/channel/create.js +7 -6
- package/build/commands/channel/edit.js +34 -28
- package/build/commands/channel/rollout.js +47 -38
- package/build/commands/channel/view.d.ts +0 -2
- package/build/commands/channel/view.js +3 -47
- package/build/commands/update/delete.js +2 -2
- package/build/commands/update/index.js +14 -0
- package/build/graphql/generated.d.ts +19 -0
- package/build/graphql/queries/BranchQuery.d.ts +7 -0
- package/build/graphql/queries/BranchQuery.js +29 -0
- package/build/graphql/queries/ChannelQuery.d.ts +4 -0
- package/build/graphql/queries/ChannelQuery.js +49 -0
- package/build/project/projectUtils.d.ts +5 -5
- package/build/project/projectUtils.js +24 -25
- package/oclif.manifest.json +1 -1
- package/package.json +16 -16
|
@@ -8,8 +8,8 @@ const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
|
|
|
8
8
|
const fs_extra_1 = (0, tslib_1.__importDefault)(require("fs-extra"));
|
|
9
9
|
const path_1 = (0, tslib_1.__importDefault)(require("path"));
|
|
10
10
|
const log_1 = (0, tslib_1.__importDefault)(require("../../log"));
|
|
11
|
+
const projectUtils_1 = require("../../project/projectUtils");
|
|
11
12
|
const workflow_1 = require("../../project/workflow");
|
|
12
|
-
const updates_1 = require("../utils/updates");
|
|
13
13
|
const UpdatesModule_1 = require("./UpdatesModule");
|
|
14
14
|
const version_1 = require("./version");
|
|
15
15
|
async function syncProjectConfigurationAsync({ projectDir, exp, buildProfile, }) {
|
|
@@ -18,7 +18,7 @@ async function syncProjectConfigurationAsync({ projectDir, exp, buildProfile, })
|
|
|
18
18
|
const versionBumpStrategy = resolveVersionBumpStrategy(autoIncrement !== null && autoIncrement !== void 0 ? autoIncrement : false);
|
|
19
19
|
if (workflow === eas_build_job_1.Workflow.GENERIC) {
|
|
20
20
|
await cleanUpOldEasBuildGradleScriptAsync(projectDir);
|
|
21
|
-
if ((0,
|
|
21
|
+
if ((0, projectUtils_1.isExpoUpdatesInstalled)(projectDir)) {
|
|
22
22
|
await (0, UpdatesModule_1.syncUpdatesConfigurationAsync)(projectDir, exp);
|
|
23
23
|
}
|
|
24
24
|
await (0, version_1.bumpVersionAsync)({ projectDir, exp, bumpStrategy: versionBumpStrategy });
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.syncProjectConfigurationAsync = void 0;
|
|
4
4
|
const eas_build_job_1 = require("@expo/eas-build-job");
|
|
5
|
+
const projectUtils_1 = require("../../project/projectUtils");
|
|
5
6
|
const workflow_1 = require("../../project/workflow");
|
|
6
|
-
const updates_1 = require("../utils/updates");
|
|
7
7
|
const UpdatesModule_1 = require("./UpdatesModule");
|
|
8
8
|
const version_1 = require("./version");
|
|
9
9
|
async function syncProjectConfigurationAsync({ projectDir, exp, buildProfile, buildSettings, }) {
|
|
@@ -11,7 +11,7 @@ async function syncProjectConfigurationAsync({ projectDir, exp, buildProfile, bu
|
|
|
11
11
|
const { autoIncrement } = buildProfile;
|
|
12
12
|
const versionBumpStrategy = resolveVersionBumpStrategy(autoIncrement !== null && autoIncrement !== void 0 ? autoIncrement : false);
|
|
13
13
|
if (workflow === eas_build_job_1.Workflow.GENERIC) {
|
|
14
|
-
if ((0,
|
|
14
|
+
if ((0, projectUtils_1.isExpoUpdatesInstalled)(projectDir)) {
|
|
15
15
|
await (0, UpdatesModule_1.syncUpdatesConfigurationAsync)(projectDir, exp);
|
|
16
16
|
}
|
|
17
17
|
await (0, version_1.bumpVersionAsync)({ projectDir, exp, bumpStrategy: versionBumpStrategy, buildSettings });
|
package/build/build/metadata.js
CHANGED
|
@@ -15,7 +15,6 @@ const UpdatesModule_1 = require("./android/UpdatesModule");
|
|
|
15
15
|
const version_1 = require("./android/version");
|
|
16
16
|
const UpdatesModule_2 = require("./ios/UpdatesModule");
|
|
17
17
|
const version_2 = require("./ios/version");
|
|
18
|
-
const updates_1 = require("./utils/updates");
|
|
19
18
|
// TODO(JJ): Replace this with the getRuntimeVersionNullable function in @expo/config-plugins
|
|
20
19
|
function getRuntimeVersionNullable(...[config, platform]) {
|
|
21
20
|
try {
|
|
@@ -78,7 +77,7 @@ function resolveAppIdentifier(ctx) {
|
|
|
78
77
|
}
|
|
79
78
|
}
|
|
80
79
|
async function resolveChannelOrReleaseChannelAsync(ctx) {
|
|
81
|
-
if (!(0,
|
|
80
|
+
if (!(0, projectUtils_1.isExpoUpdatesInstalled)(ctx.projectDir)) {
|
|
82
81
|
return null;
|
|
83
82
|
}
|
|
84
83
|
if (ctx.buildProfile.channel) {
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ensureValidVersions =
|
|
4
|
-
const config_1 = require("@expo/config");
|
|
5
|
-
function isExpoUpdatesInstalled(projectDir) {
|
|
6
|
-
const packageJson = (0, config_1.getPackageJson)(projectDir);
|
|
7
|
-
return !!(packageJson.dependencies && 'expo-updates' in packageJson.dependencies);
|
|
8
|
-
}
|
|
9
|
-
exports.isExpoUpdatesInstalled = isExpoUpdatesInstalled;
|
|
3
|
+
exports.ensureValidVersions = void 0;
|
|
10
4
|
function ensureValidVersions(exp) {
|
|
11
5
|
if (!exp.runtimeVersion && !exp.sdkVersion) {
|
|
12
6
|
throw new Error("Couldn't find either 'runtimeVersion' or 'sdkVersion' to configure 'expo-updates'. Please specify at least one of these properties under the 'expo' key in 'app.json'");
|
|
@@ -9,7 +9,6 @@ const UpdatesModule_1 = require("../../build/android/UpdatesModule");
|
|
|
9
9
|
const syncProjectConfiguration_1 = require("../../build/android/syncProjectConfiguration");
|
|
10
10
|
const configure_1 = require("../../build/configure");
|
|
11
11
|
const UpdatesModule_2 = require("../../build/ios/UpdatesModule");
|
|
12
|
-
const updates_1 = require("../../build/utils/updates");
|
|
13
12
|
const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/EasCommand"));
|
|
14
13
|
const log_1 = (0, tslib_1.__importStar)(require("../../log"));
|
|
15
14
|
const platform_1 = require("../../platform");
|
|
@@ -24,7 +23,7 @@ class BuildConfigure extends EasCommand_1.default {
|
|
|
24
23
|
log_1.default.log('💡 The following process will configure your iOS and/or Android project to be compatible with EAS Build. These changes only apply to your local project files and you can safely revert them at any time.');
|
|
25
24
|
await (0, vcs_1.getVcsClient)().ensureRepoExistsAsync();
|
|
26
25
|
const projectDir = await (0, projectUtils_1.findProjectRootAsync)();
|
|
27
|
-
const expoUpdatesIsInstalled = (0,
|
|
26
|
+
const expoUpdatesIsInstalled = (0, projectUtils_1.isExpoUpdatesInstalled)(projectDir);
|
|
28
27
|
const platform = (_a = flags.platform) !== null && _a !== void 0 ? _a : (await promptForPlatformAsync());
|
|
29
28
|
// clean up old Android configuration
|
|
30
29
|
if ([platform_1.RequestedPlatform.Android, platform_1.RequestedPlatform.All].includes(platform)) {
|
|
@@ -8,6 +8,7 @@ const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
|
|
|
8
8
|
const graphql_tag_1 = (0, tslib_1.__importDefault)(require("graphql-tag"));
|
|
9
9
|
const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/EasCommand"));
|
|
10
10
|
const client_1 = require("../../graphql/client");
|
|
11
|
+
const BranchQuery_1 = require("../../graphql/queries/BranchQuery");
|
|
11
12
|
const log_1 = (0, tslib_1.__importDefault)(require("../../log"));
|
|
12
13
|
const projectUtils_1 = require("../../project/projectUtils");
|
|
13
14
|
const prompts_1 = require("../../prompts");
|
|
@@ -62,15 +63,15 @@ class ChannelCreate extends EasCommand_1.default {
|
|
|
62
63
|
}
|
|
63
64
|
let branchId;
|
|
64
65
|
let branchMessage;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
const existingBranch = await BranchQuery_1.BranchQuery.getBranchByNameAsync({
|
|
67
|
+
appId: projectId,
|
|
68
|
+
name: channelName,
|
|
69
|
+
});
|
|
70
|
+
if (existingBranch) {
|
|
70
71
|
branchId = existingBranch.id;
|
|
71
72
|
branchMessage = `We found a branch with the same name`;
|
|
72
73
|
}
|
|
73
|
-
|
|
74
|
+
else {
|
|
74
75
|
const newBranch = await (0, create_1.createUpdateBranchOnAppAsync)({
|
|
75
76
|
appId: projectId,
|
|
76
77
|
name: channelName,
|
|
@@ -8,6 +8,7 @@ const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
|
|
|
8
8
|
const graphql_tag_1 = (0, tslib_1.__importDefault)(require("graphql-tag"));
|
|
9
9
|
const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/EasCommand"));
|
|
10
10
|
const client_1 = require("../../graphql/client");
|
|
11
|
+
const BranchQuery_1 = require("../../graphql/queries/BranchQuery");
|
|
11
12
|
const log_1 = (0, tslib_1.__importDefault)(require("../../log"));
|
|
12
13
|
const projectUtils_1 = require("../../project/projectUtils");
|
|
13
14
|
const prompts_1 = require("../../prompts");
|
|
@@ -62,42 +63,27 @@ async function updateChannelBranchMappingAsync({ channelId, branchMapping, }) {
|
|
|
62
63
|
exports.updateChannelBranchMappingAsync = updateChannelBranchMappingAsync;
|
|
63
64
|
class ChannelEdit extends EasCommand_1.default {
|
|
64
65
|
async runAsync() {
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
var _a, _b;
|
|
67
|
+
const { args, flags } = await this.parse(ChannelEdit);
|
|
68
|
+
if (flags.json) {
|
|
67
69
|
(0, json_1.enableJsonOutput)();
|
|
68
70
|
}
|
|
69
71
|
const projectDir = await (0, projectUtils_1.findProjectRootAsync)();
|
|
70
72
|
const { exp } = (0, config_1.getConfig)(projectDir, { skipSDKVersionRequirement: true });
|
|
71
73
|
const projectId = await (0, projectUtils_1.getProjectIdAsync)(exp);
|
|
72
|
-
|
|
73
|
-
const validationMessage = 'A channel name is required to edit a specific channel.';
|
|
74
|
-
if (jsonFlag) {
|
|
75
|
-
throw new Error(validationMessage);
|
|
76
|
-
}
|
|
77
|
-
({ name: channelName } = await (0, prompts_1.promptAsync)({
|
|
78
|
-
type: 'text',
|
|
79
|
-
name: 'name',
|
|
80
|
-
message: 'Please enter the name of the channel to edit:',
|
|
81
|
-
validate: value => (value ? true : validationMessage),
|
|
82
|
-
}));
|
|
83
|
-
}
|
|
74
|
+
const channelName = (_a = args.name) !== null && _a !== void 0 ? _a : (await promptForChannelAsync());
|
|
84
75
|
const existingChannel = await getChannelByNameForAppAsync({ appId: projectId, channelName });
|
|
85
76
|
if (existingChannel.updateBranches.length > 1) {
|
|
86
77
|
throw new Error('There is a rollout in progress. Please manage it with "channel:rollout" instead.');
|
|
87
78
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
name: 'name',
|
|
96
|
-
message: (0, chalk_1.default) `What branch should it change to?`,
|
|
97
|
-
validate: value => (value ? true : validationMessage),
|
|
98
|
-
}));
|
|
79
|
+
const branchName = (_b = flags.branch) !== null && _b !== void 0 ? _b : (await promptForBranchAsync());
|
|
80
|
+
const branch = await BranchQuery_1.BranchQuery.getBranchByNameAsync({
|
|
81
|
+
appId: projectId,
|
|
82
|
+
name: branchName,
|
|
83
|
+
});
|
|
84
|
+
if (!branch) {
|
|
85
|
+
throw new Error(`Could not find a branch named "${branchName}". Please check what branches exist on this project with ${chalk_1.default.bold('eas branch:list')}.`);
|
|
99
86
|
}
|
|
100
|
-
const branch = await (0, projectUtils_1.getBranchByNameAsync)({ appId: projectId, name: branchName });
|
|
101
87
|
const channel = await updateChannelBranchMappingAsync({
|
|
102
88
|
channelId: existingChannel.id,
|
|
103
89
|
// todo: move branch mapping logic to utility
|
|
@@ -106,7 +92,7 @@ class ChannelEdit extends EasCommand_1.default {
|
|
|
106
92
|
version: 0,
|
|
107
93
|
}),
|
|
108
94
|
});
|
|
109
|
-
if (
|
|
95
|
+
if (flags.json) {
|
|
110
96
|
(0, json_1.printJsonOnlyOutput)(channel);
|
|
111
97
|
}
|
|
112
98
|
else {
|
|
@@ -130,7 +116,27 @@ ChannelEdit.flags = {
|
|
|
130
116
|
description: 'Name of the branch to point to',
|
|
131
117
|
}),
|
|
132
118
|
json: core_1.Flags.boolean({
|
|
133
|
-
description: '
|
|
119
|
+
description: 'Print output as a JSON object with the channel ID, name and branch mapping',
|
|
134
120
|
default: false,
|
|
135
121
|
}),
|
|
136
122
|
};
|
|
123
|
+
async function promptForChannelAsync() {
|
|
124
|
+
log_1.default.addNewLineIfNone();
|
|
125
|
+
const { name } = await (0, prompts_1.promptAsync)({
|
|
126
|
+
type: 'text',
|
|
127
|
+
name: 'name',
|
|
128
|
+
message: 'Please enter the name of the channel to edit:',
|
|
129
|
+
validate: value => (value ? true : 'The channel name may not be empty.'),
|
|
130
|
+
});
|
|
131
|
+
return name;
|
|
132
|
+
}
|
|
133
|
+
async function promptForBranchAsync() {
|
|
134
|
+
log_1.default.addNewLineIfNone();
|
|
135
|
+
const { name } = await (0, prompts_1.promptAsync)({
|
|
136
|
+
type: 'text',
|
|
137
|
+
name: 'name',
|
|
138
|
+
message: `To which branch should the channel link?`,
|
|
139
|
+
validate: value => (value ? true : 'The branch name may not be empty.'),
|
|
140
|
+
});
|
|
141
|
+
return name;
|
|
142
|
+
}
|
|
@@ -5,6 +5,8 @@ const config_1 = require("@expo/config");
|
|
|
5
5
|
const core_1 = require("@oclif/core");
|
|
6
6
|
const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
|
|
7
7
|
const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/EasCommand"));
|
|
8
|
+
const BranchQuery_1 = require("../../graphql/queries/BranchQuery");
|
|
9
|
+
const ChannelQuery_1 = require("../../graphql/queries/ChannelQuery");
|
|
8
10
|
const log_1 = (0, tslib_1.__importDefault)(require("../../log"));
|
|
9
11
|
const projectUtils_1 = require("../../project/projectUtils");
|
|
10
12
|
const prompts_1 = require("../../prompts");
|
|
@@ -29,33 +31,25 @@ async function promptForRolloutPercentAsync({ promptMessage, }) {
|
|
|
29
31
|
});
|
|
30
32
|
return rolloutPercent;
|
|
31
33
|
}
|
|
32
|
-
function getRolloutInfo(
|
|
33
|
-
|
|
34
|
-
const { branchMapping } = (0, view_1.getBranchMapping)((_b = (_a = getUpdateChannelByNameForAppResult.app) === null || _a === void 0 ? void 0 : _a.byId.updateChannelByName) === null || _b === void 0 ? void 0 : _b.branchMapping);
|
|
34
|
+
function getRolloutInfo(channel) {
|
|
35
|
+
const { branchMapping } = (0, view_1.getBranchMapping)(channel.branchMapping);
|
|
35
36
|
const [newBranchId, oldBranchId] = branchMapping.data.map(d => d.branchId);
|
|
36
|
-
const newBranch =
|
|
37
|
-
const oldBranch =
|
|
37
|
+
const newBranch = channel.updateBranches.filter(branch => branch.id === newBranchId)[0];
|
|
38
|
+
const oldBranch = channel.updateBranches.filter(branch => branch.id === oldBranchId)[0];
|
|
38
39
|
if (!newBranch || !oldBranch) {
|
|
39
|
-
throw new Error(`Branch mapping rollout is missing a branch for channel "${
|
|
40
|
+
throw new Error(`Branch mapping rollout is missing a branch for channel "${channel.name}".`);
|
|
40
41
|
}
|
|
41
42
|
const currentPercent = 100 * branchMapping.data[0].branchMappingLogic.operand;
|
|
42
43
|
return { newBranch, oldBranch, currentPercent };
|
|
43
44
|
}
|
|
44
|
-
async function startRolloutAsync({ channelName, branchName, percent, jsonFlag, projectId, fullName, currentBranchMapping,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
({ name: branchName } = await (0, prompts_1.promptAsync)({
|
|
52
|
-
type: 'text',
|
|
53
|
-
name: 'name',
|
|
54
|
-
message: `Select a branch to rollout onto ${channelName}`,
|
|
55
|
-
validate: value => (value ? true : validationMessage),
|
|
56
|
-
}));
|
|
45
|
+
async function startRolloutAsync({ channelName, branchName, percent, jsonFlag, projectId, fullName, currentBranchMapping, channel, }) {
|
|
46
|
+
const branch = await BranchQuery_1.BranchQuery.getBranchByNameAsync({
|
|
47
|
+
appId: projectId,
|
|
48
|
+
name: branchName,
|
|
49
|
+
});
|
|
50
|
+
if (!branch) {
|
|
51
|
+
throw new Error(`Could not find a branch named "${branchName}". Please check what branches exist on this project with ${chalk_1.default.bold('eas branch:list')}.`);
|
|
57
52
|
}
|
|
58
|
-
const branch = await (0, projectUtils_1.getBranchByNameAsync)({ appId: projectId, name: branchName });
|
|
59
53
|
const oldBranchId = currentBranchMapping.data[0].branchId;
|
|
60
54
|
if (branch.id === oldBranchId) {
|
|
61
55
|
throw new Error(`channel "${channelName}" is already pointing at branch "${branchName}". Rollouts must be done with distinct branches.`);
|
|
@@ -82,19 +76,18 @@ async function startRolloutAsync({ channelName, branchName, percent, jsonFlag, p
|
|
|
82
76
|
],
|
|
83
77
|
};
|
|
84
78
|
const newChannelInfo = await (0, edit_1.updateChannelBranchMappingAsync)({
|
|
85
|
-
channelId:
|
|
79
|
+
channelId: channel.id,
|
|
86
80
|
branchMapping: JSON.stringify(newBranchMapping),
|
|
87
81
|
});
|
|
88
|
-
const oldBranch =
|
|
82
|
+
const oldBranch = channel.updateBranches.filter(branch => branch.id === oldBranchId)[0];
|
|
89
83
|
if (!oldBranch) {
|
|
90
84
|
throw new Error(`Branch mapping is missing its only branch for channel "${channelName}" on app "${fullName}"`);
|
|
91
85
|
}
|
|
92
86
|
const logMessage = `️Started a rollout of branch ${chalk_1.default.bold(branchName)} onto channel ${chalk_1.default.bold(channelName)}! ${chalk_1.default.bold(percent)}% of users will be directed to branch ${chalk_1.default.bold(branchName)}, ${chalk_1.default.bold(100 - percent)}% to branch ${chalk_1.default.bold(oldBranch.name)}.`;
|
|
93
87
|
return { newChannelInfo, logMessage };
|
|
94
88
|
}
|
|
95
|
-
async function editRolloutAsync({ channelName, percent, jsonFlag, currentBranchMapping,
|
|
96
|
-
|
|
97
|
-
const { newBranch, oldBranch, currentPercent } = getRolloutInfo(getUpdateChannelByNameForAppResult);
|
|
89
|
+
async function editRolloutAsync({ channelName, percent, jsonFlag, currentBranchMapping, channel, }) {
|
|
90
|
+
const { newBranch, oldBranch, currentPercent } = getRolloutInfo(channel);
|
|
98
91
|
if (percent == null) {
|
|
99
92
|
if (jsonFlag) {
|
|
100
93
|
throw new Error('A rollout is already in progress. If you wish to modify it you must use specify the new rollout percentage with the --percent flag.');
|
|
@@ -105,19 +98,24 @@ async function editRolloutAsync({ channelName, percent, jsonFlag, currentBranchM
|
|
|
105
98
|
const newBranchMapping = { ...currentBranchMapping };
|
|
106
99
|
newBranchMapping.data[0].branchMappingLogic.operand = percent / 100;
|
|
107
100
|
const newChannelInfo = await (0, edit_1.updateChannelBranchMappingAsync)({
|
|
108
|
-
channelId:
|
|
101
|
+
channelId: channel.id,
|
|
109
102
|
branchMapping: JSON.stringify(newBranchMapping),
|
|
110
103
|
});
|
|
111
104
|
const logMessage = `️Rollout of branch ${chalk_1.default.bold(newBranch.name)} onto channel ${chalk_1.default.bold(channelName)} updated from ${chalk_1.default.bold(currentPercent)}% to ${chalk_1.default.bold(percent)}%. ${chalk_1.default.bold(percent)}% of users will be directed to branch ${chalk_1.default.bold(newBranch.name)}, ${chalk_1.default.bold(100 - percent)}% to branch ${chalk_1.default.bold(oldBranch.name)}.`;
|
|
112
105
|
return { newChannelInfo, logMessage };
|
|
113
106
|
}
|
|
114
|
-
async function endRolloutAsync({ channelName, branchName, jsonFlag, projectId,
|
|
115
|
-
var _a, _b;
|
|
107
|
+
async function endRolloutAsync({ channelName, branchName, jsonFlag, projectId, channel, }) {
|
|
116
108
|
// end rollout
|
|
117
|
-
const { newBranch, oldBranch, currentPercent } = getRolloutInfo(
|
|
109
|
+
const { newBranch, oldBranch, currentPercent } = getRolloutInfo(channel);
|
|
118
110
|
let endOnNewBranch;
|
|
119
111
|
if (branchName) {
|
|
120
|
-
const branch = await
|
|
112
|
+
const branch = await BranchQuery_1.BranchQuery.getBranchByNameAsync({
|
|
113
|
+
appId: projectId,
|
|
114
|
+
name: branchName,
|
|
115
|
+
});
|
|
116
|
+
if (!branch) {
|
|
117
|
+
throw new Error(`Could not find a branch named "${branchName}". Please check what branches exist on this project with ${chalk_1.default.bold('eas branch:list')}.`);
|
|
118
|
+
}
|
|
121
119
|
switch (branch.id) {
|
|
122
120
|
case newBranch.id:
|
|
123
121
|
endOnNewBranch = true;
|
|
@@ -157,7 +155,7 @@ async function endRolloutAsync({ channelName, branchName, jsonFlag, projectId, g
|
|
|
157
155
|
],
|
|
158
156
|
};
|
|
159
157
|
const newChannelInfo = await (0, edit_1.updateChannelBranchMappingAsync)({
|
|
160
|
-
channelId:
|
|
158
|
+
channelId: channel.id,
|
|
161
159
|
branchMapping: JSON.stringify(newBranchMapping),
|
|
162
160
|
});
|
|
163
161
|
const logMessage = `️Rollout on channel ${chalk_1.default.bold(channelName)} ended. All traffic is now sent to branch ${chalk_1.default.bold(endOnNewBranch ? newBranch.name : oldBranch.name)}`;
|
|
@@ -165,7 +163,6 @@ async function endRolloutAsync({ channelName, branchName, jsonFlag, projectId, g
|
|
|
165
163
|
}
|
|
166
164
|
class ChannelRollout extends EasCommand_1.default {
|
|
167
165
|
async runAsync() {
|
|
168
|
-
var _a, _b;
|
|
169
166
|
const { args: { channel: channelName }, flags: { json: jsonFlag, end: endFlag, branch: branchName, percent }, } = await this.parse(ChannelRollout);
|
|
170
167
|
if (jsonFlag) {
|
|
171
168
|
(0, json_1.enableJsonOutput)();
|
|
@@ -174,11 +171,14 @@ class ChannelRollout extends EasCommand_1.default {
|
|
|
174
171
|
const { exp } = (0, config_1.getConfig)(projectDir, { skipSDKVersionRequirement: true });
|
|
175
172
|
const fullName = await (0, projectUtils_1.getProjectFullNameAsync)(exp);
|
|
176
173
|
const projectId = await (0, projectUtils_1.getProjectIdAsync)(exp);
|
|
177
|
-
const
|
|
174
|
+
const channel = await ChannelQuery_1.ChannelQuery.getUpdateChannelByNameForAppAsync({
|
|
178
175
|
appId: projectId,
|
|
179
176
|
channelName: channelName,
|
|
180
177
|
});
|
|
181
|
-
|
|
178
|
+
if (!channel) {
|
|
179
|
+
throw new Error(`Could not find a channel named "${channelName}". Please check what channels exist on this project with ${chalk_1.default.bold('eas channel:list')}.`);
|
|
180
|
+
}
|
|
181
|
+
const { branchMapping: currentBranchMapping, isRollout } = (0, view_1.getBranchMapping)(channel.branchMapping);
|
|
182
182
|
if (currentBranchMapping.data.length === 0) {
|
|
183
183
|
throw new Error('The channel is not pointing at any branches.');
|
|
184
184
|
}
|
|
@@ -200,13 +200,13 @@ class ChannelRollout extends EasCommand_1.default {
|
|
|
200
200
|
if (!isRollout) {
|
|
201
201
|
rolloutMutationResult = await startRolloutAsync({
|
|
202
202
|
channelName,
|
|
203
|
-
branchName,
|
|
203
|
+
branchName: branchName !== null && branchName !== void 0 ? branchName : (await promptForBranchNameAsync(channelName)),
|
|
204
204
|
percent,
|
|
205
205
|
jsonFlag,
|
|
206
206
|
projectId,
|
|
207
207
|
fullName,
|
|
208
208
|
currentBranchMapping,
|
|
209
|
-
|
|
209
|
+
channel,
|
|
210
210
|
});
|
|
211
211
|
}
|
|
212
212
|
else if (endFlag) {
|
|
@@ -215,7 +215,7 @@ class ChannelRollout extends EasCommand_1.default {
|
|
|
215
215
|
branchName,
|
|
216
216
|
jsonFlag,
|
|
217
217
|
projectId,
|
|
218
|
-
|
|
218
|
+
channel,
|
|
219
219
|
});
|
|
220
220
|
}
|
|
221
221
|
else {
|
|
@@ -224,7 +224,7 @@ class ChannelRollout extends EasCommand_1.default {
|
|
|
224
224
|
percent,
|
|
225
225
|
jsonFlag,
|
|
226
226
|
currentBranchMapping,
|
|
227
|
-
|
|
227
|
+
channel,
|
|
228
228
|
});
|
|
229
229
|
}
|
|
230
230
|
if (!rolloutMutationResult) {
|
|
@@ -267,3 +267,12 @@ ChannelRollout.flags = {
|
|
|
267
267
|
default: false,
|
|
268
268
|
}),
|
|
269
269
|
};
|
|
270
|
+
async function promptForBranchNameAsync(channelName) {
|
|
271
|
+
const { name } = await (0, prompts_1.promptAsync)({
|
|
272
|
+
type: 'text',
|
|
273
|
+
name: 'name',
|
|
274
|
+
message: `Select a branch to rollout onto ${channelName}`,
|
|
275
|
+
validate: value => (value ? true : 'A branch must be specified.'),
|
|
276
|
+
});
|
|
277
|
+
return name;
|
|
278
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import EasCommand from '../../commandUtils/EasCommand';
|
|
2
|
-
import { GetChannelByNameForAppQuery, GetChannelByNameForAppQueryVariables } from '../../graphql/generated';
|
|
3
2
|
import { FormatUpdateParameter } from '../../update/utils';
|
|
4
3
|
export declare type BranchMapping = {
|
|
5
4
|
version: number;
|
|
@@ -21,7 +20,6 @@ export declare function getBranchMapping(branchMappingString?: string): {
|
|
|
21
20
|
isRollout: boolean;
|
|
22
21
|
rolloutPercent?: number;
|
|
23
22
|
};
|
|
24
|
-
export declare function getUpdateChannelByNameForAppAsync({ appId, channelName, }: GetChannelByNameForAppQueryVariables): Promise<GetChannelByNameForAppQuery>;
|
|
25
23
|
export declare function logChannelDetails(channel: {
|
|
26
24
|
branchMapping: string;
|
|
27
25
|
updateBranches: {
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.logChannelDetails = exports.
|
|
3
|
+
exports.logChannelDetails = exports.getBranchMapping = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const config_1 = require("@expo/config");
|
|
6
6
|
const core_1 = require("@oclif/core");
|
|
7
7
|
const assert_1 = (0, tslib_1.__importDefault)(require("assert"));
|
|
8
8
|
const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
|
|
9
9
|
const cli_table3_1 = (0, tslib_1.__importDefault)(require("cli-table3"));
|
|
10
|
-
const graphql_tag_1 = (0, tslib_1.__importDefault)(require("graphql-tag"));
|
|
11
10
|
const EasCommand_1 = (0, tslib_1.__importDefault)(require("../../commandUtils/EasCommand"));
|
|
12
|
-
const
|
|
11
|
+
const ChannelQuery_1 = require("../../graphql/queries/ChannelQuery");
|
|
13
12
|
const log_1 = (0, tslib_1.__importDefault)(require("../../log"));
|
|
14
13
|
const projectUtils_1 = require("../../project/projectUtils");
|
|
15
14
|
const prompts_1 = require("../../prompts");
|
|
@@ -65,47 +64,6 @@ function getBranchMapping(branchMappingString) {
|
|
|
65
64
|
return { branchMapping, isRollout, rolloutPercent };
|
|
66
65
|
}
|
|
67
66
|
exports.getBranchMapping = getBranchMapping;
|
|
68
|
-
async function getUpdateChannelByNameForAppAsync({ appId, channelName, }) {
|
|
69
|
-
return await (0, client_1.withErrorHandlingAsync)(client_1.graphqlClient
|
|
70
|
-
.query((0, graphql_tag_1.default) `
|
|
71
|
-
query GetChannelByNameForApp($appId: String!, $channelName: String!) {
|
|
72
|
-
app {
|
|
73
|
-
byId(appId: $appId) {
|
|
74
|
-
id
|
|
75
|
-
updateChannelByName(name: $channelName) {
|
|
76
|
-
id
|
|
77
|
-
name
|
|
78
|
-
createdAt
|
|
79
|
-
branchMapping
|
|
80
|
-
updateBranches(offset: 0, limit: 1000) {
|
|
81
|
-
id
|
|
82
|
-
name
|
|
83
|
-
updates(offset: 0, limit: 10) {
|
|
84
|
-
id
|
|
85
|
-
group
|
|
86
|
-
message
|
|
87
|
-
runtimeVersion
|
|
88
|
-
createdAt
|
|
89
|
-
platform
|
|
90
|
-
actor {
|
|
91
|
-
id
|
|
92
|
-
... on User {
|
|
93
|
-
username
|
|
94
|
-
}
|
|
95
|
-
... on Robot {
|
|
96
|
-
firstName
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
`, { appId, channelName }, { additionalTypenames: ['UpdateChannel', 'UpdateBranch', 'Update'] })
|
|
106
|
-
.toPromise());
|
|
107
|
-
}
|
|
108
|
-
exports.getUpdateChannelByNameForAppAsync = getUpdateChannelByNameForAppAsync;
|
|
109
67
|
function logChannelDetails(channel) {
|
|
110
68
|
var _a, _b, _c;
|
|
111
69
|
const { branchMapping, isRollout, rolloutPercent } = getBranchMapping(channel.branchMapping);
|
|
@@ -146,7 +104,6 @@ function logChannelDetails(channel) {
|
|
|
146
104
|
exports.logChannelDetails = logChannelDetails;
|
|
147
105
|
class ChannelView extends EasCommand_1.default {
|
|
148
106
|
async runAsync() {
|
|
149
|
-
var _a;
|
|
150
107
|
let { args: { name: channelName }, flags: { json: jsonFlag }, } = await this.parse(ChannelView);
|
|
151
108
|
if (jsonFlag) {
|
|
152
109
|
(0, json_1.enableJsonOutput)();
|
|
@@ -166,11 +123,10 @@ class ChannelView extends EasCommand_1.default {
|
|
|
166
123
|
validate: value => (value ? true : validationMessage),
|
|
167
124
|
}));
|
|
168
125
|
}
|
|
169
|
-
const
|
|
126
|
+
const channel = await ChannelQuery_1.ChannelQuery.getUpdateChannelByNameForAppAsync({
|
|
170
127
|
appId: projectId,
|
|
171
128
|
channelName,
|
|
172
129
|
});
|
|
173
|
-
const channel = (_a = getUpdateChannelByNameForAppresult.app) === null || _a === void 0 ? void 0 : _a.byId.updateChannelByName;
|
|
174
130
|
if (!channel) {
|
|
175
131
|
throw new Error(`Could not find a channel with name: ${channelName}`);
|
|
176
132
|
}
|
|
@@ -32,8 +32,8 @@ class UpdateDelete extends EasCommand_1.default {
|
|
|
32
32
|
const shouldAbort = await (0, prompts_1.confirmAsync)({
|
|
33
33
|
message: `🚨${chalk_1.default.red('CAUTION')}🚨\n\n` +
|
|
34
34
|
`${chalk_1.default.yellow(`This will delete all of the updates in group "${group}".`)} ${chalk_1.default.red('This is a permanent operation.')}\n\n` +
|
|
35
|
-
`If you want to revert to a previous publish, you should use '
|
|
36
|
-
`An update group should only be deleted in an emergency like an accidental publish of a secret. In this case user '
|
|
35
|
+
`If you want to revert to a previous publish, you should use 'update --republish' targeted at the last working update group instead.\n\n` +
|
|
36
|
+
`An update group should only be deleted in an emergency like an accidental publish of a secret. In this case user 'update --republish' to revert to the last working update group first and then proceed with the deletion. Deleting an update group when it is the latest publish can lead to inconsistent cacheing behavior by clients.\n\n` +
|
|
37
37
|
`Would you like to abort?`,
|
|
38
38
|
});
|
|
39
39
|
if (shouldAbort) {
|
|
@@ -98,6 +98,20 @@ class UpdatePublish extends EasCommand_1.default {
|
|
|
98
98
|
skipSDKVersionRequirement: true,
|
|
99
99
|
isPublicConfig: true,
|
|
100
100
|
});
|
|
101
|
+
if (!(0, projectUtils_1.isExpoUpdatesInstalledOrAvailable)(projectDir, exp.sdkVersion)) {
|
|
102
|
+
const install = await (0, prompts_1.confirmAsync)({
|
|
103
|
+
message: `You are creating an update which requires ${chalk_1.default.bold('expo-updates')} to be installed in your app.\n Do you want EAS CLI to install it for you?`,
|
|
104
|
+
instructions: 'The command will abort unless you agree.',
|
|
105
|
+
});
|
|
106
|
+
if (install) {
|
|
107
|
+
await (0, projectUtils_1.installExpoUpdatesAsync)(projectDir, { nonInteractive: false });
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
core_1.Errors.error(`Install ${chalk_1.default.bold('expo-updates')} manually and come back later.`, {
|
|
111
|
+
exit: 1,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
101
115
|
const runtimeVersions = await getRuntimeVersionObjectAsync(exp, platformFlag, projectDir);
|
|
102
116
|
const projectId = await (0, projectUtils_1.getProjectIdAsync)(exp);
|
|
103
117
|
await checkEASUpdateURLIsSetAsync(exp);
|
|
@@ -6041,6 +6041,25 @@ export declare type DeleteWebhookMutation = {
|
|
|
6041
6041
|
};
|
|
6042
6042
|
};
|
|
6043
6043
|
};
|
|
6044
|
+
export declare type ViewBranchQueryVariables = Exact<{
|
|
6045
|
+
appId: Scalars['String'];
|
|
6046
|
+
name: Scalars['String'];
|
|
6047
|
+
}>;
|
|
6048
|
+
export declare type ViewBranchQuery = {
|
|
6049
|
+
__typename?: 'RootQuery';
|
|
6050
|
+
app: {
|
|
6051
|
+
__typename?: 'AppQuery';
|
|
6052
|
+
byId: {
|
|
6053
|
+
__typename?: 'App';
|
|
6054
|
+
id: string;
|
|
6055
|
+
updateBranchByName?: {
|
|
6056
|
+
__typename?: 'UpdateBranch';
|
|
6057
|
+
id: string;
|
|
6058
|
+
name: string;
|
|
6059
|
+
} | null | undefined;
|
|
6060
|
+
};
|
|
6061
|
+
};
|
|
6062
|
+
};
|
|
6044
6063
|
export declare type BuildsByIdQueryVariables = Exact<{
|
|
6045
6064
|
buildId: Scalars['ID'];
|
|
6046
6065
|
}>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BranchQuery = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const graphql_tag_1 = (0, tslib_1.__importDefault)(require("graphql-tag"));
|
|
6
|
+
const client_1 = require("../client");
|
|
7
|
+
exports.BranchQuery = {
|
|
8
|
+
async getBranchByNameAsync({ appId, name, }) {
|
|
9
|
+
const { app: { byId: { updateBranchByName: branch }, }, } = await (0, client_1.withErrorHandlingAsync)(client_1.graphqlClient
|
|
10
|
+
.query((0, graphql_tag_1.default) `
|
|
11
|
+
query ViewBranch($appId: String!, $name: String!) {
|
|
12
|
+
app {
|
|
13
|
+
byId(appId: $appId) {
|
|
14
|
+
id
|
|
15
|
+
updateBranchByName(name: $name) {
|
|
16
|
+
id
|
|
17
|
+
name
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
`, {
|
|
23
|
+
appId,
|
|
24
|
+
name,
|
|
25
|
+
}, { additionalTypenames: ['UpdateBranch'] })
|
|
26
|
+
.toPromise());
|
|
27
|
+
return branch;
|
|
28
|
+
},
|
|
29
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { GetChannelByNameForAppQuery, GetChannelByNameForAppQueryVariables } from '../generated';
|
|
2
|
+
export declare const ChannelQuery: {
|
|
3
|
+
getUpdateChannelByNameForAppAsync({ appId, channelName, }: GetChannelByNameForAppQueryVariables): Promise<GetChannelByNameForAppQuery['app']['byId']['updateChannelByName']>;
|
|
4
|
+
};
|