eas-cli 3.8.1 → 3.9.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.
Files changed (40) hide show
  1. package/README.md +79 -54
  2. package/build/build/build.js +1 -1
  3. package/build/build/runBuildAndSubmit.js +1 -1
  4. package/build/commandUtils/context/DynamicProjectConfigContextField.js +1 -1
  5. package/build/commandUtils/context/contextUtils/findProjectDirAndVerifyProjectSetupAsync.js +1 -1
  6. package/build/commands/build/index.js +1 -1
  7. package/build/commands/build/internal.js +3 -0
  8. package/build/commands/build/resign.js +1 -1
  9. package/build/commands/build/version/set.js +1 -1
  10. package/build/commands/build/version/sync.js +1 -1
  11. package/build/commands/channel/rollout.d.ts +0 -2
  12. package/build/commands/channel/rollout.js +44 -18
  13. package/build/commands/config.js +1 -1
  14. package/build/commands/metadata/lint.js +1 -1
  15. package/build/commands/metadata/pull.js +1 -1
  16. package/build/commands/metadata/push.js +1 -1
  17. package/build/commands/submit.js +1 -1
  18. package/build/commands/update/index.d.ts +0 -2
  19. package/build/commands/update/index.js +31 -136
  20. package/build/commands/update/republish.js +1 -1
  21. package/build/commands/update/roll-back-to-embedded.d.ts +22 -0
  22. package/build/commands/update/roll-back-to-embedded.js +253 -0
  23. package/build/credentials/ios/IosCredentialsProvider.js +1 -1
  24. package/build/credentials/manager/SelectBuildProfileFromEasJson.js +1 -1
  25. package/build/graphql/generated.d.ts +139 -22
  26. package/build/graphql/generated.js +0 -2
  27. package/build/graphql/types/Update.js +1 -0
  28. package/build/project/customBuildConfig.js +19 -4
  29. package/build/project/publish.d.ts +31 -0
  30. package/build/project/publish.js +147 -2
  31. package/build/update/configure.js +1 -1
  32. package/build/update/utils.d.ts +2 -0
  33. package/build/update/utils.js +30 -13
  34. package/build/utils/code-signing.d.ts +4 -3
  35. package/build/utils/code-signing.js +23 -5
  36. package/build/utils/expoCli.js +3 -2
  37. package/build/utils/expodash/areSetsEqual.d.ts +1 -0
  38. package/build/utils/expodash/areSetsEqual.js +6 -0
  39. package/oclif.manifest.json +1 -1
  40. package/package.json +4 -3
@@ -4,6 +4,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const tslib_1 = require("tslib");
5
5
  const core_1 = require("@oclif/core");
6
6
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
7
+ const queries_1 = require("../../branch/queries");
8
+ const queries_2 = require("../../channel/queries");
7
9
  const utils_1 = require("../../channel/utils");
8
10
  const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
9
11
  const flags_1 = require("../../commandUtils/flags");
@@ -81,7 +83,7 @@ async function startRolloutAsync(graphqlClient, { channelName, branchName, perce
81
83
  if (!oldBranch) {
82
84
  throw new Error(`Branch mapping is missing its only branch for channel "${channelName}" on app "${displayName}"`);
83
85
  }
84
- 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)}.`;
86
+ const logMessage = `Started a rollout of branch ${chalk_1.default.bold(branchName)} on 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)}.`;
85
87
  return { newChannelInfo, logMessage };
86
88
  }
87
89
  async function editRolloutAsync(graphqlClient, { channelName, percent, nonInteractive, currentBranchMapping, channel, }) {
@@ -99,7 +101,7 @@ async function editRolloutAsync(graphqlClient, { channelName, percent, nonIntera
99
101
  channelId: channel.id,
100
102
  branchMapping: JSON.stringify(newBranchMapping),
101
103
  });
102
- 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)}.`;
104
+ const logMessage = `Rollout of branch ${chalk_1.default.bold(newBranch.name)} on 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)}.`;
103
105
  return { newChannelInfo, logMessage };
