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.
@@ -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, updates_1.isExpoUpdatesInstalled)(projectDir)) {
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, updates_1.isExpoUpdatesInstalled)(projectDir)) {
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 });
@@ -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, updates_1.isExpoUpdatesInstalled)(ctx.projectDir)) {
80
+ if (!(0, projectUtils_1.isExpoUpdatesInstalled)(ctx.projectDir)) {
82
81
  return null;
83
82
  }
84
83
  if (ctx.buildProfile.channel) {
@@ -1,3 +1,2 @@
1
1
  import { ExpoConfig } from '@expo/config';
2
- export declare function isExpoUpdatesInstalled(projectDir: string): boolean;
3
2
  export declare function ensureValidVersions(exp: ExpoConfig): void;
@@ -1,12 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ensureValidVersions = exports.isExpoUpdatesInstalled = void 0;
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, updates_1.isExpoUpdatesInstalled)(projectDir);
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
- try {
66
- const existingBranch = await (0, projectUtils_1.getBranchByNameAsync)({
67
- appId: projectId,
68
- name: channelName,
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
- catch (e) {
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
- let { args: { name: channelName }, flags: { branch: branchName, json: jsonFlag }, } = await this.parse(ChannelEdit);
66
- if (jsonFlag) {
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
- if (!channelName) {
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
- if (!branchName) {
89
- const validationMessage = 'branch name may not be empty.';
90
- if (jsonFlag) {
91
- throw new Error(validationMessage);
92
- }
93
- ({ name: branchName } = await (0, prompts_1.promptAsync)({
94
- type: 'text',
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 (jsonFlag) {
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: 'print output as a JSON object with the channel ID, name and branch mapping.',
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(getUpdateChannelByNameForAppResult) {
33
- var _a, _b, _c, _d, _e, _f, _g, _h;
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 = (_d = (_c = getUpdateChannelByNameForAppResult.app) === null || _c === void 0 ? void 0 : _c.byId.updateChannelByName) === null || _d === void 0 ? void 0 : _d.updateBranches.filter(branch => branch.id === newBranchId)[0];
37
- const oldBranch = (_f = (_e = getUpdateChannelByNameForAppResult.app) === null || _e === void 0 ? void 0 : _e.byId.updateChannelByName) === null || _f === void 0 ? void 0 : _f.updateBranches.filter(branch => branch.id === oldBranchId)[0];
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 "${(_h = (_g = getUpdateChannelByNameForAppResult.app) === null || _g === void 0 ? void 0 : _g.byId.updateChannelByName) === null || _h === void 0 ? void 0 : _h.name}".`);
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, getUpdateChannelByNameForAppResult, }) {
45
- var _a, _b, _c, _d;
46
- if (!branchName) {
47
- const validationMessage = 'A branch must be specified.';
48
- if (jsonFlag) {
49
- throw new Error(validationMessage);
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: (_b = (_a = getUpdateChannelByNameForAppResult.app) === null || _a === void 0 ? void 0 : _a.byId.updateChannelByName) === null || _b === void 0 ? void 0 : _b.id,
79
+ channelId: channel.id,
86
80
  branchMapping: JSON.stringify(newBranchMapping),
87
81
  });
88
- const oldBranch = (_d = (_c = getUpdateChannelByNameForAppResult.app) === null || _c === void 0 ? void 0 : _c.byId.updateChannelByName) === null || _d === void 0 ? void 0 : _d.updateBranches.filter(branch => branch.id === oldBranchId)[0];
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, getUpdateChannelByNameForAppResult, }) {
96
- var _a, _b;
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: (_b = (_a = getUpdateChannelByNameForAppResult.app) === null || _a === void 0 ? void 0 : _a.byId.updateChannelByName) === null || _b === void 0 ? void 0 : _b.id,
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, getUpdateChannelByNameForAppResult, }) {
115
- var _a, _b;
107
+ async function endRolloutAsync({ channelName, branchName, jsonFlag, projectId, channel, }) {
116
108
  // end rollout
117
- const { newBranch, oldBranch, currentPercent } = getRolloutInfo(getUpdateChannelByNameForAppResult);
109
+ const { newBranch, oldBranch, currentPercent } = getRolloutInfo(channel);
118
110
  let endOnNewBranch;
119
111
  if (branchName) {
120
- const branch = await (0, projectUtils_1.getBranchByNameAsync)({ appId: projectId, name: branchName });
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: (_b = (_a = getUpdateChannelByNameForAppResult.app) === null || _a === void 0 ? void 0 : _a.byId.updateChannelByName) === null || _b === void 0 ? void 0 : _b.id,
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 getUpdateChannelByNameForAppResult = await (0, view_1.getUpdateChannelByNameForAppAsync)({
174
+ const channel = await ChannelQuery_1.ChannelQuery.getUpdateChannelByNameForAppAsync({
178
175
  appId: projectId,
179
176
  channelName: channelName,
180
177
  });
181
- const { branchMapping: currentBranchMapping, isRollout } = (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);
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
- getUpdateChannelByNameForAppResult,
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
- getUpdateChannelByNameForAppResult,
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
- getUpdateChannelByNameForAppResult,
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.getUpdateChannelByNameForAppAsync = exports.getBranchMapping = void 0;
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 client_1 = require("../../graphql/client");
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 getUpdateChannelByNameForAppresult = await getUpdateChannelByNameForAppAsync({
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 'branch:publish --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 'branch:publish --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` +
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,7 @@
1
+ import { ViewBranchQuery } from '../generated';
2
+ export declare const BranchQuery: {
3
+ getBranchByNameAsync({ appId, name, }: {
4
+ appId: string;
5
+ name: string;
6
+ }): Promise<ViewBranchQuery['app']['byId']['updateBranchByName']>;
7
+ };
@@ -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
+ };