104
106
  }
105
107
  async function endRolloutAsync(graphqlClient, { channelName, branchName, nonInteractive, projectId, channel, }) {
@@ -153,12 +155,12 @@ async function endRolloutAsync(graphqlClient, { channelName, branchName, nonInte
153
155
  channelId: channel.id,
154
156
  branchMapping: JSON.stringify(newBranchMapping),
155
157
  });
156
- 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)}`;
158
+ 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)}`;
157
159
  return { newChannelInfo, logMessage };
158
160
  }
159
161
  class ChannelRollout extends EasCommand_1.default {
160
162
  async runAsync() {
161
- const { args: { channel: channelName }, flags: { json: jsonFlag, end: endFlag, branch: branchName, percent, 'non-interactive': nonInteractive, }, } = await this.parse(ChannelRollout);
163
+ const { args: { channel: channelNameArg }, flags: { json: jsonFlag, end: endFlag, branch: branchName, percent, 'non-interactive': nonInteractive, }, } = await this.parse(ChannelRollout);
162
164
  const { projectConfig: { projectId }, loggedIn: { graphqlClient }, } = await this.getContextAsync(ChannelRollout, {
163
165
  nonInteractive,
164
166
  });
@@ -166,9 +168,22 @@ class ChannelRollout extends EasCommand_1.default {
166
168
  (0, json_1.enableJsonOutput)();
167
169
  }
168
170
  const projectDisplayName = await (0, projectUtils_1.getDisplayNameForProjectIdAsync)(graphqlClient, projectId);
171
+ let channelName = channelNameArg;
172
+ if (!channelName) {
173
+ const { name } = await (0, queries_2.selectChannelOnAppAsync)(graphqlClient, {
174
+ projectId,
175
+ selectionPromptTitle: 'Select a channel on which to perform a rollout',
176
+ paginatedQueryOptions: {
177
+ json: jsonFlag,
178
+ nonInteractive,
179
+ offset: 0,
180
+ },
181
+ });
182
+ channelName = name;
183
+ }
169
184
  const channel = await ChannelQuery_1.ChannelQuery.viewUpdateChannelAsync(graphqlClient, {
170
185
  appId: projectId,
171
- channelName: channelName,
186
+ channelName,
172
187
  });
173
188
  if (!channel) {
174
189
  throw new Error(`Could not find a channel named "${channelName}". Check which channels exist on this project with ${chalk_1.default.bold('eas channel:list')}.`);
@@ -195,7 +210,13 @@ class ChannelRollout extends EasCommand_1.default {
195
210
  if (!isRollout) {
196
211
  rolloutMutationResult = await startRolloutAsync(graphqlClient, {
197
212
  channelName,
198
- branchName: branchName !== null && branchName !== void 0 ? branchName : (await promptForBranchNameAsync(channelName, nonInteractive)),
213
+ branchName: branchName !== null && branchName !== void 0 ? branchName : (await promptForBranchNameAsync({
214
+ graphqlClient,
215
+ projectId,
216
+ channelName,
217
+ nonInteractive,
218
+ json: jsonFlag,
219
+ })),
199
220
  percent,
200
221
  nonInteractive,
201
222
  projectId,
@@ -236,13 +257,11 @@ class ChannelRollout extends EasCommand_1.default {
236
257
  }
237
258
  exports.default = ChannelRollout;
238
259
  _a = ChannelRollout;
239
- ChannelRollout.hidden = true;
240
- ChannelRollout.description = 'Rollout a new branch out to a channel incrementally.';
260
+ ChannelRollout.description = 'Roll a new branch out on a channel incrementally.';
241
261
  ChannelRollout.args = [
242
262
  {
243
263
  name: 'channel',
244
- required: true,
245
- description: 'rollout that the channel is on',
264
+ description: 'channel on which the rollout should be done',
246
265
  },
247
266
  ];
248
267
  ChannelRollout.flags = {
@@ -251,7 +270,7 @@ ChannelRollout.flags = {
251
270
  required: false,
252
271
  }),
253
272
  percent: core_1.Flags.integer({
254
- description: 'percent of traffic to redirect to the new branch',
273
+ description: 'percent of users to send to the new branch',
255
274
  required: false,
256
275
  }),
257
276
  end: core_1.Flags.boolean({
@@ -264,15 +283,22 @@ ChannelRollout.contextDefinition = {
264
283
  ..._a.ContextOptions.ProjectConfig,
265
284
  ..._a.ContextOptions.LoggedIn,
266
285
  };
267
- async function promptForBranchNameAsync(channelName, nonInteractive) {
286
+ async function promptForBranchNameAsync({ graphqlClient, projectId, channelName, nonInteractive, json, }) {
268
287
  if (nonInteractive) {
269
288
  throw new Error('Must supply branch flag in non-interactive mode');
270
289
  }
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.'),
290
+ const { name: branchName } = await (0, queries_1.selectBranchOnAppAsync)(graphqlClient, {
291
+ projectId,
292
+ promptTitle: `Which branch would you like roll out on ${channelName}?`,
293
+ displayTextForListItem: updateBranch => ({
294
+ title: updateBranch.name,
295
+ }),
296
+ // discard limit and offset because this query is not their intended target
297
+ paginatedQueryOptions: {
298
+ json,
299
+ nonInteractive,
300
+ offset: 0,
301
+ },
276
302
  });
277
- return name;
303
+ return branchName;
278
304
  }
@@ -24,7 +24,7 @@ class Config extends EasCommand_1.default {
24
24
  const { getDynamicProjectConfigAsync, projectDir } = await this.getContextAsync(Config, {
25
25
  nonInteractive: false,
26
26
  });
27
- const accessor = new eas_json_1.EasJsonAccessor(projectDir);
27
+ const accessor = eas_json_1.EasJsonAccessor.fromProjectPath(projectDir);
28
28
  const profileName = maybeProfile !== null && maybeProfile !== void 0 ? maybeProfile : (await (0, prompts_1.selectAsync)('Select build profile', (await eas_json_1.EasJsonUtils.getBuildProfileNamesAsync(accessor)).map(profileName => ({
29
29
  title: profileName,
30
30
  value: profileName,
@@ -25,7 +25,7 @@ class MetadataLint extends EasCommand_1.default {
25
25
  }
26
26
  const submitProfiles = await (0, profiles_1.getProfilesAsync)({
27
27
  type: 'submit',
28
- easJsonAccessor: new eas_json_1.EasJsonAccessor(projectDir),
28
+ easJsonAccessor: eas_json_1.EasJsonAccessor.fromProjectPath(projectDir),
29
29
  platforms: [eas_build_job_1.Platform.IOS],
30
30
  profileName: flags.profile,
31
31
  });
@@ -25,7 +25,7 @@ class MetadataPull extends EasCommand_1.default {
25
25
  await (0, configure_1.ensureProjectConfiguredAsync)({ projectDir, nonInteractive: false });
26
26
  const submitProfiles = await (0, profiles_1.getProfilesAsync)({
27
27
  type: 'submit',
28
- easJsonAccessor: new eas_json_1.EasJsonAccessor(projectDir),
28
+ easJsonAccessor: eas_json_1.EasJsonAccessor.fromProjectPath(projectDir),
29
29
  platforms: [eas_build_job_1.Platform.IOS],
30
30
  profileName: flags.profile,
31
31
  });
@@ -23,7 +23,7 @@ class MetadataPush extends EasCommand_1.default {
23
23
  await (0, configure_1.ensureProjectConfiguredAsync)({ projectDir, nonInteractive: false });
24
24
  const submitProfiles = await (0, profiles_1.getProfilesAsync)({
25
25
  type: 'submit',
26
- easJsonAccessor: new eas_json_1.EasJsonAccessor(projectDir),
26
+ easJsonAccessor: eas_json_1.EasJsonAccessor.fromProjectPath(projectDir),
27
27
  platforms: [eas_build_job_1.Platform.IOS],
28
28
  profileName: flags.profile,
29
29
  });
@@ -27,7 +27,7 @@ class Submit extends EasCommand_1.default {
27
27
  const platforms = (0, platform_1.toPlatforms)(flagsWithPlatform.requestedPlatform);
28
28
  const submissionProfiles = await (0, profiles_1.getProfilesAsync)({
29
29
  type: 'submit',
30
- easJsonAccessor: new eas_json_1.EasJsonAccessor(projectDir),
30
+ easJsonAccessor: eas_json_1.EasJsonAccessor.fromProjectPath(projectDir),
31
31
  platforms,
32
32
  profileName: flagsWithPlatform.profile,
33
33
  });
@@ -1,6 +1,4 @@
1
- import { Platform as PublishPlatform } from '@expo/config';
2
1
  import EasCommand from '../../commandUtils/EasCommand';
3
- export declare const defaultPublishPlatforms: Partial<PublishPlatform>[];
4
2
  export default class UpdatePublish extends EasCommand {
5
3
  static description: string;
6
4
  static flags: {
@@ -1,16 +1,11 @@
1
1
  "use strict";
2
2
  var _a;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.defaultPublishPlatforms = void 0;
5
4
  const tslib_1 = require("tslib");
6
- const config_plugins_1 = require("@expo/config-plugins");
7
- const eas_build_job_1 = require("@expo/eas-build-job");
8
5
  const core_1 = require("@oclif/core");
9
- const assert_1 = tslib_1.__importDefault(require("assert"));
10
6
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
11
7
  const nullthrows_1 = tslib_1.__importDefault(require("nullthrows"));
12
8
  const queries_1 = require("../../branch/queries");
13
- const utils_1 = require("../../branch/utils");
14
9
  const url_1 = require("../../build/utils/url");
15
10
  const queries_2 = require("../../channel/queries");
16
11
  const EasCommand_1 = tslib_1.__importDefault(require("../../commandUtils/EasCommand"));
@@ -21,42 +16,21 @@ const generated_1 = require("../../graphql/generated");
21
16
  const PublishMutation_1 = require("../../graphql/mutations/PublishMutation");
22
17
  const log_1 = tslib_1.__importStar(require("../../log"));
23
18
  const ora_1 = require("../../ora");
24
- const platform_1 = require("../../platform");
25
19
  const projectUtils_1 = require("../../project/projectUtils");
26
20
  const publish_1 = require("../../project/publish");
27
- const workflow_1 = require("../../project/workflow");
28
- const prompts_1 = require("../../prompts");
29
21
  const configure_1 = require("../../update/configure");
30
- const getBranchNameFromChannelNameAsync_1 = require("../../update/getBranchNameFromChannelNameAsync");
31
- const utils_2 = require("../../update/utils");
22
+ const utils_1 = require("../../update/utils");
32
23
  const code_signing_1 = require("../../utils/code-signing");
33
24
  const uniqBy_1 = tslib_1.__importDefault(require("../../utils/expodash/uniqBy"));
34
25
  const formatFields_1 = tslib_1.__importDefault(require("../../utils/formatFields"));
35
26
  const json_1 = require("../../utils/json");
36
27
  const statuspageService_1 = require("../../utils/statuspageService");
37
28
  const vcs_1 = require("../../vcs");
38
- exports.defaultPublishPlatforms = ['android', 'ios'];
39
- function getRequestedPlatform(platform) {
40
- switch (platform) {
41
- case 'android':
42
- return platform_1.RequestedPlatform.Android;
43
- case 'ios':
44
- return platform_1.RequestedPlatform.Ios;
45
- case 'web':
46
- return null;
47
- case 'all':
48
- return platform_1.RequestedPlatform.All;
49
- default:
50
- throw new Error(`Unsupported platform: ${platform}`);
51
- }
52
- }
53
29
  class UpdatePublish extends EasCommand_1.default {
54
30
  async runAsync() {
55
- var _b, _c;
56
31
  const { flags: rawFlags } = await this.parse(UpdatePublish);
57
32
  const paginatedQueryOptions = (0, pagination_1.getPaginatedQueryOptions)(rawFlags);
58
- let { auto: autoFlag, platform: platformFlag, channelName, updateMessage, inputDir, skipBundler, privateKeyPath, json: jsonFlag, nonInteractive, } = this.sanitizeFlags(rawFlags);
59
- let branchName = this.sanitizeFlags(rawFlags).branchName;
33
+ const { auto: autoFlag, platform: platformFlag, channelName: channelNameArg, updateMessage: updateMessageArg, inputDir, skipBundler, privateKeyPath, json: jsonFlag, nonInteractive, branchName: branchNameArg, } = this.sanitizeFlags(rawFlags);
60
34
  const { getDynamicProjectConfigAsync, loggedIn: { graphqlClient }, } = await this.getContextAsync(UpdatePublish, {
61
35
  nonInteractive,
62
36
  });
@@ -66,76 +40,33 @@ class UpdatePublish extends EasCommand_1.default {
66
40
  const { exp: expPossiblyWithoutEasUpdateConfigured, projectId, projectDir, } = await getDynamicProjectConfigAsync({
67
41
  isPublicConfig: true,
68
42
  });
69
- const { exp: expPrivate } = await getDynamicProjectConfigAsync({
70
- isPublicConfig: false,
71
- });
72
43
  await (0, statuspageService_1.maybeWarnAboutEasOutagesAsync)(graphqlClient, [generated_1.StatuspageServiceName.EasUpdate]);
73
44
  await (0, configure_1.ensureEASUpdateIsConfiguredAsync)(graphqlClient, {
74
45
  exp: expPossiblyWithoutEasUpdateConfigured,
75
- platform: getRequestedPlatform(platformFlag),
46
+ platform: (0, publish_1.getRequestedPlatform)(platformFlag),
76
47
  projectDir,
77
48
  projectId,
78
49
  });
79
50
  const { exp } = await getDynamicProjectConfigAsync({ isPublicConfig: true });
51
+ const { exp: expPrivate } = await getDynamicProjectConfigAsync({
52
+ isPublicConfig: false,
53
+ });
80
54
  const codeSigningInfo = await (0, code_signing_1.getCodeSigningInfoAsync)(expPrivate, privateKeyPath);
81
- let realizedPlatforms = [];
82
- if (channelName && branchName) {
83
- throw new Error('Cannot specify both --channel and --branch. Specify either --channel, --branch, or --auto');
84
- }
85
- if (channelName) {
86
- branchName = await (0, getBranchNameFromChannelNameAsync_1.getBranchNameFromChannelNameAsync)(graphqlClient, projectId, channelName);
87
- }
88
- if (!branchName) {
89
- if (autoFlag) {
90
- branchName = await (0, utils_1.getDefaultBranchNameAsync)();
91
- }
92
- else if (nonInteractive) {
93
- throw new Error('Must supply --channel, --branch or --auto when in non-interactive mode');
94
- }
95
- else {
96
- try {
97
- const branch = await (0, queries_1.selectBranchOnAppAsync)(graphqlClient, {
98
- projectId,
99
- promptTitle: `Which branch would you like to publish on?`,
100
- displayTextForListItem: updateBranch => ({
101
- title: `${updateBranch.name} ${chalk_1.default.grey(`- current update: ${(0, utils_2.formatUpdateMessage)(updateBranch.updates[0])}`)}`,
102
- }),
103
- paginatedQueryOptions,
104
- });
105
- branchName = branch.name;
106
- }
107
- catch {
108
- // unable to select a branch (network error or no branches for project)
109
- ({ name: branchName } = await (0, prompts_1.promptAsync)({
110
- type: 'text',
111
- name: 'name',
112
- message: 'No branches found. Provide a branch name:',
113
- initial: await (0, utils_1.getDefaultBranchNameAsync)(),
114
- validate: value => (value ? true : 'Branch name may not be empty.'),
115
- }));
116
- }
117
- (0, assert_1.default)(branchName, 'Branch name must be specified.');
118
- }
119
- }
120
- if (!updateMessage && autoFlag) {
121
- updateMessage = (_b = (await (0, vcs_1.getVcsClient)().getLastCommitMessageAsync())) === null || _b === void 0 ? void 0 : _b.trim();
122
- }
123
- if (!updateMessage) {
124
- if (nonInteractive) {
125
- throw new Error('Must supply --message or use --auto when in non-interactive mode');
126
- }
127
- const validationMessage = 'publish message may not be empty.';
128
- if (jsonFlag) {
129
- throw new Error(validationMessage);
130
- }
131
- ({ updateMessage } = await (0, prompts_1.promptAsync)({
132
- type: 'text',
133
- name: 'updateMessage',
134
- message: `Provide an update message.`,
135
- initial: (_c = (await (0, vcs_1.getVcsClient)().getLastCommitMessageAsync())) === null || _c === void 0 ? void 0 : _c.trim(),
136
- validate: (value) => (value ? true : validationMessage),
137
- }));
138
- }
55
+ const branchName = await (0, publish_1.getBranchNameForCommandAsync)({
56
+ graphqlClient,
57
+ projectId,
58
+ channelNameArg,
59
+ branchNameArg,
60
+ autoFlag,
61
+ nonInteractive,
62
+ paginatedQueryOptions,
63
+ });
64
+ const updateMessage = await (0, publish_1.getUpdateMessageForCommandAsync)({
65
+ updateMessageArg,
66
+ autoFlag,
67
+ nonInteractive,
68
+ jsonFlag,
69
+ });
139
70
  // build bundle and upload assets for a new publish
140
71
  if (!skipBundler) {
141
72
  const bundleSpinner = (0, ora_1.ora)().start('Exporting...');
@@ -154,6 +85,7 @@ class UpdatePublish extends EasCommand_1.default {
154
85
  let unsortedUpdateInfoGroups = {};
155
86
  let uploadedAssetCount = 0;
156
87
  let assetLimitPerUpdateGroup = 0;
88
+ let realizedPlatforms = [];
157
89
  try {
158
90
  const collectedAssets = await (0, publish_1.collectAssetsAsync)(distRoot);
159
91
  const assets = (0, publish_1.filterExportedPlatformsByFlag)(collectedAssets, platformFlag);
@@ -190,20 +122,8 @@ class UpdatePublish extends EasCommand_1.default {
190
122
  assetSpinner.fail('Failed to upload');
191
123
  throw e;
192
124
  }
193
- const truncatedMessage = (0, utils_2.truncateString)(updateMessage, 1024);
194
- if (truncatedMessage !== updateMessage) {
195
- log_1.default.warn('Update message exceeds the allowed 1024 character limit. Truncating message...');
196
- }
197
- const runtimeVersions = await getRuntimeVersionObjectAsync(exp, realizedPlatforms, projectDir);
198
- const runtimeToPlatformMapping = [];
199
- for (const runtime of runtimeVersions) {
200
- const platforms = runtimeVersions
201
- .filter(({ runtimeVersion }) => runtimeVersion === runtime.runtimeVersion)
202
- .map(({ platform }) => platform);
203
- if (!runtimeToPlatformMapping.find(item => item.runtimeVersion === runtime.runtimeVersion)) {
204
- runtimeToPlatformMapping.push({ runtimeVersion: runtime.runtimeVersion, platforms });
205
- }
206
- }
125
+ const runtimeVersions = await (0, publish_1.getRuntimeVersionObjectAsync)(exp, realizedPlatforms, projectDir);
126
+ const runtimeToPlatformMapping = (0, publish_1.getRuntimeToPlatformMappingFromRuntimeVersions)(runtimeVersions);
207
127
  const { branchId, createdBranch } = await (0, queries_1.ensureBranchExistsAsync)(graphqlClient, {
208
128
  appId: projectId,
209
129
  branchName,
@@ -229,7 +149,7 @@ class UpdatePublish extends EasCommand_1.default {
229
149
  branchId,
230
150
  updateInfoGroup: localUpdateInfoGroup,
231
151
  runtimeVersion,
232
- message: truncatedMessage,
152
+ message: updateMessage,
233
153
  gitCommitHash,
234
154
  isGitWorkingTreeDirty,
235
155
  awaitingCodeSigningInfo: !!codeSigningInfo,
@@ -243,7 +163,7 @@ class UpdatePublish extends EasCommand_1.default {
243
163
  log_1.default.log('🔒 Signing updates');
244
164
  const updatesTemp = [...newUpdates];
245
165
  const updateGroupsAndTheirUpdates = updateGroups.map(updateGroup => {
246
- const newUpdates = updatesTemp.splice(0, Object.keys(updateGroup.updateInfoGroup).length);
166
+ const newUpdates = updatesTemp.splice(0, Object.keys((0, nullthrows_1.default)(updateGroup.updateInfoGroup)).length);
247
167
  return {
248
168
  updateGroup,
249
169
  newUpdates,
@@ -256,8 +176,8 @@ class UpdatePublish extends EasCommand_1.default {
256
176
  headers: { accept: 'multipart/mixed' },
257
177
  });
258
178
  const manifestBody = (0, nullthrows_1.default)(await (0, code_signing_1.getManifestBodyAsync)(response));
259
- (0, code_signing_1.checkManifestBodyAgainstUpdateInfoGroup)(manifestBody, (0, nullthrows_1.default)(updateGroup.updateInfoGroup[newUpdate.platform]));
260
- const manifestSignature = (0, code_signing_1.signManifestBody)(manifestBody, codeSigningInfo);
179
+ (0, code_signing_1.checkManifestBodyAgainstUpdateInfoGroup)(manifestBody, (0, nullthrows_1.default)((0, nullthrows_1.default)(updateGroup.updateInfoGroup)[newUpdate.platform]));
180
+ const manifestSignature = (0, code_signing_1.signBody)(manifestBody, codeSigningInfo);
261
181
  await PublishMutation_1.PublishMutation.setCodeSigningInfoAsync(graphqlClient, newUpdate.id, {
262
182
  alg: codeSigningInfo.codeSigningMetadata.alg,
263
183
  keyid: codeSigningInfo.codeSigningMetadata.keyid,
@@ -273,7 +193,7 @@ class UpdatePublish extends EasCommand_1.default {
273
193
  throw e;
274
194
  }
275
195
  if (jsonFlag) {
276
- (0, json_1.printJsonOnlyOutput)((0, utils_2.getUpdateGroupJsonInfo)(newUpdates));
196
+ (0, json_1.printJsonOnlyOutput)((0, utils_1.getUpdateGroupJsonInfo)(newUpdates));
277
197
  }
278
198
  else {
279
199
  if (new Set(newUpdates.map(update => update.group)).size > 1) {
@@ -303,7 +223,7 @@ class UpdatePublish extends EasCommand_1.default {
303
223
  ? [{ label: 'Android update ID', value: newAndroidUpdate.id }]
304
224
  : []),
305
225
  ...(newIosUpdate ? [{ label: 'iOS update ID', value: newIosUpdate.id }] : []),
306
- { label: 'Message', value: truncatedMessage },
226
+ { label: 'Message', value: updateMessage },
307
227
  ...(gitCommitHash
308
228
  ? [
309
229
  {
@@ -396,7 +316,7 @@ UpdatePublish.flags = {
396
316
  char: 'p',
397
317
  options: [
398
318
  // TODO: Add web when it's fully supported
399
- ...exports.defaultPublishPlatforms,
319
+ ...publish_1.defaultPublishPlatforms,
400
320
  'all',
401
321
  ],
402
322
  default: 'all',
@@ -416,28 +336,3 @@ UpdatePublish.contextDefinition = {
416
336
  ..._a.ContextOptions.DynamicProjectConfig,
417
337
  ..._a.ContextOptions.LoggedIn,
418
338
  };
419
- /** Get runtime versions grouped by platform. Runtime version is always `null` on web where the platform is always backwards compatible. */
420
- async function getRuntimeVersionObjectAsync(exp, platforms, projectDir) {
421
- var _b, _c;
422
- for (const platform of platforms) {
423
- if (platform === 'web') {
424
- continue;
425
- }
426
- const isPolicy = typeof ((_c = (_b = exp[platform]) === null || _b === void 0 ? void 0 : _b.runtimeVersion) !== null && _c !== void 0 ? _c : exp.runtimeVersion) === 'object';
427
- if (isPolicy) {
428
- const isManaged = (await (0, workflow_1.resolveWorkflowAsync)(projectDir, platform)) === eas_build_job_1.Workflow.MANAGED;
429
- if (!isManaged) {
430
- throw new Error('Runtime version policies are only supported in the managed workflow. In the bare workflow, runtime version needs to be set manually.');
431
- }
432
- }
433
- }
434
- return [...new Set(platforms)].map(platform => {
435
- if (platform === 'web') {
436
- return { platform: 'web', runtimeVersion: 'UNVERSIONED' };
437
- }
438
- return {
439
- platform,
440
- runtimeVersion: (0, nullthrows_1.default)(config_plugins_1.Updates.getRuntimeVersion(exp, platform), `Unable to determine runtime version for ${platform_1.requestedPlatformDisplayNames[platform]}. ${(0, log_1.learnMore)('https://docs.expo.dev/eas-update/runtime-versions/')}`),
441
- };
442
- });
443
- }
@@ -131,7 +131,7 @@ class UpdateRepublish extends EasCommand_1.default {
131
131
  }
132
132
  exports.default = UpdateRepublish;
133
133
  _a = UpdateRepublish;
134
- UpdateRepublish.description = 'rollback to an existing update';
134
+ UpdateRepublish.description = 'roll back to an existing update';
135
135
  UpdateRepublish.flags = {
136
136
  channel: core_1.Flags.string({
137
137
  description: 'Channel name to select an update to republish from',
@@ -0,0 +1,22 @@
1
+ import EasCommand from '../../commandUtils/EasCommand';
2
+ export default class UpdateRollBackToEmbedded extends EasCommand {
3
+ static hidden: boolean;
4
+ static description: string;
5
+ static flags: {
6
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
7
+ 'non-interactive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
+ branch: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
9
+ channel: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
10
+ message: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
11
+ platform: import("@oclif/core/lib/interfaces").OptionFlag<string>;
12
+ auto: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
13
+ 'private-key-path': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
14
+ };
15
+ static contextDefinition: {
16
+ loggedIn: import("../../commandUtils/context/LoggedInContextField").default;
17
+ getDynamicProjectConfigAsync: import("../../commandUtils/context/DynamicProjectConfigContextField").DynamicProjectConfigContextField;
18
+ };
19
+ runAsync(): Promise<void>;
20
+ private publishRollbacksAsync;
21
+ private sanitizeFlags;
22
+ }